Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ test/server-test-config/ssl-cert.pem
test/server-test-config/ssl-key.pem
test/server-test-config/plugin-config-data/

docs/dist
docs/built
5 changes: 3 additions & 2 deletions docs/develop/plugins/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ children:
- ../webapps.md
- deltas.md
- configuration.md
- resource_provider_plugins.md
- ../rest-api/course_calculations.md
- autopilot_provider_plugins.md
- ../rest-api/course_calculations.md
- resource_provider_plugins.md
- weather_provider_plugins.md
- publishing.md
---

Expand Down
2 changes: 1 addition & 1 deletion docs/develop/plugins/resource_provider_plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ module.exports = function (app) {

const plugin = {
id: 'mypluginid',
name: 'My Resource Providerplugin'
name: 'My Resource Provider plugin'
}

const routesProvider: ResourceProvider = {
Expand Down
88 changes: 88 additions & 0 deletions docs/develop/plugins/weather_provider_plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
title: Weather Providers
---

# Weather Providers

The Signal K server [Weather API](../rest-api/weather_api.md) provides a common set of operations for retrieving meteorological data via a "provider plugin" to facilitate communication with a weather service provider.

A weather provider plugin is a Signal K server plugin that brokers communication with a weather provider.

---

## Weather Provider Interface

For a plugin to be a weather provider it must implement the {@link @signalk/server-api!WeatherProvider | `WeatherProvider`} Interface which provides the Signal K server with methods to pass the details contained in API requests.

**A weather provider MUST return data as defined by the OpenAPI definition.**

> [!NOTE]
> Multiple weather providers can be registered with the Signal K server to enable meteorogical data retrieval from multiple sources.

## Weather Provider Interface Methods

Weather API requests made to the Signal K server will result in the plugin's {@link @signalk/server-api!WeatherProviderMethods | `WeatherProviderMethods`} being called.

A weather provider plugin MUST implement ALL of the {@link @signalk/server-api!WeatherProviderMethods | `WeatherProviderMethods`}:

- {@link @signalk/server-api!WeatherProviderMethods.getObservations | `getObservations(position, options)`}

- {@link @signalk/server-api!WeatherProviderMethods.getForecasts | `getForecasts(position, type, options)`}

- {@link @signalk/server-api!WeatherProviderMethods.getWarnings | `getWarnings(position)`}

> [!NOTE]
> The Weather Provider is responsible for implementing the methods and returning data in the required format!

---

## Registering a Weather Provider

Now that the plugin has implemented the required interface and methods, it can be registered as a weather provider with the SignalK server.

The plugin registers itself as a weather provider by calling the server's {@link @signalk/server-api!WeatherProviderRegistry.registerWeatherProvider | `registerWeatherProvider`} function during startup.

Do this within the plugin `start()` method.

_Example._

```javascript
import { WeatherProvider } from '@signalk/server-api'

module.exports = function (app) {

const weatherProvider: WeatherProvider = {
name: 'MyWeatherService',
methods: {
getObservations: (
position: Position,
options?: WeatherReqParams
) => {
// fetch observation data from weather service
return observations
},
getForecasts: (
position: Position,
type: WeatherForecastType,
options?: WeatherReqParams
) => {
// fetch forecasts data from weather service
return forecasts
},
getWarnings: () => {
// Service does not provide weather warnings.
throw new Error('Not supported!')
}
}
}

const plugin = {
id: 'mypluginid',
name: 'My Weather Provider plugin'
start: (settings: any) => {
app.registerWeatherProvider(weatherProvider)
}
}

return plugin
```
8 changes: 7 additions & 1 deletion docs/develop/rest-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ children:
- notifications_api.md
- anchor_api.md
- plugin_api.md
- resources_api.md
- weather_api.md
- anchor_api.md
- notifications_api.md
---

# REST APIs
Expand All @@ -26,14 +30,16 @@ APIs are available via `/signalk/v2/api/<endpoint>`
| [`Autopilot`](./autopilot_api.md) | Provide the ability to send common commands to an autopilot via a provider plugin. | `vessels/self/autopilot` |
| [Course](./course_api.md) | Set a course, follow a route, advance to next point, etc. | `vessels/self/navigation/course` |
| [Resources](./resources_api.md) | Create, view, update and delete waypoints, routes, etc. | `resources` |
| [`Autopilot`](./autopilot_api.md) | Provide the ability to send common commands to an autopilot via a provider plugin. | `vessels/self/autopilot` |
| [`Weather`](./weather_api.md) | Provide the ability to surface meteorological data from weather providers. | `weather` |

---

#### Following is a list of proposed APIs for implementation:

| Proposed API | Description | Endpoint |
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
| _[`Notifications`](notifications_api.md)_ | Provide the ability to raise, update and clear notifications from multiple sources. _[View PR](https://github.com/SignalK/signalk-server/pull/1560)_ | `notifications` |
| _[`Anchor`](./anchor_api.md)_ | Provide endpoints to perform operations and facilitate an anchor alarm. | `vessels/self/navigation/anchor` |
| _[`Notifications`](notifications_api.md)_ | Provide the ability to raise, update and clear notifications from multiple sources. _[View PR](https://github.com/SignalK/signalk-server/pull/1560)_ | `notifications` |

---
121 changes: 121 additions & 0 deletions docs/develop/rest-api/weather_api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
title: Weather API
---

# Weather API

The Signal K server Weather API provides a common set of operations for viewing information from weather data sources via a "provider plugin". The provider plugin facilitates the interaction with the weather service and transforms the data into the Signal K data schema.

Requests to the Weather API are made to HTTP REST endpoints rooted at `/signalk/v2/api/weather`.

Weather API requests require that a postion be supplied which determines the location from which the weather data is sourced.

The following weather data sets are supported:

- Observations
- Forecasts
- Warnings

Following are examples of the types of requests that can be made.

> [!NOTE]
> The data available is dependent on the weather service API and provider-plugin.

_Example 1: Return the latest observation data for the provided location_

```javascript
GET "/signalk/v2/api/weather/observations?lat=5.432&lon=7.334"
```

_Example 2: Return the last 5 observations for the provided location_

```javascript
GET "/signalk/v2/api/weather/observations?lat=5.432&lon=7.334&count=5"
```

_Example 3: Return the daily forecast for the next seven days for the provided location_

```javascript
GET "/signalk/v2/api/weather/forecasts/daily?lat=5.432&lon=7.334&count=7"
```

_Example 4: Return point forecasts for the next 12 periods (service provider dependant) for the provided location_

```javascript
GET "/signalk/v2/api/weather/forecasts/point?lat=5.432&lon=7.334&count=12"
```

_Example 5: Return current warnings for the provided location_

```javascript
GET "/signalk/v2/api/weather/warnings?lat=5.432&lon=7.334"
```

## Providers

The Weather API supports the registration of multiple weather provider plugins.

The first plugin registered is set as the _default_ provider and all requests will be directed to it.

Requests can be directed to a specific provider by using the `provider` parameter in the request with the _id_ of the provider plugin.

_Example:_

```javascript
GET "/signalk/v2/api/weather/warnings?lat=5.432&lon=7.334?provider=my-weather-plugin"
```

> [!NOTE] Any installed weather provider can be set as the default. _See [Setting the Default provider](#setting-a-provider-as-the-default)_

### Listing the available Weather Providers

To retrieve a list of installed weather provider plugins, submit an HTTP `GET` request to `/signalk/v2/api/weather/_providers`.

The response will be an object containing all the registered weather providers, keyed by their identifier, detailing the service `name` and whether it is assigned as the _default_.

```typescript
HTTP GET "/signalk/v2/api/weather/_providers"
```

_Example: List of registered weather providers showing that `open-meteo` is assigned as the default._

```JSON
{
"open-meteo": {
"provider":"OpenMeteo",
"isDefault": true
},
"openweather": {
"provider":"OpenWeather",
"isDefault": false
}
}
```

### Getting the Default Provider identifier

To get the id of the _default_ provider, submit an HTTP `GET` request to `/signalk/v2/api/weather/_providers/_default`.

_Example:_

```typescript
HTTP GET "//signalk/v2/api/weather/_providers"
```

_Response:_

```JSON
{
"id":"open-meteo"
}
```

### Setting a Provider as the Default

To set / change the weather provider that requests will be directed, submit an HTTP `POST` request to `/signalk/v2/api/weather/_providers/_default/{id}` where `{id}` is the identifier of the weather provider to use as the _default_.

_Example:_

```typescript
HTTP POST "/signalk/v2/api/weather/_providers/_default/openweather"
```
55 changes: 55 additions & 0 deletions docs/src/features/weather/weather.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Working with Weather Data

## Introduction

This document outlines the way in which weather data is managed in Signal K and how to reliably access and use weather data from various sources.

The Signal K specification defines an [`environment`](https://github.com/SignalK/specification/blob/master/schemas/groups/environment.json) schema which contains attributes pertaining to weather and the environment, grouped under headings such as `outside`, `inside`, `water`, `wind`, etc.

The `environment` schema is then able to be applied to Signal K contexts such as `vessels`, `atons`, `meteo`, etc to allow Signal K client apps to reliably consume weather data.

Additionally, the `environment` schema is used by the `Weather API` to provide access to observation and forecast information sourced from weather service providers.

Following are the different contexts and their use.

## 1. On Vessel sensors

Sensors installed on a vesssel making measurements directly outside of the vessel _(e.g. temperature, humidity, etc)_ are placed in the `vessels.self` context.

_On vessel sensor data paths:_

- `vessels.self.environment.outside.*` Measurements taken outside the vessel hull
- `vessels.self.environment.inside.*` Measurements taken inside the vessel hull
- `vessels.self.environment.water.*` Measurements taken relating to the water the vessel is in.

## 2. AIS Weather Sources

Environment data from AIS weather stations via NMEA0183 `VDM` sentences are placed in the `meteo` context, with each station identified by a unique identifier.

_Example - AIS sourced weather data paths:_

- `meteo.urn:mrn:imo:mmsi:123456789:081751.environment.outside.*`
- `meteo.urn:mrn:imo:mmsi:123456789:081751.environment.inside.*`
- `meteo.urn:mrn:imo:mmsi:123456789:081751.environment.water.*`
- `meteo.urn:mrn:imo:mmsi:123456789:081751.environment.tide.*`
- `meteo.urn:mrn:imo:mmsi:123456789:081751.environment.current.*`

## 3. Weather Service Providers _(Weather API)_

Weather service providers provide a collection of observations, forecasts and weather warnings for a location that can include:

- Current and historical data (observations)
- Daily and "point in time" forecasts
over varying time periods.

This information is updated at regular intervals (e.g. hourly) and will relate to an area (of varying size) based on the location provided.

The nature of this data makes it more suited to a REST API rather than a websocket stream and as such the [Signal K Weather API](../../develop/rest-api/weather_api.md) is where this information is made available.

As each weather provider tends to have different interfaces to source information, [Signal K Server plugins](../../develop/plugins/weather_provider_plugins.md) provide the vehicle for fetching and transforming the data from the various data sources and making it available via the Weather API.

The Weather API supports the use of multiple weather provider plugins with the ability to switch between them.

_Example: Fetching weather data for a location._

- `GET "/signalk/v2/api/weather?lat=5.432&lon=7.334`
2 changes: 1 addition & 1 deletion packages/server-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"generate": "ts-auto-guard src/autopilotapi.ts 2>/dev/null",
"generate": "ts-auto-guard src/autopilotapi.ts",
"build": "npm run generate && tsc -b",
"watch": "tsc --watch",
"prepublishOnly": "npm run build",
Expand Down
3 changes: 2 additions & 1 deletion packages/server-api/src/features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ export interface FeatureInfo {
}

export type SignalKApiId =
| 'resources'
| 'weather'
| 'course'
| 'resources'
| 'history'
| 'autopilot'
| 'anchor'
Expand Down
1 change: 1 addition & 0 deletions packages/server-api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from './autopilotapi'
export * from './autopilotapi.guard'
export * from './propertyvalues'
export * from './brand'
export * from './weatherapi'
export * from './streambundle'
export * from './subscriptionmanager'
export * as history from './history'
Expand Down
2 changes: 2 additions & 0 deletions packages/server-api/src/serverapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
WithFeatures,
PropertyValuesEmitter,
ResourceProviderRegistry,
WeatherProviderRegistry,
Delta
} from '.'
import { CourseApi } from './course'
Expand All @@ -28,6 +29,7 @@ export interface ServerAPI
extends PropertyValuesEmitter,
ResourceProviderRegistry,
AutopilotProviderRegistry,
WeatherProviderRegistry,
WithFeatures,
CourseApi,
SelfIdentity {
Expand Down
23 changes: 23 additions & 0 deletions packages/server-api/src/weatherapi.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Generated type guards for "weatherapi.ts".
* WARNING: Do not manually change this file.
*/
import { WeatherProvider } from "./weatherapi";

export function isWeatherProvider(obj: unknown): obj is WeatherProvider {
const typedObj = obj as WeatherProvider
return (
(typedObj !== null &&
typeof typedObj === "object" ||
typeof typedObj === "function") &&
typeof typedObj["name"] === "string" &&
(typedObj["methods"] !== null &&
typeof typedObj["methods"] === "object" ||
typeof typedObj["methods"] === "function") &&
(typeof typedObj["methods"]["pluginId"] === "undefined" ||
typeof typedObj["methods"]["pluginId"] === "string") &&
typeof typedObj["methods"]["getObservations"] === "function" &&
typeof typedObj["methods"]["getForecasts"] === "function" &&
typeof typedObj["methods"]["getWarnings"] === "function"
)
}
Loading