diff --git a/bun.lock b/bun.lock index 47faf41..44b6638 100644 --- a/bun.lock +++ b/bun.lock @@ -170,14 +170,6 @@ "@nym.sh/jrx": "*", }, }, - "packages/aelis-data-source-weatherkit": { - "name": "@aelis/data-source-weatherkit", - "version": "0.0.0", - "dependencies": { - "@aelis/core": "workspace:*", - "arktype": "^2.1.0", - }, - }, "packages/aelis-feed-enhancers": { "name": "@aelis/feed-enhancers", "version": "0.0.0", @@ -248,8 +240,6 @@ "@aelis/core": ["@aelis/core@workspace:packages/aelis-core"], - "@aelis/data-source-weatherkit": ["@aelis/data-source-weatherkit@workspace:packages/aelis-data-source-weatherkit"], - "@aelis/feed-enhancers": ["@aelis/feed-enhancers@workspace:packages/aelis-feed-enhancers"], "@aelis/source-caldav": ["@aelis/source-caldav@workspace:packages/aelis-source-caldav"], diff --git a/packages/aelis-data-source-weatherkit/.env.example b/packages/aelis-data-source-weatherkit/.env.example deleted file mode 100644 index fee8994..0000000 --- a/packages/aelis-data-source-weatherkit/.env.example +++ /dev/null @@ -1,4 +0,0 @@ -WEATHERKIT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----" -WEATHERKIT_KEY_ID=ABC123DEFG -WEATHERKIT_TEAM_ID=TEAM123456 -WEATHERKIT_SERVICE_ID=com.example.weatherkit.test diff --git a/packages/aelis-data-source-weatherkit/README.md b/packages/aelis-data-source-weatherkit/README.md deleted file mode 100644 index 64202ce..0000000 --- a/packages/aelis-data-source-weatherkit/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# @aelis/data-source-weatherkit - -Weather data source using Apple WeatherKit REST API. - -## Usage - -```typescript -import { WeatherKitDataSource, Units } from "@aelis/data-source-weatherkit" - -const dataSource = new WeatherKitDataSource({ - credentials: { - privateKey: "-----BEGIN PRIVATE KEY-----\n...", - keyId: "ABC123", - teamId: "DEF456", - serviceId: "com.example.weatherkit", - }, - hourlyLimit: 12, // optional, default: 12 - dailyLimit: 7, // optional, default: 7 -}) - -const items = await dataSource.query(context, { - units: Units.metric, // or Units.imperial -}) -``` - -## Feed Items - -The data source returns four types of feed items: - -| Type | Description | -| ----------------- | -------------------------- | -| `weather-current` | Current weather conditions | -| `weather-hourly` | Hourly forecast | -| `weather-daily` | Daily forecast | -| `weather-alert` | Weather alerts | - -## Priority - -Base priorities are adjusted based on weather conditions: - -- Severe conditions (tornado, hurricane, blizzard, etc.): +0.3 -- Moderate conditions (thunderstorm, heavy rain, etc.): +0.15 -- Alert severity: extreme=1.0, severe=0.9, moderate=0.75, minor=0.7 - -## Authentication - -WeatherKit requires Apple Developer credentials. Generate a private key in the Apple Developer portal under Certificates, Identifiers & Profiles > Keys. - -## Validation - -API responses are validated using [arktype](https://arktype.io) schemas. - -## Generating Test Fixtures - -To regenerate fixture data from the real API: - -1. Create a `.env` file with your credentials (see `.env.example`) -2. Run `bun run scripts/generate-fixtures.ts` diff --git a/packages/aelis-data-source-weatherkit/fixtures/san-francisco.json b/packages/aelis-data-source-weatherkit/fixtures/san-francisco.json deleted file mode 100644 index f4b1f77..0000000 --- a/packages/aelis-data-source-weatherkit/fixtures/san-francisco.json +++ /dev/null @@ -1,6457 +0,0 @@ -{ - "generatedAt": "2026-01-17T00:37:11.971Z", - "location": { "lat": 37.7749, "lng": -122.4194 }, - "response": { - "currentWeather": { - "name": "CurrentWeather", - "metadata": { - "attributionURL": "https://developer.apple.com/weatherkit/data-source-attribution/", - "expireTime": "2026-01-17T00:42:11Z", - "latitude": 37.77, - "longitude": -122.42, - "readTime": "2026-01-17T00:37:11Z", - "reportedTime": "2026-01-17T00:37:11Z", - "units": "m", - "version": 1, - "sourceType": "modeled" - }, - "asOf": "2026-01-17T00:37:11Z", - "cloudCover": 0.18, - "cloudCoverLowAltPct": 0.18, - "cloudCoverMidAltPct": 0.18, - "cloudCoverHighAltPct": 0.18, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.62, - "precipitationIntensity": 0, - "pressure": 1017.74, - "pressureTrend": "steady", - "temperature": 15.87, - "temperatureApparent": 14.43, - "temperatureDewPoint": 8.6, - "uvIndex": 0, - "visibility": 30655.28, - "windDirection": 352, - "windGust": 17.67, - "windSpeed": 11.15 - }, - "forecastDaily": { - "name": "DailyForecast", - "metadata": { - "attributionURL": "https://developer.apple.com/weatherkit/data-source-attribution/", - "expireTime": "2026-01-17T01:37:11Z", - "latitude": 37.77, - "longitude": -122.42, - "readTime": "2026-01-17T00:37:11Z", - "reportedTime": "2026-01-16T23:05:34Z", - "units": "m", - "version": 1, - "sourceType": "modeled" - }, - "days": [ - { - "forecastStart": "2026-01-16T08:00:00Z", - "forecastEnd": "2026-01-17T08:00:00Z", - "conditionCode": "Clear", - "maxUvIndex": 3, - "moonPhase": "waningCrescent", - "moonrise": "2026-01-16T14:09:55Z", - "moonset": "2026-01-16T23:12:47Z", - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "solarMidnight": "2026-01-16T08:19:22Z", - "solarNoon": "2026-01-16T20:19:43Z", - "sunrise": "2026-01-16T15:23:30Z", - "sunriseCivil": "2026-01-16T14:54:53Z", - "sunriseNautical": "2026-01-16T14:22:43Z", - "sunriseAstronomical": "2026-01-16T13:51:16Z", - "sunset": "2026-01-17T01:16:09Z", - "sunsetCivil": "2026-01-17T01:44:43Z", - "sunsetNautical": "2026-01-17T02:16:53Z", - "sunsetAstronomical": "2026-01-17T02:48:20Z", - "temperatureMax": 19.88, - "temperatureMin": 8.85, - "windGustSpeedMax": 18.66, - "windSpeedAvg": 5.57, - "windSpeedMax": 11.53, - "daytimeForecast": { - "forecastStart": "2026-01-16T15:00:00Z", - "forecastEnd": "2026-01-17T03:00:00Z", - "cloudCover": 0.02, - "conditionCode": "Clear", - "humidity": 0.63, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 19.88, - "temperatureMin": 9.02, - "windDirection": 6, - "windGustSpeedMax": 18.66, - "windSpeed": 5.6, - "windSpeedMax": 11.53 - }, - "overnightForecast": { - "forecastStart": "2026-01-17T03:00:00Z", - "forecastEnd": "2026-01-17T15:00:00Z", - "cloudCover": 0.13, - "conditionCode": "MostlyClear", - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 12.51, - "temperatureMin": 8.03, - "windDirection": 11, - "windGustSpeedMax": 18.52, - "windSpeed": 10.23, - "windSpeedMax": 11.28 - }, - "restOfDayForecast": { - "forecastStart": "2026-01-17T00:37:11Z", - "forecastEnd": "2026-01-17T08:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "humidity": 0.77, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 15.87, - "temperatureMin": 9.84, - "windDirection": 348, - "windGustSpeedMax": 18.52, - "windSpeed": 10.36, - "windSpeedMax": 11.15 - } - }, - { - "forecastStart": "2026-01-17T08:00:00Z", - "forecastEnd": "2026-01-18T08:00:00Z", - "conditionCode": "MostlyCloudy", - "maxUvIndex": 2, - "moonPhase": "waningCrescent", - "moonrise": "2026-01-17T14:56:53Z", - "moonset": "2026-01-18T00:13:04Z", - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "solarMidnight": "2026-01-17T08:19:42Z", - "solarNoon": "2026-01-17T20:20:03Z", - "sunrise": "2026-01-17T15:23:07Z", - "sunriseCivil": "2026-01-17T14:54:34Z", - "sunriseNautical": "2026-01-17T14:22:26Z", - "sunriseAstronomical": "2026-01-17T13:51:01Z", - "sunset": "2026-01-18T01:17:12Z", - "sunsetCivil": "2026-01-18T01:45:42Z", - "sunsetNautical": "2026-01-18T02:17:50Z", - "sunsetAstronomical": "2026-01-18T02:49:14Z", - "temperatureMax": 16.94, - "temperatureMin": 8.03, - "windGustSpeedMax": 20.39, - "windSpeedAvg": 10.06, - "windSpeedMax": 11.3, - "daytimeForecast": { - "forecastStart": "2026-01-17T15:00:00Z", - "forecastEnd": "2026-01-18T03:00:00Z", - "cloudCover": 0.71, - "conditionCode": "MostlyCloudy", - "humidity": 0.69, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 16.94, - "temperatureMin": 8.04, - "windDirection": 29, - "windGustSpeedMax": 20.39, - "windSpeed": 10.63, - "windSpeedMax": 11.3 - }, - "overnightForecast": { - "forecastStart": "2026-01-18T03:00:00Z", - "forecastEnd": "2026-01-18T15:00:00Z", - "cloudCover": 0.84, - "conditionCode": "MostlyCloudy", - "humidity": 0.78, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 13.41, - "temperatureMin": 9.08, - "windDirection": 31, - "windGustSpeedMax": 14.86, - "windSpeed": 8.91, - "windSpeedMax": 10.05 - } - }, - { - "forecastStart": "2026-01-18T08:00:00Z", - "forecastEnd": "2026-01-19T08:00:00Z", - "conditionCode": "MostlyClear", - "maxUvIndex": 3, - "moonPhase": "waningCrescent", - "moonrise": "2026-01-18T15:37:11Z", - "moonset": "2026-01-19T01:17:13Z", - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "solarMidnight": "2026-01-18T08:20:01Z", - "solarNoon": "2026-01-18T20:20:23Z", - "sunrise": "2026-01-18T15:22:41Z", - "sunriseCivil": "2026-01-18T14:54:12Z", - "sunriseNautical": "2026-01-18T14:22:08Z", - "sunriseAstronomical": "2026-01-18T13:50:45Z", - "sunset": "2026-01-19T01:18:16Z", - "sunsetCivil": "2026-01-19T01:46:43Z", - "sunsetNautical": "2026-01-19T02:18:47Z", - "sunsetAstronomical": "2026-01-19T02:50:09Z", - "temperatureMax": 18.18, - "temperatureMin": 9.08, - "windGustSpeedMax": 20.16, - "windSpeedAvg": 8.09, - "windSpeedMax": 10.05, - "daytimeForecast": { - "forecastStart": "2026-01-18T15:00:00Z", - "forecastEnd": "2026-01-19T03:00:00Z", - "cloudCover": 0.24, - "conditionCode": "MostlyClear", - "humidity": 0.63, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 18.18, - "temperatureMin": 9.19, - "windDirection": 29, - "windGustSpeedMax": 20.16, - "windSpeed": 8.65, - "windSpeedMax": 9.98 - }, - "overnightForecast": { - "forecastStart": "2026-01-19T03:00:00Z", - "forecastEnd": "2026-01-19T15:00:00Z", - "cloudCover": 0.16, - "conditionCode": "MostlyClear", - "humidity": 0.8, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 14.04, - "temperatureMin": 8.35, - "windDirection": 37, - "windGustSpeedMax": 13.01, - "windSpeed": 5.09, - "windSpeedMax": 6.54 - } - }, - { - "forecastStart": "2026-01-19T08:00:00Z", - "forecastEnd": "2026-01-20T08:00:00Z", - "conditionCode": "MostlyClear", - "maxUvIndex": 3, - "moonPhase": "waxingCrescent", - "moonrise": "2026-01-19T16:11:15Z", - "moonset": "2026-01-20T02:22:55Z", - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "solarMidnight": "2026-01-19T08:20:20Z", - "solarNoon": "2026-01-19T20:20:41Z", - "sunrise": "2026-01-19T15:22:14Z", - "sunriseCivil": "2026-01-19T14:53:48Z", - "sunriseNautical": "2026-01-19T14:21:47Z", - "sunriseAstronomical": "2026-01-19T13:50:26Z", - "sunset": "2026-01-20T01:19:21Z", - "sunsetCivil": "2026-01-20T01:47:43Z", - "sunsetNautical": "2026-01-20T02:19:45Z", - "sunsetAstronomical": "2026-01-20T02:51:04Z", - "temperatureMax": 17.4, - "temperatureMin": 8.35, - "windGustSpeedMax": 17.91, - "windSpeedAvg": 7.28, - "windSpeedMax": 9.93, - "daytimeForecast": { - "forecastStart": "2026-01-19T15:00:00Z", - "forecastEnd": "2026-01-20T03:00:00Z", - "cloudCover": 0.15, - "conditionCode": "MostlyClear", - "humidity": 0.63, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 17.4, - "temperatureMin": 8.46, - "windDirection": 29, - "windGustSpeedMax": 17.91, - "windSpeed": 8.38, - "windSpeedMax": 9.93 - }, - "overnightForecast": { - "forecastStart": "2026-01-20T03:00:00Z", - "forecastEnd": "2026-01-20T15:00:00Z", - "cloudCover": 0.06, - "conditionCode": "Clear", - "humidity": 0.78, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 13.69, - "temperatureMin": 7.41, - "windDirection": 35, - "windGustSpeedMax": 16.49, - "windSpeed": 8.46, - "windSpeedMax": 9.54 - } - }, - { - "forecastStart": "2026-01-20T08:00:00Z", - "forecastEnd": "2026-01-21T08:00:00Z", - "conditionCode": "Clear", - "maxUvIndex": 3, - "moonPhase": "waxingCrescent", - "moonrise": "2026-01-20T16:40:40Z", - "moonset": "2026-01-21T03:28:39Z", - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "solarMidnight": "2026-01-20T08:20:37Z", - "solarNoon": "2026-01-20T20:20:59Z", - "sunrise": "2026-01-20T15:21:45Z", - "sunriseCivil": "2026-01-20T14:53:23Z", - "sunriseNautical": "2026-01-20T14:21:24Z", - "sunriseAstronomical": "2026-01-20T13:50:06Z", - "sunset": "2026-01-21T01:20:26Z", - "sunsetCivil": "2026-01-21T01:48:44Z", - "sunsetNautical": "2026-01-21T02:20:44Z", - "sunsetAstronomical": "2026-01-21T02:52:00Z", - "temperatureMax": 17.26, - "temperatureMin": 7.41, - "windGustSpeedMax": 18.87, - "windSpeedAvg": 8.01, - "windSpeedMax": 9.54, - "daytimeForecast": { - "forecastStart": "2026-01-20T15:00:00Z", - "forecastEnd": "2026-01-21T03:00:00Z", - "cloudCover": 0.09, - "conditionCode": "Clear", - "humidity": 0.65, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 17.26, - "temperatureMin": 7.95, - "windDirection": 35, - "windGustSpeedMax": 18.87, - "windSpeed": 8.24, - "windSpeedMax": 9.48 - }, - "overnightForecast": { - "forecastStart": "2026-01-21T03:00:00Z", - "forecastEnd": "2026-01-21T15:00:00Z", - "cloudCover": 0.12, - "conditionCode": "Clear", - "humidity": 0.76, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 13.82, - "temperatureMin": 6.86, - "windDirection": 37, - "windGustSpeedMax": 13.61, - "windSpeed": 6.29, - "windSpeedMax": 7.08 - } - }, - { - "forecastStart": "2026-01-21T08:00:00Z", - "forecastEnd": "2026-01-22T08:00:00Z", - "conditionCode": "MostlyClear", - "maxUvIndex": 3, - "moonPhase": "waxingCrescent", - "moonrise": "2026-01-21T17:06:43Z", - "moonset": "2026-01-22T04:34:00Z", - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "solarMidnight": "2026-01-21T08:20:54Z", - "solarNoon": "2026-01-21T20:21:16Z", - "sunrise": "2026-01-21T15:21:14Z", - "sunriseCivil": "2026-01-21T14:52:56Z", - "sunriseNautical": "2026-01-21T14:21:00Z", - "sunriseAstronomical": "2026-01-21T13:49:44Z", - "sunset": "2026-01-22T01:21:31Z", - "sunsetCivil": "2026-01-22T01:49:45Z", - "sunsetNautical": "2026-01-22T02:21:42Z", - "sunsetAstronomical": "2026-01-22T02:52:56Z", - "temperatureMax": 16.24, - "temperatureMin": 6.86, - "windGustSpeedMax": 16.74, - "windSpeedAvg": 5.86, - "windSpeedMax": 7.11, - "daytimeForecast": { - "forecastStart": "2026-01-21T15:00:00Z", - "forecastEnd": "2026-01-22T03:00:00Z", - "cloudCover": 0.27, - "conditionCode": "MostlyClear", - "humidity": 0.69, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 16.24, - "temperatureMin": 6.96, - "windDirection": 20, - "windGustSpeedMax": 16.74, - "windSpeed": 6.51, - "windSpeedMax": 7.11 - }, - "overnightForecast": { - "forecastStart": "2026-01-22T03:00:00Z", - "forecastEnd": "2026-01-22T15:00:00Z", - "cloudCover": 0.46, - "conditionCode": "PartlyCloudy", - "humidity": 0.82, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 12.83, - "temperatureMin": 8.1, - "windDirection": 46, - "windGustSpeedMax": 11.04, - "windSpeed": 4.22, - "windSpeedMax": 4.9 - } - }, - { - "forecastStart": "2026-01-22T08:00:00Z", - "forecastEnd": "2026-01-23T08:00:00Z", - "conditionCode": "PartlyCloudy", - "maxUvIndex": 3, - "moonPhase": "waxingCrescent", - "moonrise": "2026-01-22T17:31:08Z", - "moonset": "2026-01-23T05:39:27Z", - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "solarMidnight": "2026-01-22T08:21:11Z", - "solarNoon": "2026-01-22T20:21:32Z", - "sunrise": "2026-01-22T15:20:40Z", - "sunriseCivil": "2026-01-22T14:52:26Z", - "sunriseNautical": "2026-01-22T14:20:34Z", - "sunriseAstronomical": "2026-01-22T13:49:21Z", - "sunset": "2026-01-23T01:22:37Z", - "sunsetCivil": "2026-01-23T01:50:47Z", - "sunsetNautical": "2026-01-23T02:22:41Z", - "sunsetAstronomical": "2026-01-23T02:53:52Z", - "temperatureMax": 13.4, - "temperatureMin": 8.1, - "windGustSpeedMax": 19.16, - "windSpeedAvg": 5.72, - "windSpeedMax": 8.56, - "daytimeForecast": { - "forecastStart": "2026-01-22T15:00:00Z", - "forecastEnd": "2026-01-23T03:00:00Z", - "cloudCover": 0.62, - "conditionCode": "PartlyCloudy", - "humidity": 0.77, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 13.4, - "temperatureMin": 8.26, - "windDirection": 329, - "windGustSpeedMax": 19.16, - "windSpeed": 6.09, - "windSpeedMax": 8.56 - }, - "overnightForecast": { - "forecastStart": "2026-01-23T03:00:00Z", - "forecastEnd": "2026-01-23T15:00:00Z", - "cloudCover": 0.71, - "conditionCode": "MostlyCloudy", - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 11.65, - "temperatureMin": 8.49, - "windDirection": 305, - "windGustSpeedMax": 17.51, - "windSpeed": 6.27, - "windSpeedMax": 7.17 - } - }, - { - "forecastStart": "2026-01-23T08:00:00Z", - "forecastEnd": "2026-01-24T08:00:00Z", - "conditionCode": "PartlyCloudy", - "maxUvIndex": 3, - "moonPhase": "waxingCrescent", - "moonrise": "2026-01-23T17:55:04Z", - "moonset": "2026-01-24T06:45:58Z", - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "solarMidnight": "2026-01-23T08:21:26Z", - "solarNoon": "2026-01-23T20:21:48Z", - "sunrise": "2026-01-23T15:20:05Z", - "sunriseCivil": "2026-01-23T14:51:55Z", - "sunriseNautical": "2026-01-23T14:20:06Z", - "sunriseAstronomical": "2026-01-23T13:48:55Z", - "sunset": "2026-01-24T01:23:43Z", - "sunsetCivil": "2026-01-24T01:51:49Z", - "sunsetNautical": "2026-01-24T02:23:41Z", - "sunsetAstronomical": "2026-01-24T02:54:49Z", - "temperatureMax": 13.01, - "temperatureMin": 8.49, - "windGustSpeedMax": 13.85, - "windSpeedAvg": 6.88, - "windSpeedMax": 10.62, - "daytimeForecast": { - "forecastStart": "2026-01-23T15:00:00Z", - "forecastEnd": "2026-01-24T03:00:00Z", - "cloudCover": 0.44, - "conditionCode": "PartlyCloudy", - "humidity": 0.78, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 13.01, - "temperatureMin": 8.74, - "windDirection": 303, - "windGustSpeedMax": 13.85, - "windSpeed": 5.96, - "windSpeedMax": 9.31 - }, - "overnightForecast": { - "forecastStart": "2026-01-24T03:00:00Z", - "forecastEnd": "2026-01-24T15:00:00Z", - "cloudCover": 0.24, - "conditionCode": "MostlyClear", - "humidity": 0.85, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 11.59, - "temperatureMin": 8.31, - "windDirection": 263, - "windGustSpeedMax": 14.96, - "windSpeed": 9.88, - "windSpeedMax": 10.77 - } - }, - { - "forecastStart": "2026-01-24T08:00:00Z", - "forecastEnd": "2026-01-25T08:00:00Z", - "conditionCode": "MostlyClear", - "maxUvIndex": 3, - "moonPhase": "waxingCrescent", - "moonrise": "2026-01-24T18:20:13Z", - "moonset": "2026-01-25T07:54:38Z", - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "solarMidnight": "2026-01-24T08:21:41Z", - "solarNoon": "2026-01-24T20:22:02Z", - "sunrise": "2026-01-24T15:19:29Z", - "sunriseCivil": "2026-01-24T14:51:22Z", - "sunriseNautical": "2026-01-24T14:19:36Z", - "sunriseAstronomical": "2026-01-24T13:48:28Z", - "sunset": "2026-01-25T01:24:50Z", - "sunsetCivil": "2026-01-25T01:52:51Z", - "sunsetNautical": "2026-01-25T02:24:40Z", - "sunsetAstronomical": "2026-01-25T02:55:45Z", - "temperatureMax": 12.51, - "temperatureMin": 8.31, - "windGustSpeedMax": 21.4, - "windSpeedAvg": 9.99, - "windSpeedMax": 13.53, - "daytimeForecast": { - "forecastStart": "2026-01-24T15:00:00Z", - "forecastEnd": "2026-01-25T03:00:00Z", - "cloudCover": 0.34, - "conditionCode": "MostlyClear", - "humidity": 0.75, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 12.51, - "temperatureMin": 8.31, - "windDirection": 318, - "windGustSpeedMax": 21.4, - "windSpeed": 11.5, - "windSpeedMax": 13.53 - }, - "overnightForecast": { - "forecastStart": "2026-01-25T03:00:00Z", - "forecastEnd": "2026-01-25T15:00:00Z", - "cloudCover": 0.41, - "conditionCode": "PartlyCloudy", - "humidity": 0.87, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 10.99, - "temperatureMin": 8.32, - "windDirection": 170, - "windGustSpeedMax": 16.36, - "windSpeed": 7.05, - "windSpeedMax": 8.54 - } - }, - { - "forecastStart": "2026-01-25T08:00:00Z", - "forecastEnd": "2026-01-26T08:00:00Z", - "conditionCode": "PartlyCloudy", - "maxUvIndex": 3, - "moonPhase": "waxingCrescent", - "moonrise": "2026-01-25T18:48:10Z", - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "solarMidnight": "2026-01-25T08:21:55Z", - "solarNoon": "2026-01-25T20:22:16Z", - "sunrise": "2026-01-25T15:18:50Z", - "sunriseCivil": "2026-01-25T14:50:48Z", - "sunriseNautical": "2026-01-25T14:19:04Z", - "sunriseAstronomical": "2026-01-25T13:47:59Z", - "sunset": "2026-01-26T01:25:56Z", - "sunsetCivil": "2026-01-26T01:53:53Z", - "sunsetNautical": "2026-01-26T02:25:40Z", - "sunsetAstronomical": "2026-01-26T02:56:42Z", - "temperatureMax": 13.9, - "temperatureMin": 8.32, - "windGustSpeedMax": 15.97, - "windSpeedAvg": 9.09, - "windSpeedMax": 11.17, - "daytimeForecast": { - "forecastStart": "2026-01-25T15:00:00Z", - "forecastEnd": "2026-01-26T03:00:00Z", - "cloudCover": 0.51, - "conditionCode": "PartlyCloudy", - "humidity": 0.78, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 13.9, - "temperatureMin": 8.74, - "windDirection": 45, - "windGustSpeedMax": 15.97, - "windSpeed": 10.2, - "windSpeedMax": 11.17 - }, - "overnightForecast": { - "forecastStart": "2026-01-26T03:00:00Z", - "forecastEnd": "2026-01-26T15:00:00Z", - "cloudCover": 0.56, - "conditionCode": "PartlyCloudy", - "humidity": 0.88, - "precipitationAmount": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "snowfallAmount": 0, - "temperatureMax": 12.43, - "temperatureMin": 9.06, - "windDirection": 57, - "windGustSpeedMax": 11.61, - "windSpeed": 7.45, - "windSpeedMax": 9.93 - } - } - ] - }, - "forecastHourly": { - "name": "HourlyForecast", - "metadata": { - "attributionURL": "https://developer.apple.com/weatherkit/data-source-attribution/", - "expireTime": "2026-01-17T01:37:11Z", - "latitude": 37.77, - "longitude": -122.42, - "readTime": "2026-01-17T00:37:11Z", - "reportedTime": "2026-01-16T23:05:34Z", - "units": "m", - "version": 1, - "sourceType": "modeled" - }, - "hours": [ - { - "forecastStart": "2026-01-16T06:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.78, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1016.91, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.96, - "temperatureApparent": 11.68, - "temperatureDewPoint": 8.24, - "uvIndex": 0, - "visibility": 25281, - "windDirection": 5, - "windGust": 2.65, - "windSpeed": 0.73 - }, - { - "forecastStart": "2026-01-16T07:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.79, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.43, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.37, - "temperatureApparent": 11.14, - "temperatureDewPoint": 7.86, - "uvIndex": 0, - "visibility": 24048, - "windDirection": 182, - "windGust": 2.79, - "windSpeed": 0.8 - }, - { - "forecastStart": "2026-01-16T08:00:00Z", - "cloudCover": 0.02, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.83, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.53, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.62, - "temperatureApparent": 10.52, - "temperatureDewPoint": 7.85, - "uvIndex": 0, - "visibility": 22707, - "windDirection": 357, - "windGust": 3.88, - "windSpeed": 0.82 - }, - { - "forecastStart": "2026-01-16T09:00:00Z", - "cloudCover": 0.02, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.83, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.5, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.39, - "temperatureApparent": 10.33, - "temperatureDewPoint": 7.63, - "uvIndex": 0, - "visibility": 25066, - "windDirection": 200, - "windGust": 2.5, - "windSpeed": 0.68 - }, - { - "forecastStart": "2026-01-16T10:00:00Z", - "cloudCover": 0.12, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.89, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.59, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.56, - "temperatureApparent": 9.41, - "temperatureDewPoint": 7.84, - "uvIndex": 0, - "visibility": 18724, - "windDirection": 9, - "windGust": 4.97, - "windSpeed": 2.56 - }, - { - "forecastStart": "2026-01-16T11:00:00Z", - "cloudCover": 0.12, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.9, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.67, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.89, - "temperatureApparent": 8.97, - "temperatureDewPoint": 7.34, - "uvIndex": 0, - "visibility": 16412, - "windDirection": 338, - "windGust": 4.78, - "windSpeed": 1.75 - }, - { - "forecastStart": "2026-01-16T12:00:00Z", - "cloudCover": 0.12, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.91, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.42, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.94, - "temperatureApparent": 8.37, - "temperatureDewPoint": 7.55, - "uvIndex": 0, - "visibility": 16605, - "windDirection": 354, - "windGust": 7.59, - "windSpeed": 4.32 - }, - { - "forecastStart": "2026-01-16T13:00:00Z", - "cloudCover": 0.04, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.88, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.3, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.08, - "temperatureApparent": 8.67, - "temperatureDewPoint": 7.2, - "uvIndex": 0, - "visibility": 19567, - "windDirection": 336, - "windGust": 6.45, - "windSpeed": 3.24 - }, - { - "forecastStart": "2026-01-16T14:00:00Z", - "cloudCover": 0.06, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.79, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.24, - "temperatureApparent": 9.08, - "temperatureDewPoint": 6.68, - "uvIndex": 0, - "visibility": 20343, - "windDirection": 339, - "windGust": 5.93, - "windSpeed": 2.13 - }, - { - "forecastStart": "2026-01-16T15:00:00Z", - "cloudCover": 0.3, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.87, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.1, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.02, - "temperatureApparent": 9.47, - "temperatureDewPoint": 6.97, - "uvIndex": 0, - "visibility": 15151, - "windDirection": 279, - "windGust": 3.14, - "windSpeed": 0.99 - }, - { - "forecastStart": "2026-01-16T16:00:00Z", - "cloudCover": 0.03, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.19, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.71, - "temperatureApparent": 11.3, - "temperatureDewPoint": 7.14, - "uvIndex": 0, - "visibility": 19853, - "windDirection": 339, - "windGust": 5.91, - "windSpeed": 3.46 - }, - { - "forecastStart": "2026-01-16T17:00:00Z", - "cloudCover": 0.02, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.82, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.69, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.86, - "temperatureApparent": 15.63, - "temperatureDewPoint": 8.89, - "uvIndex": 1, - "visibility": 21686, - "windDirection": 245, - "windGust": 4.28, - "windSpeed": 1.65 - }, - { - "forecastStart": "2026-01-16T18:00:00Z", - "cloudCover": 0.01, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.72, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.12, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 14.33, - "temperatureApparent": 18.29, - "temperatureDewPoint": 9.35, - "uvIndex": 1, - "visibility": 25615, - "windDirection": 44, - "windGust": 5.63, - "windSpeed": 1.31 - }, - { - "forecastStart": "2026-01-16T19:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.59, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.16, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 16.21, - "temperatureApparent": 19.27, - "temperatureDewPoint": 8.19, - "uvIndex": 2, - "visibility": 34519, - "windDirection": 69, - "windGust": 9.4, - "windSpeed": 4.72 - }, - { - "forecastStart": "2026-01-16T20:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.53, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.71, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 17.61, - "temperatureApparent": 20.71, - "temperatureDewPoint": 7.92, - "uvIndex": 3, - "visibility": 35618, - "windDirection": 81, - "windGust": 8.53, - "windSpeed": 4.12 - }, - { - "forecastStart": "2026-01-16T21:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.44, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.86, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 19.46, - "temperatureApparent": 22.52, - "temperatureDewPoint": 6.89, - "uvIndex": 3, - "visibility": 38272, - "windDirection": 75, - "windGust": 5.78, - "windSpeed": 3.32 - }, - { - "forecastStart": "2026-01-16T22:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.4, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.42, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 19.87, - "temperatureApparent": 22.74, - "temperatureDewPoint": 5.87, - "uvIndex": 2, - "visibility": 40905, - "windDirection": 59, - "windGust": 8.74, - "windSpeed": 3.64 - }, - { - "forecastStart": "2026-01-16T23:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.45, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.42, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 19.25, - "temperatureApparent": 21.53, - "temperatureDewPoint": 7.02, - "uvIndex": 1, - "visibility": 35011, - "windDirection": 3, - "windGust": 9.57, - "windSpeed": 6.19 - }, - { - "forecastStart": "2026-01-17T00:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.58, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.63, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 17.2, - "temperatureApparent": 17.49, - "temperatureDewPoint": 8.86, - "uvIndex": 0, - "visibility": 32714, - "windDirection": 2, - "windGust": 18.66, - "windSpeed": 11.53 - }, - { - "forecastStart": "2026-01-17T01:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.65, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.8, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 15.13, - "temperatureApparent": 12.79, - "temperatureDewPoint": 8.6, - "uvIndex": 0, - "visibility": 29392, - "windDirection": 347, - "windGust": 17.07, - "windSpeed": 10.92 - }, - { - "forecastStart": "2026-01-17T02:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.68, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.62, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.69, - "temperatureApparent": 10.87, - "temperatureDewPoint": 7.89, - "uvIndex": 0, - "visibility": 28074, - "windDirection": 341, - "windGust": 16.19, - "windSpeed": 10.59 - }, - { - "forecastStart": "2026-01-17T03:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.75, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.15, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.51, - "temperatureApparent": 9.61, - "temperatureDewPoint": 8.2, - "uvIndex": 0, - "visibility": 25398, - "windDirection": 342, - "windGust": 16.85, - "windSpeed": 10.57 - }, - { - "forecastStart": "2026-01-17T04:00:00Z", - "cloudCover": 0.01, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.78, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.61, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.77, - "temperatureApparent": 8.75, - "temperatureDewPoint": 8.06, - "uvIndex": 0, - "visibility": 23936, - "windDirection": 347, - "windGust": 18.52, - "windSpeed": 10.89 - }, - { - "forecastStart": "2026-01-17T05:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.82, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.12, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.94, - "temperatureApparent": 8.22, - "temperatureDewPoint": 7.99, - "uvIndex": 0, - "visibility": 23576, - "windDirection": 344, - "windGust": 16.32, - "windSpeed": 9.92 - }, - { - "forecastStart": "2026-01-17T06:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.26, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.38, - "temperatureApparent": 7.61, - "temperatureDewPoint": 7.79, - "uvIndex": 0, - "visibility": 22835, - "windDirection": 348, - "windGust": 16.17, - "windSpeed": 10.07 - }, - { - "forecastStart": "2026-01-17T07:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.23, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.85, - "temperatureApparent": 7.02, - "temperatureDewPoint": 7.62, - "uvIndex": 0, - "visibility": 21793, - "windDirection": 351, - "windGust": 15.88, - "windSpeed": 10.2 - }, - { - "forecastStart": "2026-01-17T08:00:00Z", - "cloudCover": 0.04, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.82, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.15, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.95, - "temperatureApparent": 7.52, - "temperatureDewPoint": 7.02, - "uvIndex": 0, - "visibility": 22640, - "windDirection": 17, - "windGust": 13.96, - "windSpeed": 9.07 - }, - { - "forecastStart": "2026-01-17T09:00:00Z", - "cloudCover": 0.05, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.85, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.24, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.4, - "temperatureApparent": 6.98, - "temperatureDewPoint": 7.01, - "uvIndex": 0, - "visibility": 21858, - "windDirection": 23, - "windGust": 14.17, - "windSpeed": 9.08 - }, - { - "forecastStart": "2026-01-17T10:00:00Z", - "cloudCover": 0.07, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.57, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.01, - "temperatureApparent": 6.5, - "temperatureDewPoint": 6.79, - "uvIndex": 0, - "visibility": 21783, - "windDirection": 27, - "windGust": 14.07, - "windSpeed": 9.38 - }, - { - "forecastStart": "2026-01-17T11:00:00Z", - "cloudCover": 0.14, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.66, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.72, - "temperatureApparent": 6.08, - "temperatureDewPoint": 6.51, - "uvIndex": 0, - "visibility": 21016, - "windDirection": 26, - "windGust": 14.98, - "windSpeed": 9.95 - }, - { - "forecastStart": "2026-01-17T12:00:00Z", - "cloudCover": 0.24, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.87, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.7, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.54, - "temperatureApparent": 5.59, - "temperatureDewPoint": 6.5, - "uvIndex": 0, - "visibility": 20080, - "windDirection": 24, - "windGust": 16.9, - "windSpeed": 11.06 - }, - { - "forecastStart": "2026-01-17T13:00:00Z", - "cloudCover": 0.34, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.87, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.91, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.31, - "temperatureApparent": 5.4, - "temperatureDewPoint": 6.27, - "uvIndex": 0, - "visibility": 19963, - "windDirection": 26, - "windGust": 16.98, - "windSpeed": 11.28 - }, - { - "forecastStart": "2026-01-17T14:00:00Z", - "cloudCover": 0.42, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.87, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.34, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.14, - "temperatureApparent": 5.4, - "temperatureDewPoint": 6.11, - "uvIndex": 0, - "visibility": 20565, - "windDirection": 27, - "windGust": 16.86, - "windSpeed": 11.08 - }, - { - "forecastStart": "2026-01-17T15:00:00Z", - "cloudCover": 0.56, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.87, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.65, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.04, - "temperatureApparent": 5.55, - "temperatureDewPoint": 6.01, - "uvIndex": 0, - "visibility": 21167, - "windDirection": 30, - "windGust": 16.38, - "windSpeed": 10.9 - }, - { - "forecastStart": "2026-01-17T16:00:00Z", - "cloudCover": 0.57, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1021.03, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.36, - "temperatureApparent": 6.37, - "temperatureDewPoint": 6.15, - "uvIndex": 0, - "visibility": 18945, - "windDirection": 35, - "windGust": 16.9, - "windSpeed": 11.12 - }, - { - "forecastStart": "2026-01-17T17:00:00Z", - "cloudCover": 0.58, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.83, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1021.58, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.44, - "temperatureApparent": 7.94, - "temperatureDewPoint": 6.7, - "uvIndex": 1, - "visibility": 19316, - "windDirection": 36, - "windGust": 16.93, - "windSpeed": 11.17 - }, - { - "forecastStart": "2026-01-17T18:00:00Z", - "cloudCover": 0.77, - "conditionCode": "MostlyCloudy", - "daylight": true, - "humidity": 0.78, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1021.84, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.98, - "temperatureApparent": 8.8, - "temperatureDewPoint": 7.29, - "uvIndex": 1, - "visibility": 21518, - "windDirection": 38, - "windGust": 16.37, - "windSpeed": 11.3 - }, - { - "forecastStart": "2026-01-17T19:00:00Z", - "cloudCover": 0.78, - "conditionCode": "MostlyCloudy", - "daylight": true, - "humidity": 0.73, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1021.83, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.44, - "temperatureApparent": 10.28, - "temperatureDewPoint": 7.73, - "uvIndex": 2, - "visibility": 23392, - "windDirection": 36, - "windGust": 16.75, - "windSpeed": 11.28 - }, - { - "forecastStart": "2026-01-17T20:00:00Z", - "cloudCover": 0.77, - "conditionCode": "MostlyCloudy", - "daylight": true, - "humidity": 0.67, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1021.36, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 14.1, - "temperatureApparent": 12.23, - "temperatureDewPoint": 8.06, - "uvIndex": 2, - "visibility": 26378, - "windDirection": 32, - "windGust": 17.3, - "windSpeed": 11.03 - }, - { - "forecastStart": "2026-01-17T21:00:00Z", - "cloudCover": 0.73, - "conditionCode": "MostlyCloudy", - "daylight": true, - "humidity": 0.62, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.86, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 15.48, - "temperatureApparent": 13.83, - "temperatureDewPoint": 8.23, - "uvIndex": 2, - "visibility": 27132, - "windDirection": 27, - "windGust": 18.8, - "windSpeed": 11.17 - }, - { - "forecastStart": "2026-01-17T22:00:00Z", - "cloudCover": 0.78, - "conditionCode": "MostlyCloudy", - "daylight": true, - "humidity": 0.58, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.48, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 16.42, - "temperatureApparent": 14.69, - "temperatureDewPoint": 8.13, - "uvIndex": 2, - "visibility": 28404, - "windDirection": 26, - "windGust": 20.39, - "windSpeed": 11.13 - }, - { - "forecastStart": "2026-01-17T23:00:00Z", - "cloudCover": 0.76, - "conditionCode": "MostlyCloudy", - "daylight": true, - "humidity": 0.56, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.39, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 16.88, - "temperatureApparent": 15.38, - "temperatureDewPoint": 8.05, - "uvIndex": 1, - "visibility": 28630, - "windDirection": 24, - "windGust": 20.01, - "windSpeed": 10.68 - }, - { - "forecastStart": "2026-01-18T00:00:00Z", - "cloudCover": 0.68, - "conditionCode": "MostlyCloudy", - "daylight": true, - "humidity": 0.57, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.42, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 16.78, - "temperatureApparent": 15.67, - "temperatureDewPoint": 8.21, - "uvIndex": 0, - "visibility": 28195, - "windDirection": 21, - "windGust": 18.22, - "windSpeed": 9.93 - }, - { - "forecastStart": "2026-01-18T01:00:00Z", - "cloudCover": 0.79, - "conditionCode": "MostlyCloudy", - "daylight": true, - "humidity": 0.61, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.7, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 15.47, - "temperatureApparent": 14.06, - "temperatureDewPoint": 7.98, - "uvIndex": 0, - "visibility": 27557, - "windDirection": 20, - "windGust": 17.83, - "windSpeed": 9.49 - }, - { - "forecastStart": "2026-01-18T02:00:00Z", - "cloudCover": 0.74, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.65, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1021.12, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 14.36, - "temperatureApparent": 12.8, - "temperatureDewPoint": 7.87, - "uvIndex": 0, - "visibility": 27266, - "windDirection": 20, - "windGust": 16.92, - "windSpeed": 9.45 - }, - { - "forecastStart": "2026-01-18T03:00:00Z", - "cloudCover": 0.69, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.68, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1021.5, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.41, - "temperatureApparent": 11.91, - "temperatureDewPoint": 7.62, - "uvIndex": 0, - "visibility": 27301, - "windDirection": 21, - "windGust": 14.77, - "windSpeed": 8.85 - }, - { - "forecastStart": "2026-01-18T04:00:00Z", - "cloudCover": 0.85, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.71, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1021.76, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.58, - "temperatureApparent": 11.22, - "temperatureDewPoint": 7.46, - "uvIndex": 0, - "visibility": 27156, - "windDirection": 26, - "windGust": 14.62, - "windSpeed": 8.91 - }, - { - "forecastStart": "2026-01-18T05:00:00Z", - "cloudCover": 0.87, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.73, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.95, - "temperatureApparent": 10.78, - "temperatureDewPoint": 7.26, - "uvIndex": 0, - "visibility": 26528, - "windDirection": 26, - "windGust": 13.29, - "windSpeed": 8.33 - }, - { - "forecastStart": "2026-01-18T06:00:00Z", - "cloudCover": 0.89, - "conditionCode": "Cloudy", - "daylight": false, - "humidity": 0.75, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.25, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.47, - "temperatureApparent": 10.34, - "temperatureDewPoint": 7.19, - "uvIndex": 0, - "visibility": 26125, - "windDirection": 29, - "windGust": 13.6, - "windSpeed": 8.33 - }, - { - "forecastStart": "2026-01-18T07:00:00Z", - "cloudCover": 0.87, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.76, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.4, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.01, - "temperatureApparent": 10.01, - "temperatureDewPoint": 6.94, - "uvIndex": 0, - "visibility": 24304, - "windDirection": 30, - "windGust": 13.12, - "windSpeed": 7.95 - }, - { - "forecastStart": "2026-01-18T08:00:00Z", - "cloudCover": 0.83, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.78, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.42, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.59, - "temperatureApparent": 9.4, - "temperatureDewPoint": 6.91, - "uvIndex": 0, - "visibility": 22807, - "windDirection": 32, - "windGust": 14.07, - "windSpeed": 8.35 - }, - { - "forecastStart": "2026-01-18T09:00:00Z", - "cloudCover": 0.78, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.79, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.42, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.22, - "temperatureApparent": 8.89, - "temperatureDewPoint": 6.74, - "uvIndex": 0, - "visibility": 22647, - "windDirection": 32, - "windGust": 14.04, - "windSpeed": 8.59 - }, - { - "forecastStart": "2026-01-18T10:00:00Z", - "cloudCover": 0.82, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.8, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.55, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.85, - "temperatureApparent": 8.61, - "temperatureDewPoint": 6.56, - "uvIndex": 0, - "visibility": 22592, - "windDirection": 33, - "windGust": 13.99, - "windSpeed": 8.49 - }, - { - "forecastStart": "2026-01-18T11:00:00Z", - "cloudCover": 0.86, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.82, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.34, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.54, - "temperatureApparent": 8.16, - "temperatureDewPoint": 6.62, - "uvIndex": 0, - "visibility": 23167, - "windDirection": 29, - "windGust": 13.28, - "windSpeed": 9.03 - }, - { - "forecastStart": "2026-01-18T12:00:00Z", - "cloudCover": 0.86, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.83, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.05, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.33, - "temperatureApparent": 7.71, - "temperatureDewPoint": 6.59, - "uvIndex": 0, - "visibility": 22506, - "windDirection": 33, - "windGust": 14.22, - "windSpeed": 9.66 - }, - { - "forecastStart": "2026-01-18T13:00:00Z", - "cloudCover": 0.84, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1021.98, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.21, - "temperatureApparent": 7.5, - "temperatureDewPoint": 6.65, - "uvIndex": 0, - "visibility": 22218, - "windDirection": 35, - "windGust": 13.78, - "windSpeed": 9.83 - }, - { - "forecastStart": "2026-01-18T14:00:00Z", - "cloudCover": 0.85, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.17, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.08, - "temperatureApparent": 7.3, - "temperatureDewPoint": 6.52, - "uvIndex": 0, - "visibility": 21996, - "windDirection": 35, - "windGust": 14.57, - "windSpeed": 10.05 - }, - { - "forecastStart": "2026-01-18T15:00:00Z", - "cloudCover": 0.78, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.39, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.19, - "temperatureApparent": 7.34, - "temperatureDewPoint": 6.63, - "uvIndex": 0, - "visibility": 22507, - "windDirection": 35, - "windGust": 14.86, - "windSpeed": 9.98 - }, - { - "forecastStart": "2026-01-18T16:00:00Z", - "cloudCover": 0.6, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.82, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.49, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.58, - "temperatureApparent": 8.1, - "temperatureDewPoint": 6.66, - "uvIndex": 0, - "visibility": 23001, - "windDirection": 38, - "windGust": 14.49, - "windSpeed": 9.73 - }, - { - "forecastStart": "2026-01-18T17:00:00Z", - "cloudCover": 0.55, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.79, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.72, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.57, - "temperatureApparent": 9.93, - "temperatureDewPoint": 7.08, - "uvIndex": 1, - "visibility": 25449, - "windDirection": 42, - "windGust": 15.2, - "windSpeed": 9.09 - }, - { - "forecastStart": "2026-01-18T18:00:00Z", - "cloudCover": 0.34, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.73, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.81, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.15, - "temperatureApparent": 12.33, - "temperatureDewPoint": 7.45, - "uvIndex": 1, - "visibility": 26640, - "windDirection": 42, - "windGust": 15.01, - "windSpeed": 9.21 - }, - { - "forecastStart": "2026-01-18T19:00:00Z", - "cloudCover": 0.26, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.66, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.57, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.9, - "temperatureApparent": 14.42, - "temperatureDewPoint": 7.65, - "uvIndex": 2, - "visibility": 27682, - "windDirection": 48, - "windGust": 15.8, - "windSpeed": 9.11 - }, - { - "forecastStart": "2026-01-18T20:00:00Z", - "cloudCover": 0.17, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.59, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1021.81, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 15.65, - "temperatureApparent": 16.41, - "temperatureDewPoint": 7.66, - "uvIndex": 3, - "visibility": 28854, - "windDirection": 41, - "windGust": 17.27, - "windSpeed": 9.53 - }, - { - "forecastStart": "2026-01-18T21:00:00Z", - "cloudCover": 0.1, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.54, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1021.03, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 16.97, - "temperatureApparent": 18.03, - "temperatureDewPoint": 7.6, - "uvIndex": 3, - "visibility": 29576, - "windDirection": 32, - "windGust": 19.32, - "windSpeed": 9.45 - }, - { - "forecastStart": "2026-01-18T22:00:00Z", - "cloudCover": 0.18, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.51, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.52, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 17.8, - "temperatureApparent": 18.7, - "temperatureDewPoint": 7.53, - "uvIndex": 2, - "visibility": 29821, - "windDirection": 27, - "windGust": 20.16, - "windSpeed": 9.03 - }, - { - "forecastStart": "2026-01-18T23:00:00Z", - "cloudCover": 0.05, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.5, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.22, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 18.18, - "temperatureApparent": 19.54, - "temperatureDewPoint": 7.59, - "uvIndex": 1, - "visibility": 29869, - "windDirection": 21, - "windGust": 19.28, - "windSpeed": 8.49 - }, - { - "forecastStart": "2026-01-19T00:00:00Z", - "cloudCover": 0.1, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.5, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.01, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 17.86, - "temperatureApparent": 18.68, - "temperatureDewPoint": 7.29, - "uvIndex": 0, - "visibility": 29687, - "windDirection": 9, - "windGust": 18.48, - "windSpeed": 7.99 - }, - { - "forecastStart": "2026-01-19T01:00:00Z", - "cloudCover": 0.09, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.53, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.94, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 16.67, - "temperatureApparent": 15.43, - "temperatureDewPoint": 7.04, - "uvIndex": 0, - "visibility": 29314, - "windDirection": 0, - "windGust": 17.16, - "windSpeed": 7.43 - }, - { - "forecastStart": "2026-01-19T02:00:00Z", - "cloudCover": 0.03, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.59, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 15.24, - "temperatureApparent": 13.58, - "temperatureDewPoint": 7.28, - "uvIndex": 0, - "visibility": 28859, - "windDirection": 0, - "windGust": 15.11, - "windSpeed": 6.78 - }, - { - "forecastStart": "2026-01-19T03:00:00Z", - "cloudCover": 0.02, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.64, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 14.04, - "temperatureApparent": 12.55, - "temperatureDewPoint": 7.33, - "uvIndex": 0, - "visibility": 28557, - "windDirection": 3, - "windGust": 13.01, - "windSpeed": 6.04 - }, - { - "forecastStart": "2026-01-19T04:00:00Z", - "cloudCover": 0.02, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.68, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.96, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.14, - "temperatureApparent": 11.76, - "temperatureDewPoint": 7.36, - "uvIndex": 0, - "visibility": 27881, - "windDirection": 11, - "windGust": 11.88, - "windSpeed": 5.61 - }, - { - "forecastStart": "2026-01-19T05:00:00Z", - "cloudCover": 0.02, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.72, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.97, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.36, - "temperatureApparent": 11.06, - "temperatureDewPoint": 7.45, - "uvIndex": 0, - "visibility": 27407, - "windDirection": 17, - "windGust": 11.11, - "windSpeed": 5.26 - }, - { - "forecastStart": "2026-01-19T06:00:00Z", - "cloudCover": 0.02, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.74, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.01, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.67, - "temperatureApparent": 10.49, - "temperatureDewPoint": 7.19, - "uvIndex": 0, - "visibility": 27084, - "windDirection": 26, - "windGust": 10.39, - "windSpeed": 4.96 - }, - { - "forecastStart": "2026-01-19T07:00:00Z", - "cloudCover": 0.08, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.77, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.01, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.89, - "temperatureApparent": 9.97, - "temperatureDewPoint": 7.02, - "uvIndex": 0, - "visibility": 26394, - "windDirection": 33, - "windGust": 9.21, - "windSpeed": 4.52 - }, - { - "forecastStart": "2026-01-19T08:00:00Z", - "cloudCover": 0.17, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.8, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.89, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.28, - "temperatureApparent": 9.64, - "temperatureDewPoint": 6.98, - "uvIndex": 0, - "visibility": 25832, - "windDirection": 42, - "windGust": 8.07, - "windSpeed": 4.15 - }, - { - "forecastStart": "2026-01-19T09:00:00Z", - "cloudCover": 0.26, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.82, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.76, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.76, - "temperatureApparent": 9.26, - "temperatureDewPoint": 6.83, - "uvIndex": 0, - "visibility": 24877, - "windDirection": 51, - "windGust": 7.75, - "windSpeed": 4.24 - }, - { - "forecastStart": "2026-01-19T10:00:00Z", - "cloudCover": 0.27, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.83, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.66, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.32, - "temperatureApparent": 8.75, - "temperatureDewPoint": 6.58, - "uvIndex": 0, - "visibility": 22331, - "windDirection": 56, - "windGust": 7.8, - "windSpeed": 4.59 - }, - { - "forecastStart": "2026-01-19T11:00:00Z", - "cloudCover": 0.27, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.43, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.97, - "temperatureApparent": 8.31, - "temperatureDewPoint": 6.41, - "uvIndex": 0, - "visibility": 21652, - "windDirection": 54, - "windGust": 7.97, - "windSpeed": 4.91 - }, - { - "forecastStart": "2026-01-19T12:00:00Z", - "cloudCover": 0.29, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.13, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.83, - "temperatureApparent": 8.15, - "temperatureDewPoint": 6.62, - "uvIndex": 0, - "visibility": 20961, - "windDirection": 51, - "windGust": 7.97, - "windSpeed": 5.11 - }, - { - "forecastStart": "2026-01-19T13:00:00Z", - "cloudCover": 0.23, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.03, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.41, - "temperatureApparent": 7.53, - "temperatureDewPoint": 6.2, - "uvIndex": 0, - "visibility": 20134, - "windDirection": 47, - "windGust": 8.5, - "windSpeed": 5.49 - }, - { - "forecastStart": "2026-01-19T14:00:00Z", - "cloudCover": 0.19, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.87, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.08, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.36, - "temperatureApparent": 7.26, - "temperatureDewPoint": 6.32, - "uvIndex": 0, - "visibility": 19096, - "windDirection": 44, - "windGust": 9.02, - "windSpeed": 5.97 - }, - { - "forecastStart": "2026-01-19T15:00:00Z", - "cloudCover": 0.27, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.23, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.46, - "temperatureApparent": 7.25, - "temperatureDewPoint": 6.25, - "uvIndex": 0, - "visibility": 17581, - "windDirection": 42, - "windGust": 9.44, - "windSpeed": 6.54 - }, - { - "forecastStart": "2026-01-19T16:00:00Z", - "cloudCover": 0.3, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.46, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.68, - "temperatureApparent": 8.44, - "temperatureDewPoint": 6.13, - "uvIndex": 0, - "visibility": 18744, - "windDirection": 42, - "windGust": 10.29, - "windSpeed": 7.37 - }, - { - "forecastStart": "2026-01-19T17:00:00Z", - "cloudCover": 0.31, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.81, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.85, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.55, - "temperatureApparent": 10.22, - "temperatureDewPoint": 6.45, - "uvIndex": 1, - "visibility": 19891, - "windDirection": 44, - "windGust": 10.95, - "windSpeed": 7.71 - }, - { - "forecastStart": "2026-01-19T18:00:00Z", - "cloudCover": 0.32, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.76, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.16, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.87, - "temperatureApparent": 11.62, - "temperatureDewPoint": 6.81, - "uvIndex": 1, - "visibility": 24708, - "windDirection": 42, - "windGust": 11.26, - "windSpeed": 7.8 - }, - { - "forecastStart": "2026-01-19T19:00:00Z", - "cloudCover": 0.27, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.68, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.06, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.68, - "temperatureApparent": 13.27, - "temperatureDewPoint": 6.93, - "uvIndex": 2, - "visibility": 27216, - "windDirection": 39, - "windGust": 12.84, - "windSpeed": 8.6 - }, - { - "forecastStart": "2026-01-19T20:00:00Z", - "cloudCover": 0.11, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.6, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.38, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 14.58, - "temperatureApparent": 15.49, - "temperatureDewPoint": 6.9, - "uvIndex": 3, - "visibility": 28895, - "windDirection": 33, - "windGust": 15.22, - "windSpeed": 9.46 - }, - { - "forecastStart": "2026-01-19T21:00:00Z", - "cloudCover": 0.06, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.54, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.63, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 16.06, - "temperatureApparent": 17.02, - "temperatureDewPoint": 6.75, - "uvIndex": 3, - "visibility": 30281, - "windDirection": 27, - "windGust": 16.44, - "windSpeed": 9.92 - }, - { - "forecastStart": "2026-01-19T22:00:00Z", - "cloudCover": 0.1, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.51, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.1, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 16.97, - "temperatureApparent": 17.79, - "temperatureDewPoint": 6.76, - "uvIndex": 2, - "visibility": 30544, - "windDirection": 24, - "windGust": 17.27, - "windSpeed": 9.93 - }, - { - "forecastStart": "2026-01-19T23:00:00Z", - "cloudCover": 0.05, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.48, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.78, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 17.38, - "temperatureApparent": 18.35, - "temperatureDewPoint": 6.26, - "uvIndex": 1, - "visibility": 30235, - "windDirection": 23, - "windGust": 17.91, - "windSpeed": 9.57 - }, - { - "forecastStart": "2026-01-20T00:00:00Z", - "cloudCover": 0.02, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.49, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.59, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 17.22, - "temperatureApparent": 17.99, - "temperatureDewPoint": 6.41, - "uvIndex": 0, - "visibility": 29939, - "windDirection": 20, - "windGust": 16.55, - "windSpeed": 8.69 - }, - { - "forecastStart": "2026-01-20T01:00:00Z", - "cloudCover": 0.02, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.52, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.62, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 16.18, - "temperatureApparent": 14.85, - "temperatureDewPoint": 6.31, - "uvIndex": 0, - "visibility": 29604, - "windDirection": 15, - "windGust": 14.34, - "windSpeed": 7.54 - }, - { - "forecastStart": "2026-01-20T02:00:00Z", - "cloudCover": 0.03, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.56, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.91, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 14.86, - "temperatureApparent": 13.01, - "temperatureDewPoint": 6.16, - "uvIndex": 0, - "visibility": 28795, - "windDirection": 12, - "windGust": 12.98, - "windSpeed": 7.14 - }, - { - "forecastStart": "2026-01-20T03:00:00Z", - "cloudCover": 0.03, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.6, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.2, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.69, - "temperatureApparent": 11.8, - "temperatureDewPoint": 6.06, - "uvIndex": 0, - "visibility": 27947, - "windDirection": 17, - "windGust": 12.37, - "windSpeed": 7.12 - }, - { - "forecastStart": "2026-01-20T04:00:00Z", - "cloudCover": 0.03, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.64, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.45, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.71, - "temperatureApparent": 10.68, - "temperatureDewPoint": 6.07, - "uvIndex": 0, - "visibility": 27449, - "windDirection": 21, - "windGust": 13.02, - "windSpeed": 7.45 - }, - { - "forecastStart": "2026-01-20T05:00:00Z", - "cloudCover": 0.04, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.68, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.69, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.64, - "temperatureApparent": 9.51, - "temperatureDewPoint": 5.93, - "uvIndex": 0, - "visibility": 27330, - "windDirection": 26, - "windGust": 13.61, - "windSpeed": 7.72 - }, - { - "forecastStart": "2026-01-20T06:00:00Z", - "cloudCover": 0.04, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.72, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.92, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.84, - "temperatureApparent": 8.69, - "temperatureDewPoint": 5.99, - "uvIndex": 0, - "visibility": 26377, - "windDirection": 30, - "windGust": 13.95, - "windSpeed": 7.92 - }, - { - "forecastStart": "2026-01-20T07:00:00Z", - "cloudCover": 0.01, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.75, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.65, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.99, - "temperatureApparent": 7.81, - "temperatureDewPoint": 5.76, - "uvIndex": 0, - "visibility": 27658, - "windDirection": 29, - "windGust": 14.76, - "windSpeed": 7.95 - }, - { - "forecastStart": "2026-01-20T08:00:00Z", - "cloudCover": 0.02, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.78, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.69, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.39, - "temperatureApparent": 7.26, - "temperatureDewPoint": 5.75, - "uvIndex": 0, - "visibility": 26837, - "windDirection": 32, - "windGust": 14.44, - "windSpeed": 7.91 - }, - { - "forecastStart": "2026-01-20T09:00:00Z", - "cloudCover": 0.02, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.8, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.67, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.86, - "temperatureApparent": 6.63, - "temperatureDewPoint": 5.6, - "uvIndex": 0, - "visibility": 25655, - "windDirection": 35, - "windGust": 14.58, - "windSpeed": 8.21 - }, - { - "forecastStart": "2026-01-20T10:00:00Z", - "cloudCover": 0.05, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.83, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.64, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.39, - "temperatureApparent": 6.09, - "temperatureDewPoint": 5.67, - "uvIndex": 0, - "visibility": 23659, - "windDirection": 36, - "windGust": 15.14, - "windSpeed": 8.54 - }, - { - "forecastStart": "2026-01-20T11:00:00Z", - "cloudCover": 0.08, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.85, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.54, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.01, - "temperatureApparent": 5.55, - "temperatureDewPoint": 5.64, - "uvIndex": 0, - "visibility": 21303, - "windDirection": 38, - "windGust": 16.04, - "windSpeed": 9.07 - }, - { - "forecastStart": "2026-01-20T12:00:00Z", - "cloudCover": 0.11, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.5, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 7.74, - "temperatureApparent": 5.2, - "temperatureDewPoint": 5.55, - "uvIndex": 0, - "visibility": 19499, - "windDirection": 41, - "windGust": 16.49, - "windSpeed": 9.39 - }, - { - "forecastStart": "2026-01-20T13:00:00Z", - "cloudCover": 0.12, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.87, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.58, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 7.54, - "temperatureApparent": 4.96, - "temperatureDewPoint": 5.52, - "uvIndex": 0, - "visibility": 18464, - "windDirection": 44, - "windGust": 16.21, - "windSpeed": 9.52 - }, - { - "forecastStart": "2026-01-20T14:00:00Z", - "cloudCover": 0.13, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.87, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.77, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 7.43, - "temperatureApparent": 4.85, - "temperatureDewPoint": 5.41, - "uvIndex": 0, - "visibility": 17980, - "windDirection": 47, - "windGust": 15.64, - "windSpeed": 9.54 - }, - { - "forecastStart": "2026-01-20T15:00:00Z", - "cloudCover": 0.14, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.06, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 7.95, - "temperatureApparent": 5.41, - "temperatureDewPoint": 5.75, - "uvIndex": 0, - "visibility": 18313, - "windDirection": 50, - "windGust": 15.26, - "windSpeed": 9.45 - }, - { - "forecastStart": "2026-01-20T16:00:00Z", - "cloudCover": 0.16, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.45, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.37, - "temperatureApparent": 7.44, - "temperatureDewPoint": 5.82, - "uvIndex": 0, - "visibility": 19824, - "windDirection": 51, - "windGust": 15.29, - "windSpeed": 9.48 - }, - { - "forecastStart": "2026-01-20T17:00:00Z", - "cloudCover": 0.17, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.81, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.85, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.12, - "temperatureApparent": 9.63, - "temperatureDewPoint": 6.03, - "uvIndex": 1, - "visibility": 22154, - "windDirection": 51, - "windGust": 15.42, - "windSpeed": 9.37 - }, - { - "forecastStart": "2026-01-20T18:00:00Z", - "cloudCover": 0.17, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.76, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.03, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.19, - "temperatureApparent": 11.03, - "temperatureDewPoint": 6.15, - "uvIndex": 1, - "visibility": 24487, - "windDirection": 50, - "windGust": 15.53, - "windSpeed": 9.15 - }, - { - "forecastStart": "2026-01-20T19:00:00Z", - "cloudCover": 0.12, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.71, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.78, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.79, - "temperatureApparent": 12.7, - "temperatureDewPoint": 6.7, - "uvIndex": 2, - "visibility": 26742, - "windDirection": 47, - "windGust": 16.28, - "windSpeed": 9.03 - }, - { - "forecastStart": "2026-01-20T20:00:00Z", - "cloudCover": 0.06, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.65, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.15, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.68, - "temperatureApparent": 14.93, - "temperatureDewPoint": 7.22, - "uvIndex": 3, - "visibility": 28998, - "windDirection": 41, - "windGust": 17.42, - "windSpeed": 8.85 - }, - { - "forecastStart": "2026-01-20T21:00:00Z", - "cloudCover": 0.02, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.6, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.54, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 15.23, - "temperatureApparent": 16.75, - "temperatureDewPoint": 7.51, - "uvIndex": 3, - "visibility": 30680, - "windDirection": 35, - "windGust": 18.28, - "windSpeed": 8.56 - }, - { - "forecastStart": "2026-01-20T22:00:00Z", - "cloudCover": 0.02, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.56, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.15, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 16.31, - "temperatureApparent": 18.02, - "temperatureDewPoint": 7.51, - "uvIndex": 2, - "visibility": 31487, - "windDirection": 27, - "windGust": 18.66, - "windSpeed": 7.94 - }, - { - "forecastStart": "2026-01-20T23:00:00Z", - "cloudCover": 0.04, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.52, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.86, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 17.06, - "temperatureApparent": 18.71, - "temperatureDewPoint": 7.13, - "uvIndex": 1, - "visibility": 31721, - "windDirection": 20, - "windGust": 18.87, - "windSpeed": 7.46 - }, - { - "forecastStart": "2026-01-21T00:00:00Z", - "cloudCover": 0.06, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.51, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.71, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 17.21, - "temperatureApparent": 18.42, - "temperatureDewPoint": 6.98, - "uvIndex": 0, - "visibility": 31712, - "windDirection": 14, - "windGust": 18.44, - "windSpeed": 6.98 - }, - { - "forecastStart": "2026-01-21T01:00:00Z", - "cloudCover": 0.08, - "conditionCode": "Clear", - "daylight": true, - "humidity": 0.52, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.76, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 16.38, - "temperatureApparent": 15.33, - "temperatureDewPoint": 6.5, - "uvIndex": 0, - "visibility": 31503, - "windDirection": 11, - "windGust": 17.25, - "windSpeed": 6.99 - }, - { - "forecastStart": "2026-01-21T02:00:00Z", - "cloudCover": 0.1, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.55, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.04, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 15.05, - "temperatureApparent": 13.35, - "temperatureDewPoint": 6.08, - "uvIndex": 0, - "visibility": 31051, - "windDirection": 14, - "windGust": 15.12, - "windSpeed": 6.9 - }, - { - "forecastStart": "2026-01-21T03:00:00Z", - "cloudCover": 0.12, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.58, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.31, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.82, - "temperatureApparent": 12.11, - "temperatureDewPoint": 5.7, - "uvIndex": 0, - "visibility": 30557, - "windDirection": 17, - "windGust": 13.61, - "windSpeed": 6.78 - }, - { - "forecastStart": "2026-01-21T04:00:00Z", - "cloudCover": 0.12, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.61, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.52, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.85, - "temperatureApparent": 11.23, - "temperatureDewPoint": 5.51, - "uvIndex": 0, - "visibility": 30195, - "windDirection": 21, - "windGust": 12.2, - "windSpeed": 6.38 - }, - { - "forecastStart": "2026-01-21T05:00:00Z", - "cloudCover": 0.11, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.65, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.69, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.95, - "temperatureApparent": 10.43, - "temperatureDewPoint": 5.57, - "uvIndex": 0, - "visibility": 29791, - "windDirection": 29, - "windGust": 10.98, - "windSpeed": 5.99 - }, - { - "forecastStart": "2026-01-21T06:00:00Z", - "cloudCover": 0.1, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.69, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.81, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.14, - "temperatureApparent": 9.68, - "temperatureDewPoint": 5.66, - "uvIndex": 0, - "visibility": 29023, - "windDirection": 33, - "windGust": 10.43, - "windSpeed": 5.95 - }, - { - "forecastStart": "2026-01-21T07:00:00Z", - "cloudCover": 0.09, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.72, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.9, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.11, - "temperatureApparent": 8.74, - "temperatureDewPoint": 5.29, - "uvIndex": 0, - "visibility": 27595, - "windDirection": 39, - "windGust": 10.03, - "windSpeed": 5.79 - }, - { - "forecastStart": "2026-01-21T08:00:00Z", - "cloudCover": 0.07, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.74, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.95, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.46, - "temperatureApparent": 8.11, - "temperatureDewPoint": 5.06, - "uvIndex": 0, - "visibility": 25805, - "windDirection": 42, - "windGust": 9.88, - "windSpeed": 5.77 - }, - { - "forecastStart": "2026-01-21T09:00:00Z", - "cloudCover": 0.06, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.76, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.91, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.87, - "temperatureApparent": 7.46, - "temperatureDewPoint": 4.87, - "uvIndex": 0, - "visibility": 24225, - "windDirection": 42, - "windGust": 10.22, - "windSpeed": 6 - }, - { - "forecastStart": "2026-01-21T10:00:00Z", - "cloudCover": 0.07, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.79, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.89, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.29, - "temperatureApparent": 6.87, - "temperatureDewPoint": 4.86, - "uvIndex": 0, - "visibility": 23260, - "windDirection": 42, - "windGust": 10.7, - "windSpeed": 6.13 - }, - { - "forecastStart": "2026-01-21T11:00:00Z", - "cloudCover": 0.08, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.82, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.81, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 7.77, - "temperatureApparent": 6.32, - "temperatureDewPoint": 4.89, - "uvIndex": 0, - "visibility": 22502, - "windDirection": 41, - "windGust": 11.53, - "windSpeed": 6.35 - }, - { - "forecastStart": "2026-01-21T12:00:00Z", - "cloudCover": 0.1, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.79, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 7.37, - "temperatureApparent": 5.86, - "temperatureDewPoint": 4.84, - "uvIndex": 0, - "visibility": 21302, - "windDirection": 41, - "windGust": 12.22, - "windSpeed": 6.63 - }, - { - "forecastStart": "2026-01-21T13:00:00Z", - "cloudCover": 0.16, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.9, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 7.06, - "temperatureApparent": 5.63, - "temperatureDewPoint": 4.88, - "uvIndex": 0, - "visibility": 18790, - "windDirection": 41, - "windGust": 12.1, - "windSpeed": 6.68 - }, - { - "forecastStart": "2026-01-21T14:00:00Z", - "cloudCover": 0.25, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.88, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.11, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 6.87, - "temperatureApparent": 5.49, - "temperatureDewPoint": 5.02, - "uvIndex": 0, - "visibility": 15835, - "windDirection": 41, - "windGust": 11.92, - "windSpeed": 6.88 - }, - { - "forecastStart": "2026-01-21T15:00:00Z", - "cloudCover": 0.28, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.88, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.35, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 6.96, - "temperatureApparent": 5.55, - "temperatureDewPoint": 5.11, - "uvIndex": 0, - "visibility": 14394, - "windDirection": 42, - "windGust": 12.16, - "windSpeed": 7.08 - }, - { - "forecastStart": "2026-01-21T16:00:00Z", - "cloudCover": 0.26, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.69, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 7.37, - "temperatureApparent": 7.36, - "temperatureDewPoint": 5.18, - "uvIndex": 0, - "visibility": 15702, - "windDirection": 42, - "windGust": 12.72, - "windSpeed": 7.03 - }, - { - "forecastStart": "2026-01-21T17:00:00Z", - "cloudCover": 0.27, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.83, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.04, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.05, - "temperatureApparent": 9.18, - "temperatureDewPoint": 5.34, - "uvIndex": 1, - "visibility": 18530, - "windDirection": 42, - "windGust": 13.77, - "windSpeed": 7.07 - }, - { - "forecastStart": "2026-01-21T18:00:00Z", - "cloudCover": 0.31, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.79, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.18, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.06, - "temperatureApparent": 10.2, - "temperatureDewPoint": 5.61, - "uvIndex": 2, - "visibility": 21149, - "windDirection": 41, - "windGust": 14.67, - "windSpeed": 7.11 - }, - { - "forecastStart": "2026-01-21T19:00:00Z", - "cloudCover": 0.28, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.74, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.89, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.94, - "temperatureApparent": 12.09, - "temperatureDewPoint": 6.49, - "uvIndex": 2, - "visibility": 22907, - "windDirection": 36, - "windGust": 15.53, - "windSpeed": 7.08 - }, - { - "forecastStart": "2026-01-21T20:00:00Z", - "cloudCover": 0.23, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.68, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.36, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.7, - "temperatureApparent": 13.95, - "temperatureDewPoint": 6.94, - "uvIndex": 3, - "visibility": 24459, - "windDirection": 30, - "windGust": 16.34, - "windSpeed": 6.99 - }, - { - "forecastStart": "2026-01-21T21:00:00Z", - "cloudCover": 0.2, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.64, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.86, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 14.15, - "temperatureApparent": 15.56, - "temperatureDewPoint": 7.44, - "uvIndex": 3, - "visibility": 26033, - "windDirection": 23, - "windGust": 16.74, - "windSpeed": 6.85 - }, - { - "forecastStart": "2026-01-21T22:00:00Z", - "cloudCover": 0.21, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.6, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.43, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 15.23, - "temperatureApparent": 16.67, - "temperatureDewPoint": 7.51, - "uvIndex": 2, - "visibility": 27965, - "windDirection": 14, - "windGust": 16.53, - "windSpeed": 6.64 - }, - { - "forecastStart": "2026-01-21T23:00:00Z", - "cloudCover": 0.22, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.58, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.04, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 16.01, - "temperatureApparent": 17.41, - "temperatureDewPoint": 7.75, - "uvIndex": 1, - "visibility": 29914, - "windDirection": 3, - "windGust": 15.91, - "windSpeed": 6.38 - }, - { - "forecastStart": "2026-01-22T00:00:00Z", - "cloudCover": 0.25, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.57, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.83, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 16.21, - "temperatureApparent": 17.25, - "temperatureDewPoint": 7.68, - "uvIndex": 0, - "visibility": 31104, - "windDirection": 354, - "windGust": 15.03, - "windSpeed": 6.06 - }, - { - "forecastStart": "2026-01-22T01:00:00Z", - "cloudCover": 0.3, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.59, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.91, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 15.44, - "temperatureApparent": 14.91, - "temperatureDewPoint": 7.46, - "uvIndex": 0, - "visibility": 31045, - "windDirection": 348, - "windGust": 13.77, - "windSpeed": 5.71 - }, - { - "forecastStart": "2026-01-22T02:00:00Z", - "cloudCover": 0.35, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.63, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.18, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 14.07, - "temperatureApparent": 13.18, - "temperatureDewPoint": 7.13, - "uvIndex": 0, - "visibility": 30229, - "windDirection": 342, - "windGust": 12.24, - "windSpeed": 5.3 - }, - { - "forecastStart": "2026-01-22T03:00:00Z", - "cloudCover": 0.38, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.67, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.42, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.83, - "temperatureApparent": 12.09, - "temperatureDewPoint": 6.85, - "uvIndex": 0, - "visibility": 29353, - "windDirection": 339, - "windGust": 11.04, - "windSpeed": 4.8 - }, - { - "forecastStart": "2026-01-22T04:00:00Z", - "cloudCover": 0.38, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.7, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.59, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.95, - "temperatureApparent": 11.43, - "temperatureDewPoint": 6.65, - "uvIndex": 0, - "visibility": 28661, - "windDirection": 347, - "windGust": 10.44, - "windSpeed": 4.02 - }, - { - "forecastStart": "2026-01-22T05:00:00Z", - "cloudCover": 0.36, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.73, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.75, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.19, - "temperatureApparent": 10.96, - "temperatureDewPoint": 6.53, - "uvIndex": 0, - "visibility": 27909, - "windDirection": 11, - "windGust": 10.16, - "windSpeed": 3.15 - }, - { - "forecastStart": "2026-01-22T06:00:00Z", - "cloudCover": 0.34, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.76, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.83, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.27, - "temperatureApparent": 10.2, - "temperatureDewPoint": 6.22, - "uvIndex": 0, - "visibility": 27054, - "windDirection": 39, - "windGust": 9.96, - "windSpeed": 2.73 - }, - { - "forecastStart": "2026-01-22T07:00:00Z", - "cloudCover": 0.39, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.8, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.82, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.68, - "temperatureApparent": 9.64, - "temperatureDewPoint": 6.4, - "uvIndex": 0, - "visibility": 26223, - "windDirection": 50, - "windGust": 9.8, - "windSpeed": 3.15 - }, - { - "forecastStart": "2026-01-22T08:00:00Z", - "cloudCover": 0.46, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.83, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.73, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.19, - "temperatureApparent": 9.05, - "temperatureDewPoint": 6.45, - "uvIndex": 0, - "visibility": 25289, - "windDirection": 50, - "windGust": 9.71, - "windSpeed": 4.02 - }, - { - "forecastStart": "2026-01-22T09:00:00Z", - "cloudCover": 0.5, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.85, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.59, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.06, - "temperatureApparent": 8.8, - "temperatureDewPoint": 6.67, - "uvIndex": 0, - "visibility": 23825, - "windDirection": 51, - "windGust": 9.67, - "windSpeed": 4.68 - }, - { - "forecastStart": "2026-01-22T10:00:00Z", - "cloudCover": 0.51, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.87, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.36, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.69, - "temperatureApparent": 8.4, - "temperatureDewPoint": 6.65, - "uvIndex": 0, - "visibility": 21214, - "windDirection": 53, - "windGust": 9.63, - "windSpeed": 4.89 - }, - { - "forecastStart": "2026-01-22T11:00:00Z", - "cloudCover": 0.52, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.89, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.08, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.41, - "temperatureApparent": 8.15, - "temperatureDewPoint": 6.7, - "uvIndex": 0, - "visibility": 18067, - "windDirection": 54, - "windGust": 9.62, - "windSpeed": 4.9 - }, - { - "forecastStart": "2026-01-22T12:00:00Z", - "cloudCover": 0.52, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.89, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.93, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.25, - "temperatureApparent": 8.01, - "temperatureDewPoint": 6.54, - "uvIndex": 0, - "visibility": 15812, - "windDirection": 57, - "windGust": 9.72, - "windSpeed": 4.87 - }, - { - "forecastStart": "2026-01-22T13:00:00Z", - "cloudCover": 0.52, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.89, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.97, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.15, - "temperatureApparent": 7.93, - "temperatureDewPoint": 6.45, - "uvIndex": 0, - "visibility": 14785, - "windDirection": 65, - "windGust": 9.87, - "windSpeed": 4.83 - }, - { - "forecastStart": "2026-01-22T14:00:00Z", - "cloudCover": 0.52, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.88, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.14, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.11, - "temperatureApparent": 7.92, - "temperatureDewPoint": 6.24, - "uvIndex": 0, - "visibility": 14306, - "windDirection": 72, - "windGust": 10.02, - "windSpeed": 4.72 - }, - { - "forecastStart": "2026-01-22T15:00:00Z", - "cloudCover": 0.53, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.87, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.38, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.26, - "temperatureApparent": 8.13, - "temperatureDewPoint": 6.22, - "uvIndex": 0, - "visibility": 14279, - "windDirection": 75, - "windGust": 10.3, - "windSpeed": 4.54 - }, - { - "forecastStart": "2026-01-22T16:00:00Z", - "cloudCover": 0.55, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.71, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.6, - "temperatureApparent": 9.36, - "temperatureDewPoint": 6.39, - "uvIndex": 0, - "visibility": 14610, - "windDirection": 71, - "windGust": 10.77, - "windSpeed": 4.13 - }, - { - "forecastStart": "2026-01-22T17:00:00Z", - "cloudCover": 0.58, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.83, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.02, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.09, - "temperatureApparent": 10.43, - "temperatureDewPoint": 6.35, - "uvIndex": 1, - "visibility": 15201, - "windDirection": 62, - "windGust": 11.39, - "windSpeed": 3.65 - }, - { - "forecastStart": "2026-01-22T18:00:00Z", - "cloudCover": 0.6, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.81, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.09, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.65, - "temperatureApparent": 10.96, - "temperatureDewPoint": 6.55, - "uvIndex": 1, - "visibility": 15950, - "windDirection": 51, - "windGust": 12.09, - "windSpeed": 3.57 - }, - { - "forecastStart": "2026-01-22T19:00:00Z", - "cloudCover": 0.62, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.78, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.79, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.39, - "temperatureApparent": 11.33, - "temperatureDewPoint": 6.72, - "uvIndex": 2, - "visibility": 17166, - "windDirection": 35, - "windGust": 12.96, - "windSpeed": 4.21 - }, - { - "forecastStart": "2026-01-22T20:00:00Z", - "cloudCover": 0.63, - "conditionCode": "MostlyCloudy", - "daylight": true, - "humidity": 0.76, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.24, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.32, - "temperatureApparent": 11.77, - "temperatureDewPoint": 7.24, - "uvIndex": 3, - "visibility": 18988, - "windDirection": 6, - "windGust": 14.12, - "windSpeed": 5.28 - }, - { - "forecastStart": "2026-01-22T21:00:00Z", - "cloudCover": 0.64, - "conditionCode": "MostlyCloudy", - "daylight": true, - "humidity": 0.74, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.68, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.84, - "temperatureApparent": 11.84, - "temperatureDewPoint": 7.35, - "uvIndex": 2, - "visibility": 21062, - "windDirection": 338, - "windGust": 15.52, - "windSpeed": 6.32 - }, - { - "forecastStart": "2026-01-22T22:00:00Z", - "cloudCover": 0.63, - "conditionCode": "MostlyCloudy", - "daylight": true, - "humidity": 0.72, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.19, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.82, - "temperatureApparent": 12.58, - "temperatureDewPoint": 7.9, - "uvIndex": 2, - "visibility": 23035, - "windDirection": 318, - "windGust": 17.06, - "windSpeed": 7.24 - }, - { - "forecastStart": "2026-01-22T23:00:00Z", - "cloudCover": 0.62, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.71, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1016.76, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.26, - "temperatureApparent": 12.77, - "temperatureDewPoint": 8.11, - "uvIndex": 1, - "visibility": 24557, - "windDirection": 303, - "windGust": 18.41, - "windSpeed": 8.1 - }, - { - "forecastStart": "2026-01-23T00:00:00Z", - "cloudCover": 0.63, - "conditionCode": "MostlyCloudy", - "daylight": true, - "humidity": 0.71, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1016.47, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.39, - "temperatureApparent": 12.62, - "temperatureDewPoint": 8.24, - "uvIndex": 0, - "visibility": 25276, - "windDirection": 296, - "windGust": 19.16, - "windSpeed": 8.56 - }, - { - "forecastStart": "2026-01-23T01:00:00Z", - "cloudCover": 0.65, - "conditionCode": "MostlyCloudy", - "daylight": true, - "humidity": 0.72, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1016.38, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.02, - "temperatureApparent": 11.78, - "temperatureDewPoint": 8.09, - "uvIndex": 0, - "visibility": 25093, - "windDirection": 293, - "windGust": 19.16, - "windSpeed": 8.38 - }, - { - "forecastStart": "2026-01-23T02:00:00Z", - "cloudCover": 0.68, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.75, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1016.4, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.36, - "temperatureApparent": 11.14, - "temperatureDewPoint": 8.05, - "uvIndex": 0, - "visibility": 24270, - "windDirection": 293, - "windGust": 18.59, - "windSpeed": 7.79 - }, - { - "forecastStart": "2026-01-23T03:00:00Z", - "cloudCover": 0.7, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.77, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1016.45, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.65, - "temperatureApparent": 10.67, - "temperatureDewPoint": 7.75, - "uvIndex": 0, - "visibility": 22996, - "windDirection": 291, - "windGust": 17.51, - "windSpeed": 7.17 - }, - { - "forecastStart": "2026-01-23T04:00:00Z", - "cloudCover": 0.72, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.79, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1016.47, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.03, - "temperatureApparent": 10.3, - "temperatureDewPoint": 7.53, - "uvIndex": 0, - "visibility": 21461, - "windDirection": 287, - "windGust": 16, - "windSpeed": 6.62 - }, - { - "forecastStart": "2026-01-23T05:00:00Z", - "cloudCover": 0.72, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.81, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1016.45, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.47, - "temperatureApparent": 9.94, - "temperatureDewPoint": 7.35, - "uvIndex": 0, - "visibility": 19858, - "windDirection": 282, - "windGust": 14.37, - "windSpeed": 6.09 - }, - { - "forecastStart": "2026-01-23T06:00:00Z", - "cloudCover": 0.71, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.82, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1016.37, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.4, - "temperatureApparent": 9.98, - "temperatureDewPoint": 7.46, - "uvIndex": 0, - "visibility": 18376, - "windDirection": 278, - "windGust": 13.1, - "windSpeed": 5.8 - }, - { - "forecastStart": "2026-01-23T07:00:00Z", - "cloudCover": 0.69, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.83, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1016.21, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.81, - "temperatureApparent": 9.35, - "temperatureDewPoint": 7.06, - "uvIndex": 0, - "visibility": 16860, - "windDirection": 278, - "windGust": 12.27, - "windSpeed": 5.89 - }, - { - "forecastStart": "2026-01-23T08:00:00Z", - "cloudCover": 0.66, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1016, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.55, - "temperatureApparent": 8.95, - "temperatureDewPoint": 6.98, - "uvIndex": 0, - "visibility": 15128, - "windDirection": 281, - "windGust": 11.62, - "windSpeed": 6.2 - }, - { - "forecastStart": "2026-01-23T09:00:00Z", - "cloudCover": 0.66, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.85, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1015.78, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.31, - "temperatureApparent": 8.63, - "temperatureDewPoint": 6.92, - "uvIndex": 0, - "visibility": 13333, - "windDirection": 288, - "windGust": 11.11, - "windSpeed": 6.48 - }, - { - "forecastStart": "2026-01-23T10:00:00Z", - "cloudCover": 0.68, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1015.56, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.04, - "temperatureApparent": 8.33, - "temperatureDewPoint": 6.82, - "uvIndex": 0, - "visibility": 11627, - "windDirection": 302, - "windGust": 10.69, - "windSpeed": 6.66 - }, - { - "forecastStart": "2026-01-23T11:00:00Z", - "cloudCover": 0.73, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.87, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1015.37, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.74, - "temperatureApparent": 8.06, - "temperatureDewPoint": 6.7, - "uvIndex": 0, - "visibility": 10162, - "windDirection": 318, - "windGust": 10.35, - "windSpeed": 6.77 - }, - { - "forecastStart": "2026-01-23T12:00:00Z", - "cloudCover": 0.77, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.88, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1015.24, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.49, - "temperatureApparent": 7.91, - "temperatureDewPoint": 6.62, - "uvIndex": 0, - "visibility": 9086, - "windDirection": 330, - "windGust": 10.01, - "windSpeed": 6.68 - }, - { - "forecastStart": "2026-01-23T13:00:00Z", - "cloudCover": 0.7, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.88, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1015.25, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.78, - "temperatureApparent": 8.26, - "temperatureDewPoint": 6.9, - "uvIndex": 0, - "visibility": 10809, - "windDirection": 342, - "windGust": 7.91, - "windSpeed": 6.27 - }, - { - "forecastStart": "2026-01-23T14:00:00Z", - "cloudCover": 0.72, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.88, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1015.44, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.67, - "temperatureApparent": 8.41, - "temperatureDewPoint": 6.79, - "uvIndex": 0, - "visibility": 10815, - "windDirection": 356, - "windGust": 8.44, - "windSpeed": 5.65 - }, - { - "forecastStart": "2026-01-23T15:00:00Z", - "cloudCover": 0.72, - "conditionCode": "MostlyCloudy", - "daylight": false, - "humidity": 0.88, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1015.67, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.74, - "temperatureApparent": 8.69, - "temperatureDewPoint": 6.86, - "uvIndex": 0, - "visibility": 10822, - "windDirection": 11, - "windGust": 8.81, - "windSpeed": 5.06 - }, - { - "forecastStart": "2026-01-23T16:00:00Z", - "cloudCover": 0.7, - "conditionCode": "MostlyCloudy", - "daylight": true, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1015.99, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.06, - "temperatureApparent": 9.49, - "temperatureDewPoint": 6.84, - "uvIndex": 0, - "visibility": 10829, - "windDirection": 27, - "windGust": 8.93, - "windSpeed": 4.56 - }, - { - "forecastStart": "2026-01-23T17:00:00Z", - "cloudCover": 0.66, - "conditionCode": "MostlyCloudy", - "daylight": true, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1016.32, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.34, - "temperatureApparent": 10.23, - "temperatureDewPoint": 6.77, - "uvIndex": 1, - "visibility": 11555, - "windDirection": 41, - "windGust": 8.95, - "windSpeed": 4.15 - }, - { - "forecastStart": "2026-01-23T18:00:00Z", - "cloudCover": 0.61, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.82, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1016.42, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.95, - "temperatureApparent": 11.09, - "temperatureDewPoint": 7.02, - "uvIndex": 1, - "visibility": 12422, - "windDirection": 44, - "windGust": 9.04, - "windSpeed": 3.95 - }, - { - "forecastStart": "2026-01-23T19:00:00Z", - "cloudCover": 0.56, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.79, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1016.15, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.71, - "temperatureApparent": 11.94, - "temperatureDewPoint": 7.22, - "uvIndex": 2, - "visibility": 13549, - "windDirection": 30, - "windGust": 9.24, - "windSpeed": 3.97 - }, - { - "forecastStart": "2026-01-23T20:00:00Z", - "cloudCover": 0.49, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.76, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1015.66, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.59, - "temperatureApparent": 12.88, - "temperatureDewPoint": 7.5, - "uvIndex": 3, - "visibility": 15058, - "windDirection": 3, - "windGust": 9.57, - "windSpeed": 4.22 - }, - { - "forecastStart": "2026-01-23T21:00:00Z", - "cloudCover": 0.42, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.74, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1015.16, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12, - "temperatureApparent": 13.32, - "temperatureDewPoint": 7.51, - "uvIndex": 3, - "visibility": 16789, - "windDirection": 332, - "windGust": 10.16, - "windSpeed": 4.76 - }, - { - "forecastStart": "2026-01-23T22:00:00Z", - "cloudCover": 0.38, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.72, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1014.74, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.52, - "temperatureApparent": 13.68, - "temperatureDewPoint": 7.61, - "uvIndex": 2, - "visibility": 18577, - "windDirection": 294, - "windGust": 10.99, - "windSpeed": 5.73 - }, - { - "forecastStart": "2026-01-23T23:00:00Z", - "cloudCover": 0.36, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.72, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1014.37, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.9, - "temperatureApparent": 13.72, - "temperatureDewPoint": 7.97, - "uvIndex": 1, - "visibility": 20262, - "windDirection": 270, - "windGust": 11.84, - "windSpeed": 6.91 - }, - { - "forecastStart": "2026-01-24T00:00:00Z", - "cloudCover": 0.32, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.71, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1014.12, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13, - "temperatureApparent": 13.37, - "temperatureDewPoint": 7.86, - "uvIndex": 0, - "visibility": 21684, - "windDirection": 263, - "windGust": 12.56, - "windSpeed": 7.83 - }, - { - "forecastStart": "2026-01-24T01:00:00Z", - "cloudCover": 0.27, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.76, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1013.45, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.71, - "temperatureApparent": 11.24, - "temperatureDewPoint": 8.59, - "uvIndex": 0, - "visibility": 23024, - "windDirection": 258, - "windGust": 13.2, - "windSpeed": 9.03 - }, - { - "forecastStart": "2026-01-24T02:00:00Z", - "cloudCover": 0.11, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.78, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1013.63, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.16, - "temperatureApparent": 9.78, - "temperatureDewPoint": 8.44, - "uvIndex": 0, - "visibility": 24450, - "windDirection": 261, - "windGust": 13.73, - "windSpeed": 9.18 - }, - { - "forecastStart": "2026-01-24T03:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.8, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1013.8, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.59, - "temperatureApparent": 9.03, - "temperatureDewPoint": 8.26, - "uvIndex": 0, - "visibility": 25772, - "windDirection": 264, - "windGust": 13.85, - "windSpeed": 9.31 - }, - { - "forecastStart": "2026-01-24T04:00:00Z", - "cloudCover": 0, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.82, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1013.91, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.12, - "temperatureApparent": 8.49, - "temperatureDewPoint": 8.16, - "uvIndex": 0, - "visibility": 26805, - "windDirection": 264, - "windGust": 13.44, - "windSpeed": 9.51 - }, - { - "forecastStart": "2026-01-24T05:00:00Z", - "cloudCover": 0.02, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1013.99, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.71, - "temperatureApparent": 8.02, - "temperatureDewPoint": 8.12, - "uvIndex": 0, - "visibility": 27362, - "windDirection": 263, - "windGust": 12.79, - "windSpeed": 9.74 - }, - { - "forecastStart": "2026-01-24T06:00:00Z", - "cloudCover": 0.08, - "conditionCode": "Clear", - "daylight": false, - "humidity": 0.85, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1014.04, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.39, - "temperatureApparent": 7.68, - "temperatureDewPoint": 7.98, - "uvIndex": 0, - "visibility": 27258, - "windDirection": 263, - "windGust": 12.25, - "windSpeed": 10 - }, - { - "forecastStart": "2026-01-24T07:00:00Z", - "cloudCover": 0.2, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1014.07, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.13, - "temperatureApparent": 7.46, - "temperatureDewPoint": 7.89, - "uvIndex": 0, - "visibility": 26118, - "windDirection": 264, - "windGust": 11.76, - "windSpeed": 10.32 - }, - { - "forecastStart": "2026-01-24T08:00:00Z", - "cloudCover": 0.34, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.87, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1014.08, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.91, - "temperatureApparent": 7.3, - "temperatureDewPoint": 7.85, - "uvIndex": 0, - "visibility": 24022, - "windDirection": 266, - "windGust": 11.23, - "windSpeed": 10.62 - }, - { - "forecastStart": "2026-01-24T09:00:00Z", - "cloudCover": 0.44, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.87, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1014.09, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.72, - "temperatureApparent": 7.18, - "temperatureDewPoint": 7.66, - "uvIndex": 0, - "visibility": 21462, - "windDirection": 267, - "windGust": 10.98, - "windSpeed": 10.77 - }, - { - "forecastStart": "2026-01-24T10:00:00Z", - "cloudCover": 0.41, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1014.06, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.62, - "temperatureApparent": 7.03, - "temperatureDewPoint": 7.39, - "uvIndex": 0, - "visibility": 18928, - "windDirection": 267, - "windGust": 11.25, - "windSpeed": 10.75 - }, - { - "forecastStart": "2026-01-24T11:00:00Z", - "cloudCover": 0.32, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.85, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1014.06, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.45, - "temperatureApparent": 6.78, - "temperatureDewPoint": 7.05, - "uvIndex": 0, - "visibility": 16908, - "windDirection": 266, - "windGust": 11.89, - "windSpeed": 10.6 - }, - { - "forecastStart": "2026-01-24T12:00:00Z", - "cloudCover": 0.25, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1014.2, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.31, - "temperatureApparent": 6.67, - "temperatureDewPoint": 6.74, - "uvIndex": 0, - "visibility": 15886, - "windDirection": 264, - "windGust": 12.6, - "windSpeed": 10.24 - }, - { - "forecastStart": "2026-01-24T13:00:00Z", - "cloudCover": 0.28, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1014.55, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.95, - "temperatureApparent": 6.69, - "temperatureDewPoint": 6.39, - "uvIndex": 0, - "visibility": 15944, - "windDirection": 261, - "windGust": 13.24, - "windSpeed": 9.29 - }, - { - "forecastStart": "2026-01-24T14:00:00Z", - "cloudCover": 0.31, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1015.05, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.53, - "temperatureApparent": 6.75, - "temperatureDewPoint": 5.98, - "uvIndex": 0, - "visibility": 16708, - "windDirection": 255, - "windGust": 13.99, - "windSpeed": 8.12 - }, - { - "forecastStart": "2026-01-24T15:00:00Z", - "cloudCover": 0.34, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1015.65, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.31, - "temperatureApparent": 6.69, - "temperatureDewPoint": 5.76, - "uvIndex": 0, - "visibility": 17971, - "windDirection": 243, - "windGust": 14.96, - "windSpeed": 7.8 - }, - { - "forecastStart": "2026-01-24T16:00:00Z", - "cloudCover": 0.39, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.82, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1016.41, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.64, - "temperatureApparent": 7.67, - "temperatureDewPoint": 5.74, - "uvIndex": 0, - "visibility": 19529, - "windDirection": 264, - "windGust": 16.23, - "windSpeed": 9.16 - }, - { - "forecastStart": "2026-01-24T17:00:00Z", - "cloudCover": 0.44, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.81, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.22, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.13, - "temperatureApparent": 7.96, - "temperatureDewPoint": 6.04, - "uvIndex": 1, - "visibility": 21178, - "windDirection": 27, - "windGust": 17.54, - "windSpeed": 11.37 - }, - { - "forecastStart": "2026-01-24T18:00:00Z", - "cloudCover": 0.46, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.79, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.76, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.67, - "temperatureApparent": 7.92, - "temperatureDewPoint": 6.2, - "uvIndex": 2, - "visibility": 22718, - "windDirection": 26, - "windGust": 18.53, - "windSpeed": 13.01 - }, - { - "forecastStart": "2026-01-24T19:00:00Z", - "cloudCover": 0.43, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.76, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.82, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.29, - "temperatureApparent": 8.47, - "temperatureDewPoint": 6.24, - "uvIndex": 2, - "visibility": 24368, - "windDirection": 18, - "windGust": 19.1, - "windSpeed": 13.53 - }, - { - "forecastStart": "2026-01-24T20:00:00Z", - "cloudCover": 0.37, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.74, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.61, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.11, - "temperatureApparent": 9.49, - "temperatureDewPoint": 6.65, - "uvIndex": 3, - "visibility": 26330, - "windDirection": 351, - "windGust": 19.55, - "windSpeed": 13.52 - }, - { - "forecastStart": "2026-01-24T21:00:00Z", - "cloudCover": 0.32, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.71, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.45, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.69, - "temperatureApparent": 10.3, - "temperatureDewPoint": 6.61, - "uvIndex": 3, - "visibility": 28380, - "windDirection": 314, - "windGust": 20.08, - "windSpeed": 13.35 - }, - { - "forecastStart": "2026-01-24T22:00:00Z", - "cloudCover": 0.29, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.7, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.47, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.12, - "temperatureApparent": 10.94, - "temperatureDewPoint": 6.81, - "uvIndex": 2, - "visibility": 30296, - "windDirection": 299, - "windGust": 20.81, - "windSpeed": 13.08 - }, - { - "forecastStart": "2026-01-24T23:00:00Z", - "cloudCover": 0.27, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.7, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.6, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.42, - "temperatureApparent": 11.47, - "temperatureDewPoint": 7.1, - "uvIndex": 1, - "visibility": 31858, - "windDirection": 293, - "windGust": 21.4, - "windSpeed": 12.56 - }, - { - "forecastStart": "2026-01-25T00:00:00Z", - "cloudCover": 0.26, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.7, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1017.83, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.49, - "temperatureApparent": 11.55, - "temperatureDewPoint": 7.17, - "uvIndex": 0, - "visibility": 32848, - "windDirection": 290, - "windGust": 21.37, - "windSpeed": 11.74 - }, - { - "forecastStart": "2026-01-25T01:00:00Z", - "cloudCover": 0.26, - "conditionCode": "MostlyClear", - "daylight": true, - "humidity": 0.71, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.2, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.17, - "temperatureApparent": 10.15, - "temperatureDewPoint": 7.07, - "uvIndex": 0, - "visibility": 33155, - "windDirection": 284, - "windGust": 20.32, - "windSpeed": 10.4 - }, - { - "forecastStart": "2026-01-25T02:00:00Z", - "cloudCover": 0.26, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.74, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1018.67, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.59, - "temperatureApparent": 9.46, - "temperatureDewPoint": 7.11, - "uvIndex": 0, - "visibility": 32934, - "windDirection": 278, - "windGust": 18.49, - "windSpeed": 8.74 - }, - { - "forecastStart": "2026-01-25T03:00:00Z", - "cloudCover": 0.28, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.76, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.17, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.99, - "temperatureApparent": 9.39, - "temperatureDewPoint": 6.92, - "uvIndex": 0, - "visibility": 32373, - "windDirection": 273, - "windGust": 16.36, - "windSpeed": 7.37 - }, - { - "forecastStart": "2026-01-25T04:00:00Z", - "cloudCover": 0.28, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.79, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1019.69, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.47, - "temperatureApparent": 9.15, - "temperatureDewPoint": 6.98, - "uvIndex": 0, - "visibility": 31653, - "windDirection": 275, - "windGust": 14.27, - "windSpeed": 6.67 - }, - { - "forecastStart": "2026-01-25T05:00:00Z", - "cloudCover": 0.3, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.82, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.21, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.98, - "temperatureApparent": 8.8, - "temperatureDewPoint": 7.05, - "uvIndex": 0, - "visibility": 30958, - "windDirection": 279, - "windGust": 12.45, - "windSpeed": 6.44 - }, - { - "forecastStart": "2026-01-25T06:00:00Z", - "cloudCover": 0.31, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.65, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.58, - "temperatureApparent": 8.47, - "temperatureDewPoint": 7.01, - "uvIndex": 0, - "visibility": 30466, - "windDirection": 281, - "windGust": 11.29, - "windSpeed": 6.37 - }, - { - "forecastStart": "2026-01-25T07:00:00Z", - "cloudCover": 0.34, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1020.96, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.25, - "temperatureApparent": 8.21, - "temperatureDewPoint": 7.03, - "uvIndex": 0, - "visibility": 30192, - "windDirection": 248, - "windGust": 10.89, - "windSpeed": 6.33 - }, - { - "forecastStart": "2026-01-25T08:00:00Z", - "cloudCover": 0.36, - "conditionCode": "MostlyClear", - "daylight": false, - "humidity": 0.88, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1021.2, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.93, - "temperatureApparent": 7.91, - "temperatureDewPoint": 7.05, - "uvIndex": 0, - "visibility": 29994, - "windDirection": 192, - "windGust": 10.95, - "windSpeed": 6.39 - }, - { - "forecastStart": "2026-01-25T09:00:00Z", - "cloudCover": 0.4, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.88, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1021.41, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.71, - "temperatureApparent": 7.69, - "temperatureDewPoint": 6.83, - "uvIndex": 0, - "visibility": 29816, - "windDirection": 173, - "windGust": 11.23, - "windSpeed": 6.57 - }, - { - "forecastStart": "2026-01-25T10:00:00Z", - "cloudCover": 0.44, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.9, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1021.6, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.53, - "temperatureApparent": 7.45, - "temperatureDewPoint": 6.98, - "uvIndex": 0, - "visibility": 29606, - "windDirection": 159, - "windGust": 11.48, - "windSpeed": 6.9 - }, - { - "forecastStart": "2026-01-25T11:00:00Z", - "cloudCover": 0.48, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.9, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1021.79, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.4, - "temperatureApparent": 7.23, - "temperatureDewPoint": 6.85, - "uvIndex": 0, - "visibility": 29310, - "windDirection": 135, - "windGust": 11.71, - "windSpeed": 7.29 - }, - { - "forecastStart": "2026-01-25T12:00:00Z", - "cloudCover": 0.51, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.91, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.01, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.32, - "temperatureApparent": 7.06, - "temperatureDewPoint": 6.94, - "uvIndex": 0, - "visibility": 28876, - "windDirection": 108, - "windGust": 12.05, - "windSpeed": 7.63 - }, - { - "forecastStart": "2026-01-25T13:00:00Z", - "cloudCover": 0.53, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.91, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.25, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.36, - "temperatureApparent": 7.02, - "temperatureDewPoint": 6.98, - "uvIndex": 0, - "visibility": 28170, - "windDirection": 101, - "windGust": 12.83, - "windSpeed": 7.9 - }, - { - "forecastStart": "2026-01-25T14:00:00Z", - "cloudCover": 0.53, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.91, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.52, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.47, - "temperatureApparent": 7.03, - "temperatureDewPoint": 7.08, - "uvIndex": 0, - "visibility": 27211, - "windDirection": 101, - "windGust": 13.98, - "windSpeed": 8.18 - }, - { - "forecastStart": "2026-01-25T15:00:00Z", - "cloudCover": 0.53, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.9, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1022.85, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 8.74, - "temperatureApparent": 7.15, - "temperatureDewPoint": 7.19, - "uvIndex": 0, - "visibility": 26171, - "windDirection": 101, - "windGust": 15.04, - "windSpeed": 8.54 - }, - { - "forecastStart": "2026-01-25T16:00:00Z", - "cloudCover": 0.53, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.88, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1023.34, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.24, - "temperatureApparent": 8.25, - "temperatureDewPoint": 7.35, - "uvIndex": 0, - "visibility": 25222, - "windDirection": 98, - "windGust": 15.62, - "windSpeed": 9.01 - }, - { - "forecastStart": "2026-01-25T17:00:00Z", - "cloudCover": 0.53, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1023.87, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.95, - "temperatureApparent": 9.3, - "temperatureDewPoint": 7.72, - "uvIndex": 1, - "visibility": 24531, - "windDirection": 95, - "windGust": 15.8, - "windSpeed": 9.5 - }, - { - "forecastStart": "2026-01-25T18:00:00Z", - "cloudCover": 0.53, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.83, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1024.18, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.66, - "temperatureApparent": 9.94, - "temperatureDewPoint": 7.89, - "uvIndex": 1, - "visibility": 24266, - "windDirection": 90, - "windGust": 15.87, - "windSpeed": 9.89 - }, - { - "forecastStart": "2026-01-25T19:00:00Z", - "cloudCover": 0.54, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.8, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1024.12, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.5, - "temperatureApparent": 10.65, - "temperatureDewPoint": 8.17, - "uvIndex": 2, - "visibility": 24553, - "windDirection": 84, - "windGust": 15.97, - "windSpeed": 10.1 - }, - { - "forecastStart": "2026-01-25T20:00:00Z", - "cloudCover": 0.55, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.77, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1023.84, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.43, - "temperatureApparent": 11.52, - "temperatureDewPoint": 8.51, - "uvIndex": 3, - "visibility": 25278, - "windDirection": 72, - "windGust": 15.97, - "windSpeed": 10.2 - }, - { - "forecastStart": "2026-01-25T21:00:00Z", - "cloudCover": 0.56, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.74, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1023.59, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.16, - "temperatureApparent": 12.23, - "temperatureDewPoint": 8.63, - "uvIndex": 3, - "visibility": 26249, - "windDirection": 48, - "windGust": 15.73, - "windSpeed": 10.31 - }, - { - "forecastStart": "2026-01-25T22:00:00Z", - "cloudCover": 0.53, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.73, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1023.44, - "pressureTrend": "falling", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.61, - "temperatureApparent": 12.72, - "temperatureDewPoint": 8.86, - "uvIndex": 2, - "visibility": 27275, - "windDirection": 12, - "windGust": 15.49, - "windSpeed": 10.61 - }, - { - "forecastStart": "2026-01-25T23:00:00Z", - "cloudCover": 0.5, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.73, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1023.33, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.86, - "temperatureApparent": 12.94, - "temperatureDewPoint": 9.1, - "uvIndex": 1, - "visibility": 28169, - "windDirection": 350, - "windGust": 15.35, - "windSpeed": 11 - }, - { - "forecastStart": "2026-01-26T00:00:00Z", - "cloudCover": 0.47, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.73, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1023.3, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.87, - "temperatureApparent": 12.82, - "temperatureDewPoint": 9.11, - "uvIndex": 0, - "visibility": 28745, - "windDirection": 347, - "windGust": 14.99, - "windSpeed": 11.17 - }, - { - "forecastStart": "2026-01-26T01:00:00Z", - "cloudCover": 0.46, - "conditionCode": "PartlyCloudy", - "daylight": true, - "humidity": 0.74, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1023.38, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.56, - "temperatureApparent": 11.66, - "temperatureDewPoint": 9.01, - "uvIndex": 0, - "visibility": 28971, - "windDirection": 2, - "windGust": 14.01, - "windSpeed": 10.93 - }, - { - "forecastStart": "2026-01-26T02:00:00Z", - "cloudCover": 0.44, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.76, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1023.53, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 13.01, - "temperatureApparent": 10.72, - "temperatureDewPoint": 8.88, - "uvIndex": 0, - "visibility": 28991, - "windDirection": 23, - "windGust": 12.67, - "windSpeed": 10.43 - }, - { - "forecastStart": "2026-01-26T03:00:00Z", - "cloudCover": 0.44, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.78, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1023.7, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 12.43, - "temperatureApparent": 10.26, - "temperatureDewPoint": 8.7, - "uvIndex": 0, - "visibility": 28887, - "windDirection": 36, - "windGust": 11.61, - "windSpeed": 9.93 - }, - { - "forecastStart": "2026-01-26T04:00:00Z", - "cloudCover": 0.44, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.8, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1023.86, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.91, - "temperatureApparent": 9.86, - "temperatureDewPoint": 8.57, - "uvIndex": 0, - "visibility": 28739, - "windDirection": 45, - "windGust": 11.15, - "windSpeed": 9.48 - }, - { - "forecastStart": "2026-01-26T05:00:00Z", - "cloudCover": 0.45, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.82, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1024.01, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 11.38, - "temperatureApparent": 9.52, - "temperatureDewPoint": 8.42, - "uvIndex": 0, - "visibility": 28627, - "windDirection": 53, - "windGust": 10.95, - "windSpeed": 9 - }, - { - "forecastStart": "2026-01-26T06:00:00Z", - "cloudCover": 0.46, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.84, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1024.14, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.91, - "temperatureApparent": 9.23, - "temperatureDewPoint": 8.31, - "uvIndex": 0, - "visibility": 28630, - "windDirection": 59, - "windGust": 10.63, - "windSpeed": 8.56 - }, - { - "forecastStart": "2026-01-26T07:00:00Z", - "cloudCover": 0.46, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.86, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1024.25, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.48, - "temperatureApparent": 8.98, - "temperatureDewPoint": 8.24, - "uvIndex": 0, - "visibility": 28747, - "windDirection": 66, - "windGust": 9.99, - "windSpeed": 8.09 - }, - { - "forecastStart": "2026-01-26T08:00:00Z", - "cloudCover": 0.45, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.87, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1024.34, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 10.08, - "temperatureApparent": 8.73, - "temperatureDewPoint": 8.01, - "uvIndex": 0, - "visibility": 28916, - "windDirection": 72, - "windGust": 9.27, - "windSpeed": 7.66 - }, - { - "forecastStart": "2026-01-26T09:00:00Z", - "cloudCover": 0.45, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.88, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1024.38, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.78, - "temperatureApparent": 8.48, - "temperatureDewPoint": 7.89, - "uvIndex": 0, - "visibility": 29117, - "windDirection": 77, - "windGust": 8.83, - "windSpeed": 7.52 - }, - { - "forecastStart": "2026-01-26T10:00:00Z", - "cloudCover": 0.44, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.88, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1024.32, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.64, - "temperatureApparent": 8.22, - "temperatureDewPoint": 7.75, - "uvIndex": 0, - "visibility": 29334, - "windDirection": 75, - "windGust": 8.8, - "windSpeed": 7.84 - }, - { - "forecastStart": "2026-01-26T11:00:00Z", - "cloudCover": 0.44, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.89, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1024.22, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.6, - "temperatureApparent": 7.96, - "temperatureDewPoint": 7.88, - "uvIndex": 0, - "visibility": 29549, - "windDirection": 72, - "windGust": 9.01, - "windSpeed": 8.44 - }, - { - "forecastStart": "2026-01-26T12:00:00Z", - "cloudCover": 0.44, - "conditionCode": "PartlyCloudy", - "daylight": false, - "humidity": 0.89, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1024.16, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.57, - "temperatureApparent": 7.67, - "temperatureDewPoint": 7.85, - "uvIndex": 0, - "visibility": 29744, - "windDirection": 69, - "windGust": 9.35, - "windSpeed": 9.14 - }, - { - "forecastStart": "2026-01-26T13:00:00Z", - "cloudCover": 1, - "conditionCode": "Cloudy", - "daylight": false, - "humidity": 0.98, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1024.99, - "pressureTrend": "steady", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.09, - "temperatureApparent": 10.32, - "temperatureDewPoint": 8.79, - "uvIndex": 0, - "visibility": 24135, - "windDirection": 344, - "windGust": 3.34, - "windSpeed": 2.57 - }, - { - "forecastStart": "2026-01-26T14:00:00Z", - "cloudCover": 1, - "conditionCode": "Cloudy", - "daylight": false, - "humidity": 0.97, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1025.49, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.15, - "temperatureApparent": 10, - "temperatureDewPoint": 8.7, - "uvIndex": 0, - "visibility": 24135, - "windDirection": 329, - "windGust": 4.36, - "windSpeed": 3.8 - }, - { - "forecastStart": "2026-01-26T15:00:00Z", - "cloudCover": 1, - "conditionCode": "Cloudy", - "daylight": false, - "humidity": 0.94, - "precipitationAmount": 0, - "precipitationIntensity": 0, - "precipitationChance": 0, - "precipitationType": "clear", - "pressure": 1025.91, - "pressureTrend": "rising", - "snowfallIntensity": 0, - "snowfallAmount": 0, - "temperature": 9.38, - "temperatureApparent": 9.92, - "temperatureDewPoint": 8.46, - "uvIndex": 0, - "visibility": 24135, - "windDirection": 327, - "windGust": 4.98, - "windSpeed": 4.64 - } - ] - } - } -} diff --git a/packages/aelis-data-source-weatherkit/package.json b/packages/aelis-data-source-weatherkit/package.json deleted file mode 100644 index 6243be0..0000000 --- a/packages/aelis-data-source-weatherkit/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "@aelis/data-source-weatherkit", - "version": "0.0.0", - "type": "module", - "main": "src/index.ts", - "types": "src/index.ts", - "scripts": { - "test": "bun test ." - }, - "dependencies": { - "@aelis/core": "workspace:*", - "arktype": "^2.1.0" - } -} diff --git a/packages/aelis-data-source-weatherkit/scripts/generate-fixtures.ts b/packages/aelis-data-source-weatherkit/scripts/generate-fixtures.ts deleted file mode 100644 index 042ea94..0000000 --- a/packages/aelis-data-source-weatherkit/scripts/generate-fixtures.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { DefaultWeatherKitClient } from "../src/weatherkit" - -function loadEnv(): Record { - const content = require("fs").readFileSync(".env", "utf-8") - const env: Record = {} - - for (const line of content.split("\n")) { - const trimmed = line.trim() - if (!trimmed || trimmed.startsWith("#")) continue - - const eqIndex = trimmed.indexOf("=") - if (eqIndex === -1) continue - - const key = trimmed.slice(0, eqIndex) - let value = trimmed.slice(eqIndex + 1) - - if (value.startsWith('"') && value.endsWith('"')) { - value = value.slice(1, -1) - } - - env[key] = value.replace(/\\n/g, "\n") - } - - return env -} - -const env = loadEnv() - -const client = new DefaultWeatherKitClient({ - privateKey: env.WEATHERKIT_PRIVATE_KEY!, - keyId: env.WEATHERKIT_KEY_ID!, - teamId: env.WEATHERKIT_TEAM_ID!, - serviceId: env.WEATHERKIT_SERVICE_ID!, -}) - -const locations = { - sanFrancisco: { lat: 37.7749, lng: -122.4194 }, -} - -async function main() { - console.log("Fetching weather data for San Francisco...") - - const response = await client.fetch({ - lat: locations.sanFrancisco.lat, - lng: locations.sanFrancisco.lng, - }) - - const fixture = { - generatedAt: new Date().toISOString(), - location: locations.sanFrancisco, - response, - } - - const output = JSON.stringify(fixture) - await Bun.write("fixtures/san-francisco.json", output) - - console.log("Fixture written to fixtures/san-francisco.json") -} - -main().catch(console.error) diff --git a/packages/aelis-data-source-weatherkit/src/data-source.test.ts b/packages/aelis-data-source-weatherkit/src/data-source.test.ts deleted file mode 100644 index 8efd0a3..0000000 --- a/packages/aelis-data-source-weatherkit/src/data-source.test.ts +++ /dev/null @@ -1,233 +0,0 @@ -import type { ContextKey } from "@aelis/core" - -import { Context, contextKey } from "@aelis/core" -import { describe, expect, test } from "bun:test" - -import type { WeatherKitClient, WeatherKitResponse } from "./weatherkit" - -import fixture from "../fixtures/san-francisco.json" -import { WeatherKitDataSource, Units } from "./data-source" -import { WeatherFeedItemType } from "./feed-items" - -const mockCredentials = { - privateKey: "mock", - keyId: "mock", - teamId: "mock", - serviceId: "mock", -} - -interface LocationData { - lat: number - lng: number - accuracy: number -} - -const LocationKey: ContextKey = contextKey("aelis.location", "location") - -const createMockClient = (response: WeatherKitResponse): WeatherKitClient => ({ - fetch: async () => response, -}) - -function createMockContext(location?: { lat: number; lng: number }): Context { - const ctx = new Context(new Date("2026-01-17T00:00:00Z")) - if (location) { - ctx.set([[LocationKey, { ...location, accuracy: 10 }]]) - } - return ctx -} - -describe("WeatherKitDataSource", () => { - test("returns empty array when location is missing", async () => { - const dataSource = new WeatherKitDataSource({ - credentials: mockCredentials, - }) - const items = await dataSource.query(createMockContext()) - - expect(items).toEqual([]) - }) - - test("type is weather-current", () => { - const dataSource = new WeatherKitDataSource({ - credentials: mockCredentials, - }) - - expect(dataSource.type).toBe(WeatherFeedItemType.Current) - }) - - test("throws error if neither client nor credentials provided", () => { - expect(() => new WeatherKitDataSource({})).toThrow( - "Either client or credentials must be provided", - ) - }) -}) - -describe("WeatherKitDataSource with fixture", () => { - const response = fixture.response - - test("parses current weather from fixture", () => { - const current = response.currentWeather - - expect(typeof current.conditionCode).toBe("string") - expect(typeof current.temperature).toBe("number") - expect(typeof current.humidity).toBe("number") - expect(current.pressureTrend).toMatch(/^(rising|falling|steady)$/) - }) - - test("parses hourly forecast from fixture", () => { - const hours = response.forecastHourly.hours - - expect(hours.length).toBeGreaterThan(0) - - const firstHour = hours[0]! - expect(firstHour.forecastStart).toBeDefined() - expect(typeof firstHour.temperature).toBe("number") - expect(typeof firstHour.precipitationChance).toBe("number") - }) - - test("parses daily forecast from fixture", () => { - const days = response.forecastDaily.days - - expect(days.length).toBeGreaterThan(0) - - const firstDay = days[0]! - expect(firstDay.forecastStart).toBeDefined() - expect(typeof firstDay.temperatureMax).toBe("number") - expect(typeof firstDay.temperatureMin).toBe("number") - expect(firstDay.sunrise).toBeDefined() - expect(firstDay.sunset).toBeDefined() - }) - - test("hourly limit is respected", () => { - const dataSource = new WeatherKitDataSource({ - credentials: mockCredentials, - hourlyLimit: 6, - }) - - expect(dataSource["hourlyLimit"]).toBe(6) - }) - - test("daily limit is respected", () => { - const dataSource = new WeatherKitDataSource({ - credentials: mockCredentials, - dailyLimit: 3, - }) - - expect(dataSource["dailyLimit"]).toBe(3) - }) - - test("default limits are applied", () => { - const dataSource = new WeatherKitDataSource({ - credentials: mockCredentials, - }) - - expect(dataSource["hourlyLimit"]).toBe(12) - expect(dataSource["dailyLimit"]).toBe(7) - }) -}) - -describe("unit conversion", () => { - test("Units enum has metric and imperial", () => { - expect(Units.metric).toBe("metric") - expect(Units.imperial).toBe("imperial") - }) -}) - -describe("query() with mocked client", () => { - const mockClient = createMockClient(fixture.response as WeatherKitResponse) - - test("transforms API response into feed items", async () => { - const dataSource = new WeatherKitDataSource({ client: mockClient }) - const context = createMockContext({ lat: 37.7749, lng: -122.4194 }) - - const items = await dataSource.query(context) - - expect(items.length).toBeGreaterThan(0) - expect(items.some((i) => i.type === WeatherFeedItemType.Current)).toBe(true) - expect(items.some((i) => i.type === WeatherFeedItemType.Hourly)).toBe(true) - expect(items.some((i) => i.type === WeatherFeedItemType.Daily)).toBe(true) - }) - - test("applies hourly and daily limits", async () => { - const dataSource = new WeatherKitDataSource({ - client: mockClient, - hourlyLimit: 3, - dailyLimit: 2, - }) - const context = createMockContext({ lat: 37.7749, lng: -122.4194 }) - - const items = await dataSource.query(context) - - const hourlyItems = items.filter((i) => i.type === WeatherFeedItemType.Hourly) - const dailyItems = items.filter((i) => i.type === WeatherFeedItemType.Daily) - - expect(hourlyItems.length).toBe(3) - expect(dailyItems.length).toBe(2) - }) - - test("sets timestamp from context.time", async () => { - const dataSource = new WeatherKitDataSource({ client: mockClient }) - const queryTime = new Date("2026-01-17T12:00:00Z") - const context = createMockContext({ lat: 37.7749, lng: -122.4194 }) - context.time = queryTime - - const items = await dataSource.query(context) - - for (const item of items) { - expect(item.timestamp).toEqual(queryTime) - } - }) - - test("converts temperatures to imperial", async () => { - const dataSource = new WeatherKitDataSource({ client: mockClient }) - const context = createMockContext({ lat: 37.7749, lng: -122.4194 }) - - const metricItems = await dataSource.query(context, { - units: Units.metric, - }) - const imperialItems = await dataSource.query(context, { - units: Units.imperial, - }) - - const metricCurrent = metricItems.find((i) => i.type === WeatherFeedItemType.Current) - const imperialCurrent = imperialItems.find((i) => i.type === WeatherFeedItemType.Current) - - expect(metricCurrent).toBeDefined() - expect(imperialCurrent).toBeDefined() - - const metricTemp = (metricCurrent!.data as { temperature: number }).temperature - const imperialTemp = (imperialCurrent!.data as { temperature: number }).temperature - - // Verify conversion: F = C * 9/5 + 32 - const expectedImperial = (metricTemp * 9) / 5 + 32 - expect(imperialTemp).toBeCloseTo(expectedImperial, 2) - }) - - test("assigns signals based on weather conditions", async () => { - const dataSource = new WeatherKitDataSource({ client: mockClient }) - const context = createMockContext({ lat: 37.7749, lng: -122.4194 }) - - const items = await dataSource.query(context) - - for (const item of items) { - expect(item.signals).toBeDefined() - expect(item.signals!.urgency).toBeGreaterThanOrEqual(0) - expect(item.signals!.urgency).toBeLessThanOrEqual(1) - expect(item.signals!.timeRelevance).toBeDefined() - } - - const currentItem = items.find((i) => i.type === WeatherFeedItemType.Current) - expect(currentItem).toBeDefined() - expect(currentItem!.signals!.urgency).toBeGreaterThanOrEqual(0.5) - }) - - test("generates unique IDs for each item", async () => { - const dataSource = new WeatherKitDataSource({ client: mockClient }) - const context = createMockContext({ lat: 37.7749, lng: -122.4194 }) - - const items = await dataSource.query(context) - const ids = items.map((i) => i.id) - const uniqueIds = new Set(ids) - - expect(uniqueIds.size).toBe(ids.length) - }) -}) diff --git a/packages/aelis-data-source-weatherkit/src/data-source.ts b/packages/aelis-data-source-weatherkit/src/data-source.ts deleted file mode 100644 index 4df49de..0000000 --- a/packages/aelis-data-source-weatherkit/src/data-source.ts +++ /dev/null @@ -1,356 +0,0 @@ -import type { Context, ContextKey, DataSource, FeedItemSignals } from "@aelis/core" - -import { TimeRelevance, contextKey } from "@aelis/core" - -import { - WeatherFeedItemType, - type CurrentWeatherFeedItem, - type DailyWeatherFeedItem, - type HourlyWeatherFeedItem, - type WeatherAlertFeedItem, - type WeatherFeedItem, -} from "./feed-items" -import { - ConditionCode, - DefaultWeatherKitClient, - Severity, - type CurrentWeather, - type DailyForecast, - type HourlyForecast, - type WeatherAlert, - type WeatherKitClient, - type WeatherKitCredentials, -} from "./weatherkit" - -export const Units = { - metric: "metric", - imperial: "imperial", -} as const - -export type Units = (typeof Units)[keyof typeof Units] - -export interface WeatherKitDataSourceOptions { - credentials?: WeatherKitCredentials - client?: WeatherKitClient - hourlyLimit?: number - dailyLimit?: number -} - -export interface WeatherKitQueryConfig { - units?: Units -} - -interface LocationData { - lat: number - lng: number -} - -const LocationKey: ContextKey = contextKey("aelis.location", "location") - -const SOURCE_ID = "aelis.weather" - -export class WeatherKitDataSource implements DataSource { - private readonly DEFAULT_HOURLY_LIMIT = 12 - private readonly DEFAULT_DAILY_LIMIT = 7 - - readonly type = WeatherFeedItemType.Current - private readonly client: WeatherKitClient - private readonly hourlyLimit: number - private readonly dailyLimit: number - - constructor(options: WeatherKitDataSourceOptions) { - if (!options.client && !options.credentials) { - throw new Error("Either client or credentials must be provided") - } - this.client = options.client ?? new DefaultWeatherKitClient(options.credentials!) - this.hourlyLimit = options.hourlyLimit ?? this.DEFAULT_HOURLY_LIMIT - this.dailyLimit = options.dailyLimit ?? this.DEFAULT_DAILY_LIMIT - } - - async query(context: Context, config: WeatherKitQueryConfig = {}): Promise { - const location = context.get(LocationKey) - if (!location) { - return [] - } - - const units = config.units ?? Units.metric - const timestamp = context.time - - const response = await this.client.fetch({ - lat: location.lat, - lng: location.lng, - }) - - const items: WeatherFeedItem[] = [] - - if (response.currentWeather) { - items.push(createCurrentWeatherFeedItem(response.currentWeather, timestamp, units)) - } - - if (response.forecastHourly?.hours) { - const hours = response.forecastHourly.hours.slice(0, this.hourlyLimit) - for (let i = 0; i < hours.length; i++) { - const hour = hours[i] - if (hour) { - items.push(createHourlyWeatherFeedItem(hour, i, timestamp, units)) - } - } - } - - if (response.forecastDaily?.days) { - const days = response.forecastDaily.days.slice(0, this.dailyLimit) - for (let i = 0; i < days.length; i++) { - const day = days[i] - if (day) { - items.push(createDailyWeatherFeedItem(day, i, timestamp, units)) - } - } - } - - if (response.weatherAlerts?.alerts) { - for (const alert of response.weatherAlerts.alerts) { - items.push(createWeatherAlertFeedItem(alert, timestamp)) - } - } - - return items - } -} - -const BASE_URGENCY = { - current: 0.5, - hourly: 0.3, - daily: 0.2, - alert: 0.7, -} as const - -const SEVERE_CONDITIONS = new Set([ - ConditionCode.SevereThunderstorm, - ConditionCode.Hurricane, - ConditionCode.Tornado, - ConditionCode.TropicalStorm, - ConditionCode.Blizzard, - ConditionCode.FreezingRain, - ConditionCode.Hail, - ConditionCode.Frigid, - ConditionCode.Hot, -]) - -const MODERATE_CONDITIONS = new Set([ - ConditionCode.Thunderstorm, - ConditionCode.IsolatedThunderstorms, - ConditionCode.ScatteredThunderstorms, - ConditionCode.HeavyRain, - ConditionCode.HeavySnow, - ConditionCode.FreezingDrizzle, - ConditionCode.BlowingSnow, -]) - -function adjustUrgencyForCondition(baseUrgency: number, conditionCode: ConditionCode): number { - if (SEVERE_CONDITIONS.has(conditionCode)) { - return Math.min(1, baseUrgency + 0.3) - } - if (MODERATE_CONDITIONS.has(conditionCode)) { - return Math.min(1, baseUrgency + 0.15) - } - return baseUrgency -} - -function adjustUrgencyForAlertSeverity(severity: Severity): number { - switch (severity) { - case Severity.Extreme: - return 1 - case Severity.Severe: - return 0.9 - case Severity.Moderate: - return 0.75 - case Severity.Minor: - return BASE_URGENCY.alert - } -} - -function timeRelevanceForCondition(conditionCode: ConditionCode): TimeRelevance { - if (SEVERE_CONDITIONS.has(conditionCode)) { - return TimeRelevance.Imminent - } - if (MODERATE_CONDITIONS.has(conditionCode)) { - return TimeRelevance.Upcoming - } - return TimeRelevance.Ambient -} - -function timeRelevanceForAlertSeverity(severity: Severity): TimeRelevance { - switch (severity) { - case Severity.Extreme: - case Severity.Severe: - return TimeRelevance.Imminent - case Severity.Moderate: - return TimeRelevance.Upcoming - case Severity.Minor: - return TimeRelevance.Ambient - } -} - -function convertTemperature(celsius: number, units: Units): number { - if (units === Units.imperial) { - return (celsius * 9) / 5 + 32 - } - return celsius -} - -function convertSpeed(kmh: number, units: Units): number { - if (units === Units.imperial) { - return kmh * 0.621371 - } - return kmh -} - -function convertDistance(km: number, units: Units): number { - if (units === Units.imperial) { - return km * 0.621371 - } - return km -} - -function convertPrecipitation(mm: number, units: Units): number { - if (units === Units.imperial) { - return mm * 0.0393701 - } - return mm -} - -function convertPressure(mb: number, units: Units): number { - if (units === Units.imperial) { - return mb * 0.02953 - } - return mb -} - -function createCurrentWeatherFeedItem( - current: CurrentWeather, - timestamp: Date, - units: Units, -): CurrentWeatherFeedItem { - const signals: FeedItemSignals = { - urgency: adjustUrgencyForCondition(BASE_URGENCY.current, current.conditionCode), - timeRelevance: timeRelevanceForCondition(current.conditionCode), - } - - return { - id: `weather-current-${timestamp.getTime()}`, - sourceId: SOURCE_ID, - type: WeatherFeedItemType.Current, - timestamp, - data: { - conditionCode: current.conditionCode, - daylight: current.daylight, - humidity: current.humidity, - precipitationIntensity: convertPrecipitation(current.precipitationIntensity, units), - pressure: convertPressure(current.pressure, units), - pressureTrend: current.pressureTrend, - temperature: convertTemperature(current.temperature, units), - temperatureApparent: convertTemperature(current.temperatureApparent, units), - uvIndex: current.uvIndex, - visibility: convertDistance(current.visibility, units), - windDirection: current.windDirection, - windGust: convertSpeed(current.windGust, units), - windSpeed: convertSpeed(current.windSpeed, units), - }, - signals, - } -} - -function createHourlyWeatherFeedItem( - hourly: HourlyForecast, - index: number, - timestamp: Date, - units: Units, -): HourlyWeatherFeedItem { - const signals: FeedItemSignals = { - urgency: adjustUrgencyForCondition(BASE_URGENCY.hourly, hourly.conditionCode), - timeRelevance: timeRelevanceForCondition(hourly.conditionCode), - } - - return { - id: `weather-hourly-${timestamp.getTime()}-${index}`, - sourceId: SOURCE_ID, - type: WeatherFeedItemType.Hourly, - timestamp, - data: { - forecastTime: new Date(hourly.forecastStart), - conditionCode: hourly.conditionCode, - daylight: hourly.daylight, - humidity: hourly.humidity, - precipitationAmount: convertPrecipitation(hourly.precipitationAmount, units), - precipitationChance: hourly.precipitationChance, - precipitationType: hourly.precipitationType, - temperature: convertTemperature(hourly.temperature, units), - temperatureApparent: convertTemperature(hourly.temperatureApparent, units), - uvIndex: hourly.uvIndex, - windDirection: hourly.windDirection, - windGust: convertSpeed(hourly.windGust, units), - windSpeed: convertSpeed(hourly.windSpeed, units), - }, - signals, - } -} - -function createDailyWeatherFeedItem( - daily: DailyForecast, - index: number, - timestamp: Date, - units: Units, -): DailyWeatherFeedItem { - const signals: FeedItemSignals = { - urgency: adjustUrgencyForCondition(BASE_URGENCY.daily, daily.conditionCode), - timeRelevance: timeRelevanceForCondition(daily.conditionCode), - } - - return { - id: `weather-daily-${timestamp.getTime()}-${index}`, - sourceId: SOURCE_ID, - type: WeatherFeedItemType.Daily, - timestamp, - data: { - forecastDate: new Date(daily.forecastStart), - conditionCode: daily.conditionCode, - maxUvIndex: daily.maxUvIndex, - precipitationAmount: convertPrecipitation(daily.precipitationAmount, units), - precipitationChance: daily.precipitationChance, - precipitationType: daily.precipitationType, - snowfallAmount: convertPrecipitation(daily.snowfallAmount, units), - sunrise: new Date(daily.sunrise), - sunset: new Date(daily.sunset), - temperatureMax: convertTemperature(daily.temperatureMax, units), - temperatureMin: convertTemperature(daily.temperatureMin, units), - }, - signals, - } -} - -function createWeatherAlertFeedItem(alert: WeatherAlert, timestamp: Date): WeatherAlertFeedItem { - const signals: FeedItemSignals = { - urgency: adjustUrgencyForAlertSeverity(alert.severity), - timeRelevance: timeRelevanceForAlertSeverity(alert.severity), - } - - return { - id: `weather-alert-${alert.id}`, - sourceId: SOURCE_ID, - type: WeatherFeedItemType.Alert, - timestamp, - data: { - alertId: alert.id, - areaName: alert.areaName, - certainty: alert.certainty, - description: alert.description, - detailsUrl: alert.detailsUrl, - effectiveTime: new Date(alert.effectiveTime), - expireTime: new Date(alert.expireTime), - severity: alert.severity, - source: alert.source, - urgency: alert.urgency, - }, - signals, - } -} diff --git a/packages/aelis-data-source-weatherkit/src/feed-items.ts b/packages/aelis-data-source-weatherkit/src/feed-items.ts deleted file mode 100644 index 3b4ca10..0000000 --- a/packages/aelis-data-source-weatherkit/src/feed-items.ts +++ /dev/null @@ -1,97 +0,0 @@ -import type { FeedItem } from "@aelis/core" - -import type { Certainty, ConditionCode, PrecipitationType, Severity, Urgency } from "./weatherkit" - -export const WeatherFeedItemType = { - Current: "weather-current", - Hourly: "weather-hourly", - Daily: "weather-daily", - Alert: "weather-alert", -} as const - -export type WeatherFeedItemType = (typeof WeatherFeedItemType)[keyof typeof WeatherFeedItemType] - -export type CurrentWeatherData = { - conditionCode: ConditionCode - daylight: boolean - humidity: number - precipitationIntensity: number - pressure: number - pressureTrend: "rising" | "falling" | "steady" - temperature: number - temperatureApparent: number - uvIndex: number - visibility: number - windDirection: number - windGust: number - windSpeed: number -} - -export interface CurrentWeatherFeedItem extends FeedItem< - typeof WeatherFeedItemType.Current, - CurrentWeatherData -> {} - -export type HourlyWeatherData = { - forecastTime: Date - conditionCode: ConditionCode - daylight: boolean - humidity: number - precipitationAmount: number - precipitationChance: number - precipitationType: PrecipitationType - temperature: number - temperatureApparent: number - uvIndex: number - windDirection: number - windGust: number - windSpeed: number -} - -export interface HourlyWeatherFeedItem extends FeedItem< - typeof WeatherFeedItemType.Hourly, - HourlyWeatherData -> {} - -export type DailyWeatherData = { - forecastDate: Date - conditionCode: ConditionCode - maxUvIndex: number - precipitationAmount: number - precipitationChance: number - precipitationType: PrecipitationType - snowfallAmount: number - sunrise: Date - sunset: Date - temperatureMax: number - temperatureMin: number -} - -export interface DailyWeatherFeedItem extends FeedItem< - typeof WeatherFeedItemType.Daily, - DailyWeatherData -> {} - -export type WeatherAlertData = { - alertId: string - areaName: string - certainty: Certainty - description: string - detailsUrl: string - effectiveTime: Date - expireTime: Date - severity: Severity - source: string - urgency: Urgency -} - -export interface WeatherAlertFeedItem extends FeedItem< - typeof WeatherFeedItemType.Alert, - WeatherAlertData -> {} - -export type WeatherFeedItem = - | CurrentWeatherFeedItem - | HourlyWeatherFeedItem - | DailyWeatherFeedItem - | WeatherAlertFeedItem diff --git a/packages/aelis-data-source-weatherkit/src/index.ts b/packages/aelis-data-source-weatherkit/src/index.ts deleted file mode 100644 index d818113..0000000 --- a/packages/aelis-data-source-weatherkit/src/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -export { - WeatherKitDataSource, - Units, - type Units as UnitsType, - type WeatherKitDataSourceOptions, - type WeatherKitQueryConfig, -} from "./data-source" - -export { - WeatherFeedItemType, - type WeatherFeedItemType as WeatherFeedItemTypeType, - type CurrentWeatherData, - type CurrentWeatherFeedItem, - type DailyWeatherData, - type DailyWeatherFeedItem, - type HourlyWeatherData, - type HourlyWeatherFeedItem, - type WeatherAlertData, - type WeatherAlertFeedItem, - type WeatherFeedItem, -} from "./feed-items" - -export { - Severity, - Urgency, - Certainty, - PrecipitationType, - ConditionCode, - DefaultWeatherKitClient, - type Severity as SeverityType, - type Urgency as UrgencyType, - type Certainty as CertaintyType, - type PrecipitationType as PrecipitationTypeType, - type ConditionCode as ConditionCodeType, - type WeatherKitCredentials, - type WeatherKitClient, - type WeatherKitQueryOptions, -} from "./weatherkit" diff --git a/packages/aelis-data-source-weatherkit/src/weatherkit.ts b/packages/aelis-data-source-weatherkit/src/weatherkit.ts deleted file mode 100644 index 455e465..0000000 --- a/packages/aelis-data-source-weatherkit/src/weatherkit.ts +++ /dev/null @@ -1,367 +0,0 @@ -// WeatherKit REST API client and response types -// https://developer.apple.com/documentation/weatherkitrestapi - -import { type } from "arktype" - -export interface WeatherKitCredentials { - privateKey: string - keyId: string - teamId: string - serviceId: string -} - -export interface WeatherKitQueryOptions { - lat: number - lng: number - language?: string - timezone?: string -} - -export interface WeatherKitClient { - fetch(query: WeatherKitQueryOptions): Promise -} - -export class DefaultWeatherKitClient implements WeatherKitClient { - private readonly credentials: WeatherKitCredentials - - constructor(credentials: WeatherKitCredentials) { - this.credentials = credentials - } - - async fetch(query: WeatherKitQueryOptions): Promise { - const token = await generateJwt(this.credentials) - - const dataSets = ["currentWeather", "forecastHourly", "forecastDaily", "weatherAlerts"].join( - ",", - ) - - const url = new URL( - `${WEATHERKIT_API_BASE}/weather/${query.language ?? "en"}/${query.lat}/${query.lng}`, - ) - url.searchParams.set("dataSets", dataSets) - if (query.timezone) { - url.searchParams.set("timezone", query.timezone) - } - - const response = await fetch(url.toString(), { - headers: { - Authorization: `Bearer ${token}`, - }, - }) - - if (!response.ok) { - const body = await response.text() - throw new Error(`WeatherKit API error: ${response.status} ${response.statusText}: ${body}`) - } - - const json = await response.json() - const result = weatherKitResponseSchema(json) - - if (result instanceof type.errors) { - throw new Error(`WeatherKit API response validation failed: ${result.summary}`) - } - - return result - } -} - -export const Severity = { - Minor: "minor", - Moderate: "moderate", - Severe: "severe", - Extreme: "extreme", -} as const - -export type Severity = (typeof Severity)[keyof typeof Severity] - -export const Urgency = { - Immediate: "immediate", - Expected: "expected", - Future: "future", - Past: "past", - Unknown: "unknown", -} as const - -export type Urgency = (typeof Urgency)[keyof typeof Urgency] - -export const Certainty = { - Observed: "observed", - Likely: "likely", - Possible: "possible", - Unlikely: "unlikely", - Unknown: "unknown", -} as const - -export type Certainty = (typeof Certainty)[keyof typeof Certainty] - -export const PrecipitationType = { - Clear: "clear", - Precipitation: "precipitation", - Rain: "rain", - Snow: "snow", - Sleet: "sleet", - Hail: "hail", - Mixed: "mixed", -} as const - -export type PrecipitationType = (typeof PrecipitationType)[keyof typeof PrecipitationType] - -export const ConditionCode = { - Clear: "Clear", - Cloudy: "Cloudy", - Dust: "Dust", - Fog: "Fog", - Haze: "Haze", - MostlyClear: "MostlyClear", - MostlyCloudy: "MostlyCloudy", - PartlyCloudy: "PartlyCloudy", - ScatteredThunderstorms: "ScatteredThunderstorms", - Smoke: "Smoke", - Breezy: "Breezy", - Windy: "Windy", - Drizzle: "Drizzle", - HeavyRain: "HeavyRain", - Rain: "Rain", - Showers: "Showers", - Flurries: "Flurries", - HeavySnow: "HeavySnow", - MixedRainAndSleet: "MixedRainAndSleet", - MixedRainAndSnow: "MixedRainAndSnow", - MixedRainfall: "MixedRainfall", - MixedSnowAndSleet: "MixedSnowAndSleet", - ScatteredShowers: "ScatteredShowers", - ScatteredSnowShowers: "ScatteredSnowShowers", - Sleet: "Sleet", - Snow: "Snow", - SnowShowers: "SnowShowers", - Blizzard: "Blizzard", - BlowingSnow: "BlowingSnow", - FreezingDrizzle: "FreezingDrizzle", - FreezingRain: "FreezingRain", - Frigid: "Frigid", - Hail: "Hail", - Hot: "Hot", - Hurricane: "Hurricane", - IsolatedThunderstorms: "IsolatedThunderstorms", - SevereThunderstorm: "SevereThunderstorm", - Thunderstorm: "Thunderstorm", - Tornado: "Tornado", - TropicalStorm: "TropicalStorm", -} as const - -export type ConditionCode = (typeof ConditionCode)[keyof typeof ConditionCode] - -const WEATHERKIT_API_BASE = "https://weatherkit.apple.com/api/v1" - -const severitySchema = type.enumerated( - Severity.Minor, - Severity.Moderate, - Severity.Severe, - Severity.Extreme, -) - -const urgencySchema = type.enumerated( - Urgency.Immediate, - Urgency.Expected, - Urgency.Future, - Urgency.Past, - Urgency.Unknown, -) - -const certaintySchema = type.enumerated( - Certainty.Observed, - Certainty.Likely, - Certainty.Possible, - Certainty.Unlikely, - Certainty.Unknown, -) - -const precipitationTypeSchema = type.enumerated( - PrecipitationType.Clear, - PrecipitationType.Precipitation, - PrecipitationType.Rain, - PrecipitationType.Snow, - PrecipitationType.Sleet, - PrecipitationType.Hail, - PrecipitationType.Mixed, -) - -const conditionCodeSchema = type.enumerated(...Object.values(ConditionCode)) - -const pressureTrendSchema = type.enumerated("rising", "falling", "steady") - -const currentWeatherSchema = type({ - asOf: "string", - conditionCode: conditionCodeSchema, - daylight: "boolean", - humidity: "number", - precipitationIntensity: "number", - pressure: "number", - pressureTrend: pressureTrendSchema, - temperature: "number", - temperatureApparent: "number", - temperatureDewPoint: "number", - uvIndex: "number", - visibility: "number", - windDirection: "number", - windGust: "number", - windSpeed: "number", -}) - -export type CurrentWeather = typeof currentWeatherSchema.infer - -const hourlyForecastSchema = type({ - forecastStart: "string", - conditionCode: conditionCodeSchema, - daylight: "boolean", - humidity: "number", - precipitationAmount: "number", - precipitationChance: "number", - precipitationType: precipitationTypeSchema, - pressure: "number", - snowfallIntensity: "number", - temperature: "number", - temperatureApparent: "number", - temperatureDewPoint: "number", - uvIndex: "number", - visibility: "number", - windDirection: "number", - windGust: "number", - windSpeed: "number", -}) - -export type HourlyForecast = typeof hourlyForecastSchema.infer - -const dayWeatherConditionsSchema = type({ - conditionCode: conditionCodeSchema, - humidity: "number", - precipitationAmount: "number", - precipitationChance: "number", - precipitationType: precipitationTypeSchema, - snowfallAmount: "number", - temperatureMax: "number", - temperatureMin: "number", - windDirection: "number", - "windGust?": "number", - windSpeed: "number", -}) - -export type DayWeatherConditions = typeof dayWeatherConditionsSchema.infer - -const dailyForecastSchema = type({ - forecastStart: "string", - forecastEnd: "string", - conditionCode: conditionCodeSchema, - maxUvIndex: "number", - moonPhase: "string", - "moonrise?": "string", - "moonset?": "string", - precipitationAmount: "number", - precipitationChance: "number", - precipitationType: precipitationTypeSchema, - snowfallAmount: "number", - sunrise: "string", - sunriseCivil: "string", - sunriseNautical: "string", - sunriseAstronomical: "string", - sunset: "string", - sunsetCivil: "string", - sunsetNautical: "string", - sunsetAstronomical: "string", - temperatureMax: "number", - temperatureMin: "number", - "daytimeForecast?": dayWeatherConditionsSchema, - "overnightForecast?": dayWeatherConditionsSchema, -}) - -export type DailyForecast = typeof dailyForecastSchema.infer - -const weatherAlertSchema = type({ - id: "string", - areaId: "string", - areaName: "string", - certainty: certaintySchema, - countryCode: "string", - description: "string", - detailsUrl: "string", - effectiveTime: "string", - expireTime: "string", - issuedTime: "string", - responses: "string[]", - severity: severitySchema, - source: "string", - urgency: urgencySchema, -}) - -export type WeatherAlert = typeof weatherAlertSchema.infer - -const weatherKitResponseSchema = type({ - "currentWeather?": currentWeatherSchema, - "forecastHourly?": type({ - hours: hourlyForecastSchema.array(), - }), - "forecastDaily?": type({ - days: dailyForecastSchema.array(), - }), - "weatherAlerts?": type({ - alerts: weatherAlertSchema.array(), - }), -}) - -export type WeatherKitResponse = typeof weatherKitResponseSchema.infer - -async function generateJwt(credentials: WeatherKitCredentials): Promise { - const header = { - alg: "ES256", - kid: credentials.keyId, - id: `${credentials.teamId}.${credentials.serviceId}`, - } - - const now = Math.floor(Date.now() / 1000) - const payload = { - iss: credentials.teamId, - iat: now, - exp: now + 3600, - sub: credentials.serviceId, - } - - const encoder = new TextEncoder() - const headerB64 = btoa(JSON.stringify(header)) - .replace(/\+/g, "-") - .replace(/\//g, "_") - .replace(/=+$/, "") - const payloadB64 = btoa(JSON.stringify(payload)) - .replace(/\+/g, "-") - .replace(/\//g, "_") - .replace(/=+$/, "") - - const signingInput = `${headerB64}.${payloadB64}` - - const pemContents = credentials.privateKey - .replace(/-----BEGIN PRIVATE KEY-----/, "") - .replace(/-----END PRIVATE KEY-----/, "") - .replace(/\s/g, "") - - const binaryKey = Uint8Array.from(atob(pemContents), (c) => c.charCodeAt(0)) - - const cryptoKey = await crypto.subtle.importKey( - "pkcs8", - binaryKey, - { name: "ECDSA", namedCurve: "P-256" }, - false, - ["sign"], - ) - - const signature = await crypto.subtle.sign( - { name: "ECDSA", hash: "SHA-256" }, - cryptoKey, - encoder.encode(signingInput), - ) - - const signatureB64 = btoa(String.fromCharCode(...new Uint8Array(signature))) - .replace(/\+/g, "-") - .replace(/\//g, "_") - .replace(/=+$/, "") - - return `${signingInput}.${signatureB64}` -}