Skip to content

feature: Weather API definition. #1733

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
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
86 changes: 86 additions & 0 deletions docs/develop/plugins/weather_provider_plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
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.

> [!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
```
10 changes: 6 additions & 4 deletions docs/develop/rest-api/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
---
title: REST APIs
children:
- autopilot_api.md
- course_api.md
- course_calculations.md
- plugin_api.md
- resources_api.md
- notifications_api.md
- autopilot_api.md
- weather_api.md
- anchor_api.md
- plugin_api.md
- notifications_api.md
---

# REST APIs
Expand All @@ -25,14 +26,15 @@ APIs are available via `/signalk/v2/api/<endpoint>`
| [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` |

---
93 changes: 93 additions & 0 deletions docs/develop/rest-api/weather_api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
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 source for all API requests.

_Note: Any installed provider plugin, can be set as the default provider._

To see a list of registered providers and which is the default, make a HTTP `GET` request to `/signalk/v2/api/weather/_providers`.

_Example:_

```javascript
GET "/signalk/v2/api/weather/_providers"
```

_Example response:_

```JSON
{
"providerId1": {
"name":"my-provider-1",
"isDefault":true
},
"providerId2": {
"name":"my-provider-2",
"isDefault":false
}
}
```

To change the default provider, make a HTTP `POST` request supplying the provider identifier in the body of the request.

_Example:_

```javascript
POST "/signalk/v2/api/weather/_providers" {
"id": "providerId2"
}
```
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 src/weatherapi.ts 2>/dev/null",
"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
2 changes: 2 additions & 0 deletions packages/server-api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export * from './autopilotapi'
export * from './autopilotapi.guard'
export * from './propertyvalues'
export * from './brand'
export * from './weatherapi'
export * from './weatherapi.guard'
export * from './streambundle'
export * from './subscriptionmanager'

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 {
Features,
PropertyValuesEmitter,
ResourceProviderRegistry,
WeatherProviderRegistry,
Delta
} from '.'
import { CourseApi } from './course'
Expand All @@ -28,6 +29,7 @@ export interface ServerAPI
extends PropertyValuesEmitter,
ResourceProviderRegistry,
AutopilotProviderRegistry,
WeatherProviderRegistry,
Features,
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