{
    "openapi": "3.0.0",
    "info": {
        "version": "2.5.0",
        "title": "Weather API",
        "description": "Signal K weather API endpoints.",
        "termsOfService": "http://signalk.org/terms/",
        "license": {
            "name": "Apache 2.0",
            "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
        }
    },
    "externalDocs": {
        "url": "http://signalk.org/specification/",
        "description": "Signal K specification."
    },
    "servers": [
        {
            "url": "/signalk/v2/api/weather"
        }
    ],
    "tags": [
        {
            "name": "Weather",
            "description": "Operations to interact with weather service data."
        },
        {
            "name": "Provider",
            "description": "Operations to view / switch providers."
        }
    ],
    "components": {
        "schemas": {
            "Position": {
                "type": "object",
                "required": ["latitude", "longitude"],
                "properties": {
                    "latitude": {
                        "type": "number",
                        "format": "float"
                    },
                    "longitude": {
                        "type": "number",
                        "format": "float"
                    }
                }
            },
            "IsoTime": {
                "type": "string",
                "description": "Date / Time when data values were recorded",
                "pattern": "^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2}(?:\\.\\d*)?)((-(\\d{2}):(\\d{2})|Z)?)$",
                "example": "2022-04-22T05:02:56.484Z"
            },
            "WeatherDataModel": {
                "type": "object",
                "required": ["date", "type"],
                "properties": {
                    "date": {
                        "$ref": "#/components/schemas/IsoTime"
                    },
                    "description": {
                        "type": "string",
                        "example": "broken clouds"
                    },
                    "type": {
                        "type": "string",
                        "enum": ["daily", "point", "observation"]
                    },
                    "sun": {
                        "type": "object",
                        "required": ["times"],
                        "properties": {
                            "sunrise": {
                                "$ref": "#/components/schemas/IsoTime"
                            },
                            "sunset": {
                                "$ref": "#/components/schemas/IsoTime"
                            }
                        }
                    },
                    "outside": {
                        "type": "object",
                        "properties": {
                            "uvIndex": {
                                "type": "number",
                                "example": 7.5,
                                "description": "UV Index (1 UVI = 25mW/sqm)"
                            },
                            "cloudCover": {
                                "type": "number",
                                "example": 0.85,
                                "description": "Amount of cloud cover (ratio)"
                            },
                            "horizontalVisibility": {
                                "type": "number",
                                "example": 5000,
                                "description": "Visibilty (m)"
                            },
                            "horizontalVisibilityOverRange": {
                                "type": "boolean",
                                "example": "true",
                                "description": "Visibilty distance is greater than the range of the measuring equipment."
                            },
                            "temperature": {
                                "type": "number",
                                "example": 290,
                                "description": "Air temperature (K)"
                            },
                            "feelsLikeTemperature": {
                                "type": "number",
                                "example": 277,
                                "description": "Feels-like temperature (K)"
                            },
                            "dewPointTemperature": {
                                "type": "number",
                                "example": 260,
                                "description": "Dew point temperature (K)"
                            },
                            "pressure": {
                                "type": "number",
                                "example": 10100,
                                "description": "Air pressure (Pa)"
                            },
                            "pressureTendency": {
                                "type": "string",
                                "enum": ["steady", "decreasing", "increasing"],
                                "example": "steady",
                                "description": "Air pressure tendency"
                            },
                            "absoluteHumidity": {
                                "type": "number",
                                "example": 0.56,
                                "description": "Absolute humidity (ratio)"
                            },
                            "relativeHumidity": {
                                "type": "number",
                                "example": 0.56,
                                "description": "Relative humidity (ratio)"
                            },
                            "precipitationType": {
                                "type": "string",
                                "enum": [
                                    "rain",
                                    "thunderstorm",
                                    "snow",
                                    "freezing rain",
                                    "mixed/ice"
                                ],
                                "example": "rain",
                                "description": "Type of precipitation"
                            },
                            "precipitationVolume": {
                                "type": "number",
                                "example": 0.56,
                                "description": "Amount of precipitation (m)"
                            }
                        }
                    },
                    "wind": {
                        "type": "object",
                        "properties": {
                            "averageSpeed": {
                                "type": "number",
                                "example": 9.3,
                                "description": "Average wind speed (m/s)"
                            },
                            "speedTrue": {
                                "type": "number",
                                "example": 15.3,
                                "description": "Wind speed (m/s)"
                            },
                            "directionTrue": {
                                "type": "number",
                                "example": 2.145,
                                "description": "Wind direction relative to true north (rad)"
                            },
                            "gust": {
                                "type": "number",
                                "example": 21.6,
                                "description": "Wind gust (m/s)"
                            },
                            "gustDirectionTrue": {
                                "type": "number",
                                "example": 2.6,
                                "description": "Wind gust direction relative to true north (rad)"
                            }
                        }
                    },
                    "water": {
                        "type": "object",
                        "properties": {
                            "temperature": {
                                "type": "number",
                                "example": 281.6,
                                "description": "Water temperature (K)"
                            },
                            "level": {
                                "type": "number",
                                "example": 11.9,
                                "description": "Water level (m)"
                            },
                            "levelTendency": {
                                "type": "number",
                                "enum": ["steady", "decreasing", "increasing"],
                                "example": "steady",
                                "description": "Water level trend"
                            },
                            "waves": {
                                "type": "object",
                                "properties": {
                                    "significantHeight": {
                                        "type": "number",
                                        "example": 2.6,
                                        "description": "Wave height (m)"
                                    },
                                    "directionTrue": {
                                        "type": "number",
                                        "example": 2.3876,
                                        "description": "Wave direction relative to true north (rad)"
                                    },
                                    "period": {
                                        "type": "number",
                                        "example": 2.3876,
                                        "description": "Wave period (m/s)"
                                    }
                                }
                            },
                            "swell": {
                                "type": "object",
                                "properties": {
                                    "height": {
                                        "type": "number",
                                        "example": 2.6,
                                        "description": "Swell height (m)"
                                    },
                                    "directionTrue": {
                                        "type": "number",
                                        "example": 2.3876,
                                        "description": "Swell direction relative to true north (rad)"
                                    },
                                    "period": {
                                        "type": "number",
                                        "example": 2.3876,
                                        "description": "Swell period (m/s)"
                                    }
                                }
                            },
                            "seaState": {
                                "type": "number",
                                "example": 2,
                                "description": "Sea state (Beaufort)"
                            },
                            "salinity": {
                                "type": "number",
                                "example": 0.12,
                                "description": "Water salinity (ratio)"
                            },
                            "ice": {
                                "type": "boolean",
                                "example": true,
                                "description": "Ice present."
                            }
                        }
                    },
                    "current": {
                        "type": "object",
                        "properties": {
                            "drift": {
                                "type": "number",
                                "example": 3.4,
                                "description": "Surface current speed (m/s)"
                            },
                            "set": {
                                "type": "number",
                                "example": 1.74,
                                "description": "Surface current direction (rad)"
                            }
                        }
                    }
                }
            },
            "WeatherWarningModel": {
                "type": "object",
                "required": ["startTime", "endTime"],
                "properties": {
                    "startTime": {
                        "$ref": "#/components/schemas/IsoTime"
                    },
                    "endTime": {
                        "$ref": "#/components/schemas/IsoTime"
                    },
                    "source": {
                        "type": "string",
                        "description": "Name of source."
                    },
                    "type": {
                        "type": "string",
                        "description": "Type of warning.",
                        "example": "Heat Advisory"
                    },
                    "details": {
                        "type": "string",
                        "description": "Text describing the details of the warning.",
                        "example": "HEAT ADVISORY REMAINS IN EFFECT FROM 1 PM THIS AFTERNOON...."
                    }
                }
            }
        },
        "responses": {
            "200OKResponse": {
                "description": "Successful operation",
                "content": {
                    "application/json": {
                        "schema": {
                            "type": "object",
                            "description": "Request success response",
                            "properties": {
                                "state": {
                                    "type": "string",
                                    "enum": ["COMPLETED"]
                                },
                                "statusCode": {
                                    "type": "number",
                                    "enum": [200]
                                }
                            },
                            "required": ["state", "statusCode"]
                        }
                    }
                }
            },
            "ErrorResponse": {
                "description": "Failed operation",
                "content": {
                    "application/json": {
                        "schema": {
                            "type": "object",
                            "description": "Request error response",
                            "properties": {
                                "state": {
                                    "type": "string",
                                    "enum": ["FAILED"]
                                },
                                "statusCode": {
                                    "type": "number",
                                    "enum": [404]
                                },
                                "message": {
                                    "type": "string"
                                }
                            },
                            "required": ["state", "statusCode", "message"]
                        }
                    }
                }
            }
        },
        "parameters": {
            "ProviderIdParam": {
                "name": "id",
                "in": "path",
                "description": "Plugin id of the weather provider the request will be directed to.",
                "required": true,
                "schema": {
                    "type": "string",
                    "example": "myweather-provider"
                }
            },
            "ProviderIdQuery": {
                "in": "query",
                "name": "provider",
                "description": "Plugin id of the weather provider the request will be directed to.",
                "style": "form",
                "explode": false,
                "schema": {
                    "type": "string",
                    "example": "myweather-provider"
                }
            },
            "LatitudeParam": {
                "in": "query",
                "required": true,
                "name": "lat",
                "description": "Latitude at specified position.",
                "schema": {
                    "type": "number",
                    "min": -90,
                    "max": 90
                }
            },
            "LongitudeParam": {
                "in": "query",
                "required": true,
                "name": "lon",
                "description": "Longitude at specified position.",
                "schema": {
                    "type": "number",
                    "min": -180,
                    "max": 180
                }
            },
            "CountParam": {
                "in": "query",
                "required": false,
                "name": "count",
                "description": "Number of entries to return.",
                "schema": {
                    "type": "number",
                    "min": 1
                }
            },
            "StartDateParam": {
                "in": "query",
                "required": false,
                "name": "date",
                "description": "Start date for weather data to return.",
                "schema": {
                    "type": "string",
                    "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
                }
            }
        },
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "JWT"
            },
            "cookieAuth": {
                "type": "apiKey",
                "in": "cookie",
                "name": "JAUTHENTICATION"
            }
        }
    },
    "security": [{ "cookieAuth": [] }, { "bearerAuth": [] }],
    "paths": {
        "/observations": {
            "parameters": [
                {
                    "$ref": "#/components/parameters/ProviderIdQuery"
                },
                {
                    "$ref": "#/components/parameters/LatitudeParam"
                },
                {
                    "$ref": "#/components/parameters/LongitudeParam"
                },
                {
                    "$ref": "#/components/parameters/CountParam"
                },
                {
                    "$ref": "#/components/parameters/StartDateParam"
                }
            ],
            "get": {
                "tags": ["Weather"],
                "summary": "Retrieve observation data.",
                "responses": {
                    "default": {
                        "description": "Returns the observation data for the specified location (lat / lon).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "$ref": "#/components/schemas/WeatherDataModel"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/forecasts/daily": {
            "parameters": [
                {
                    "$ref": "#/components/parameters/ProviderIdQuery"
                },
                {
                    "$ref": "#/components/parameters/LatitudeParam"
                },
                {
                    "$ref": "#/components/parameters/LongitudeParam"
                },
                {
                    "$ref": "#/components/parameters/CountParam"
                },
                {
                    "$ref": "#/components/parameters/StartDateParam"
                }
            ],
            "get": {
                "tags": ["Weather"],
                "summary": "Retrieve daily forecast data.",
                "responses": {
                    "default": {
                        "description": "Returns daily forecast data for the specified location (lat / lon).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "$ref": "#/components/schemas/WeatherDataModel"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/forecasts/point": {
            "parameters": [
                {
                    "$ref": "#/components/parameters/ProviderIdQuery"
                },
                {
                    "$ref": "#/components/parameters/LatitudeParam"
                },
                {
                    "$ref": "#/components/parameters/LongitudeParam"
                },
                {
                    "$ref": "#/components/parameters/CountParam"
                },
                {
                    "$ref": "#/components/parameters/StartDateParam"
                }
            ],
            "get": {
                "tags": ["Weather"],
                "summary": "Retrieve point forecast data.",
                "responses": {
                    "default": {
                        "description": "Returns point forecast data for the specified location (lat / lon).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "$ref": "#/components/schemas/WeatherDataModel"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/warnings": {
            "parameters": [
                {
                    "$ref": "#/components/parameters/ProviderIdQuery"
                },
                {
                    "$ref": "#/components/parameters/LatitudeParam"
                },
                {
                    "$ref": "#/components/parameters/LongitudeParam"
                }
            ],
            "get": {
                "tags": ["Weather"],
                "summary": "Retrieve warning data.",
                "responses": {
                    "default": {
                        "description": "Returns the warning data for the specified location (lat / lon).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "$ref": "#/components/schemas/WeatherWarningModel"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/_providers": {
            "get": {
                "tags": ["Provider"],
                "summary": "Retrieve list of registered providers.",
                "responses": {
                    "default": {
                        "description": "Return information about the registered weather providers.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "additionalProperties": {
                                        "type": "object",
                                        "description": "Provider identifier",
                                        "required": ["name", "isDefault"],
                                        "properties": {
                                            "name": {
                                                "type": "string",
                                                "description": "Provider name."
                                            },
                                            "isDefault": {
                                                "type": "boolean",
                                                "description": "`true` if this provider is set as the default."
                                            }
                                        },
                                        "example": {
                                            "name": "OpenMeteo",
                                            "isDefault": true
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/_providers/_default": {
            "get": {
                "tags": ["Provider"],
                "summary": "Get the default weather provider id.",
                "responses": {
                    "default": {
                        "description": "Returns the id of the provider id that is the target of requests (if provider is not specified).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": ["id"],
                                    "properties": {
                                        "id": {
                                            "type": "string",
                                            "description": "Provider identifier."
                                        }
                                    },
                                    "example": {
                                        "id": "open-meteo"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/_providers/_default/{id}": {
            "parameters": [
                {
                    "$ref": "#/components/parameters/ProviderIdParam"
                }
            ],
            "post": {
                "tags": ["Provider"],
                "summary": "Sets the default weather provider.",
                "description": "Sets the proivder with the supplied `id` as the default.",
                "body": {
                    "type": "object",
                    "required": ["id"],
                    "properties": {
                        "id": {
                            "type": "string",
                            "description": "Provider identifier."
                        }
                    }
                },
                "responses": {
                    "default": {
                        "$ref": "#/components/responses/ErrorResponse"
                    },
                    "200": {
                        "$ref": "#/components/responses/200OKResponse"
                    }
                }
            }
        }
    }
}
