From d0b3f76a6f2b78e89b792d2880f3f873bee3eaf6 Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Mon, 5 Apr 2021 13:39:39 -0400 Subject: [PATCH] Add ClimaCell v4 API support (#47575) * Add ClimaCell v4 API support * fix tests * use constants * fix logic and update tests * revert accidental changes and enable hourly and nowcast forecast entities in test * use variable instead of accessing dictionary multiple times * only grab necessary fields * add _translate_condition method ot base class * bump pyclimacell again to fix bug * switch typehints back to new format * more typehint fixes * fix tests * revert merge conflict change * handle 'migration' in async_setup_entry so we don't have to bump config entry versions * parametrize timestep test --- .coveragerc | 1 - .../components/climacell/__init__.py | 214 +- .../components/climacell/config_flow.py | 34 +- homeassistant/components/climacell/const.py | 94 +- .../components/climacell/manifest.json | 2 +- .../components/climacell/strings.json | 4 +- homeassistant/components/climacell/weather.py | 370 ++- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/climacell/conftest.py | 27 +- tests/components/climacell/const.py | 31 +- .../components/climacell/test_config_flow.py | 44 +- tests/components/climacell/test_init.py | 61 +- tests/components/climacell/test_weather.py | 382 +++ .../fixtures/climacell/v3_forecast_daily.json | 992 +++++++ .../climacell/v3_forecast_hourly.json | 752 ++++++ .../climacell/v3_forecast_nowcast.json | 782 ++++++ tests/fixtures/climacell/v3_realtime.json | 38 + tests/fixtures/climacell/v4.json | 2360 +++++++++++++++++ 19 files changed, 5973 insertions(+), 219 deletions(-) create mode 100644 tests/components/climacell/test_weather.py create mode 100644 tests/fixtures/climacell/v3_forecast_daily.json create mode 100644 tests/fixtures/climacell/v3_forecast_hourly.json create mode 100644 tests/fixtures/climacell/v3_forecast_nowcast.json create mode 100644 tests/fixtures/climacell/v3_realtime.json create mode 100644 tests/fixtures/climacell/v4.json diff --git a/.coveragerc b/.coveragerc index f3cdf62ff73..2dcf43ef697 100644 --- a/.coveragerc +++ b/.coveragerc @@ -145,7 +145,6 @@ omit = homeassistant/components/clickatell/notify.py homeassistant/components/clicksend/notify.py homeassistant/components/clicksend_tts/notify.py - homeassistant/components/climacell/weather.py homeassistant/components/cmus/media_player.py homeassistant/components/co2signal/* homeassistant/components/coinbase/* diff --git a/homeassistant/components/climacell/__init__.py b/homeassistant/components/climacell/__init__.py index 1498c51f54a..8095f7991bd 100644 --- a/homeassistant/components/climacell/__init__.py +++ b/homeassistant/components/climacell/__init__.py @@ -7,14 +7,9 @@ import logging from math import ceil from typing import Any -from pyclimacell import ClimaCell -from pyclimacell.const import ( - FORECAST_DAILY, - FORECAST_HOURLY, - FORECAST_NOWCAST, - REALTIME, -) -from pyclimacell.pyclimacell import ( +from pyclimacell import ClimaCellV3, ClimaCellV4 +from pyclimacell.const import CURRENT, DAILY, FORECASTS, HOURLY, NOWCAST +from pyclimacell.exceptions import ( CantConnectException, InvalidAPIKeyException, RateLimitedException, @@ -23,7 +18,13 @@ from pyclimacell.pyclimacell import ( from homeassistant.components.weather import DOMAIN as WEATHER_DOMAIN from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME +from homeassistant.const import ( + CONF_API_KEY, + CONF_API_VERSION, + CONF_LATITUDE, + CONF_LONGITUDE, + CONF_NAME, +) from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.typing import HomeAssistantType from homeassistant.helpers.update_coordinator import ( @@ -34,15 +35,34 @@ from homeassistant.helpers.update_coordinator import ( from .const import ( ATTRIBUTION, + CC_ATTR_CONDITION, + CC_ATTR_HUMIDITY, + CC_ATTR_OZONE, + CC_ATTR_PRECIPITATION, + CC_ATTR_PRECIPITATION_PROBABILITY, + CC_ATTR_PRESSURE, + CC_ATTR_TEMPERATURE, + CC_ATTR_TEMPERATURE_HIGH, + CC_ATTR_TEMPERATURE_LOW, + CC_ATTR_VISIBILITY, + CC_ATTR_WIND_DIRECTION, + CC_ATTR_WIND_SPEED, + CC_V3_ATTR_CONDITION, + CC_V3_ATTR_HUMIDITY, + CC_V3_ATTR_OZONE, + CC_V3_ATTR_PRECIPITATION, + CC_V3_ATTR_PRECIPITATION_DAILY, + CC_V3_ATTR_PRECIPITATION_PROBABILITY, + CC_V3_ATTR_PRESSURE, + CC_V3_ATTR_TEMPERATURE, + CC_V3_ATTR_VISIBILITY, + CC_V3_ATTR_WIND_DIRECTION, + CC_V3_ATTR_WIND_SPEED, CONF_TIMESTEP, - CURRENT, - DAILY, + DEFAULT_FORECAST_TYPE, DEFAULT_TIMESTEP, DOMAIN, - FORECASTS, - HOURLY, MAX_REQUESTS_PER_DAY, - NOWCAST, ) _LOGGER = logging.getLogger(__name__) @@ -54,6 +74,7 @@ def _set_update_interval( hass: HomeAssistantType, current_entry: ConfigEntry ) -> timedelta: """Recalculate update_interval based on existing ClimaCell instances and update them.""" + api_calls = 4 if current_entry.data[CONF_API_VERSION] == 3 else 2 # We check how many ClimaCell configured instances are using the same API key and # calculate interval to not exceed allowed numbers of requests. Divide 90% of # MAX_REQUESTS_PER_DAY by 4 because every update requires four API calls and we want @@ -68,7 +89,7 @@ def _set_update_interval( interval = timedelta( minutes=( ceil( - (24 * 60 * (len(other_instance_entry_ids) + 1) * 4) + (24 * 60 * (len(other_instance_entry_ids) + 1) * api_calls) / (MAX_REQUESTS_PER_DAY * 0.9) ) ) @@ -85,24 +106,48 @@ async def async_setup_entry(hass: HomeAssistantType, config_entry: ConfigEntry) """Set up ClimaCell API from a config entry.""" hass.data.setdefault(DOMAIN, {}) + params = {} # If config entry options not set up, set them up if not config_entry.options: - hass.config_entries.async_update_entry( - config_entry, - options={ - CONF_TIMESTEP: DEFAULT_TIMESTEP, - }, - ) + params["options"] = { + CONF_TIMESTEP: DEFAULT_TIMESTEP, + } + else: + # Use valid timestep if it's invalid + timestep = config_entry.options[CONF_TIMESTEP] + if timestep not in (1, 5, 15, 30): + if timestep <= 2: + timestep = 1 + elif timestep <= 7: + timestep = 5 + elif timestep <= 20: + timestep = 15 + else: + timestep = 30 + new_options = config_entry.options.copy() + new_options[CONF_TIMESTEP] = timestep + params["options"] = new_options + # Add API version if not found + if CONF_API_VERSION not in config_entry.data: + new_data = config_entry.data.copy() + new_data[CONF_API_VERSION] = 3 + params["data"] = new_data + + if params: + hass.config_entries.async_update_entry(config_entry, **params) + + api_class = ClimaCellV3 if config_entry.data[CONF_API_VERSION] == 3 else ClimaCellV4 + api = api_class( + config_entry.data[CONF_API_KEY], + config_entry.data.get(CONF_LATITUDE, hass.config.latitude), + config_entry.data.get(CONF_LONGITUDE, hass.config.longitude), + session=async_get_clientsession(hass), + ) coordinator = ClimaCellDataUpdateCoordinator( hass, config_entry, - ClimaCell( - config_entry.data[CONF_API_KEY], - config_entry.data.get(CONF_LATITUDE, hass.config.latitude), - config_entry.data.get(CONF_LONGITUDE, hass.config.longitude), - session=async_get_clientsession(hass), - ), + api, _set_update_interval(hass, config_entry), ) @@ -145,12 +190,13 @@ class ClimaCellDataUpdateCoordinator(DataUpdateCoordinator): self, hass: HomeAssistantType, config_entry: ConfigEntry, - api: ClimaCell, + api: ClimaCellV3 | ClimaCellV4, update_interval: timedelta, ) -> None: """Initialize.""" self._config_entry = config_entry + self._api_version = config_entry.data[CONF_API_VERSION] self._api = api self.name = config_entry.data[CONF_NAME] self.data = {CURRENT: {}, FORECASTS: {}} @@ -166,27 +212,81 @@ class ClimaCellDataUpdateCoordinator(DataUpdateCoordinator): """Update data via library.""" data = {FORECASTS: {}} try: - data[CURRENT] = await self._api.realtime( - self._api.available_fields(REALTIME) - ) - data[FORECASTS][HOURLY] = await self._api.forecast_hourly( - self._api.available_fields(FORECAST_HOURLY), - None, - timedelta(hours=24), - ) + if self._api_version == 3: + data[CURRENT] = await self._api.realtime( + [ + CC_V3_ATTR_TEMPERATURE, + CC_V3_ATTR_HUMIDITY, + CC_V3_ATTR_PRESSURE, + CC_V3_ATTR_WIND_SPEED, + CC_V3_ATTR_WIND_DIRECTION, + CC_V3_ATTR_CONDITION, + CC_V3_ATTR_VISIBILITY, + CC_V3_ATTR_OZONE, + ] + ) + data[FORECASTS][HOURLY] = await self._api.forecast_hourly( + [ + CC_V3_ATTR_TEMPERATURE, + CC_V3_ATTR_WIND_SPEED, + CC_V3_ATTR_WIND_DIRECTION, + CC_V3_ATTR_CONDITION, + CC_V3_ATTR_PRECIPITATION, + CC_V3_ATTR_PRECIPITATION_PROBABILITY, + ], + None, + timedelta(hours=24), + ) - data[FORECASTS][DAILY] = await self._api.forecast_daily( - self._api.available_fields(FORECAST_DAILY), None, timedelta(days=14) - ) + data[FORECASTS][DAILY] = await self._api.forecast_daily( + [ + CC_V3_ATTR_TEMPERATURE, + CC_V3_ATTR_WIND_SPEED, + CC_V3_ATTR_WIND_DIRECTION, + CC_V3_ATTR_CONDITION, + CC_V3_ATTR_PRECIPITATION_DAILY, + CC_V3_ATTR_PRECIPITATION_PROBABILITY, + ], + None, + timedelta(days=14), + ) - data[FORECASTS][NOWCAST] = await self._api.forecast_nowcast( - self._api.available_fields(FORECAST_NOWCAST), - None, - timedelta( - minutes=min(300, self._config_entry.options[CONF_TIMESTEP] * 30) - ), - self._config_entry.options[CONF_TIMESTEP], - ) + data[FORECASTS][NOWCAST] = await self._api.forecast_nowcast( + [ + CC_V3_ATTR_TEMPERATURE, + CC_V3_ATTR_WIND_SPEED, + CC_V3_ATTR_WIND_DIRECTION, + CC_V3_ATTR_CONDITION, + CC_V3_ATTR_PRECIPITATION, + ], + None, + timedelta( + minutes=min(300, self._config_entry.options[CONF_TIMESTEP] * 30) + ), + self._config_entry.options[CONF_TIMESTEP], + ) + else: + return await self._api.realtime_and_all_forecasts( + [ + CC_ATTR_TEMPERATURE, + CC_ATTR_HUMIDITY, + CC_ATTR_PRESSURE, + CC_ATTR_WIND_SPEED, + CC_ATTR_WIND_DIRECTION, + CC_ATTR_CONDITION, + CC_ATTR_VISIBILITY, + CC_ATTR_OZONE, + ], + [ + CC_ATTR_TEMPERATURE_LOW, + CC_ATTR_TEMPERATURE_HIGH, + CC_ATTR_WIND_SPEED, + CC_ATTR_WIND_DIRECTION, + CC_ATTR_CONDITION, + CC_ATTR_PRECIPITATION, + CC_ATTR_PRECIPITATION_PROBABILITY, + ], + ) except ( CantConnectException, InvalidAPIKeyException, @@ -202,10 +302,16 @@ class ClimaCellEntity(CoordinatorEntity): """Base ClimaCell Entity.""" def __init__( - self, config_entry: ConfigEntry, coordinator: ClimaCellDataUpdateCoordinator + self, + config_entry: ConfigEntry, + coordinator: ClimaCellDataUpdateCoordinator, + forecast_type: str, + api_version: int, ) -> None: """Initialize ClimaCell Entity.""" super().__init__(coordinator) + self.api_version = api_version + self.forecast_type = forecast_type self._config_entry = config_entry @staticmethod @@ -229,15 +335,23 @@ class ClimaCellEntity(CoordinatorEntity): return items.get("value") + @property + def entity_registry_enabled_default(self) -> bool: + """Return if the entity should be enabled when first added to the entity registry.""" + if self.forecast_type == DEFAULT_FORECAST_TYPE: + return True + + return False + @property def name(self) -> str: """Return the name of the entity.""" - return self._config_entry.data[CONF_NAME] + return f"{self._config_entry.data[CONF_NAME]} - {self.forecast_type.title()}" @property def unique_id(self) -> str: """Return the unique id of the entity.""" - return self._config_entry.unique_id + return f"{self._config_entry.unique_id}_{self.forecast_type}" @property def attribution(self): diff --git a/homeassistant/components/climacell/config_flow.py b/homeassistant/components/climacell/config_flow.py index ebf63abcae4..1457479e62a 100644 --- a/homeassistant/components/climacell/config_flow.py +++ b/homeassistant/components/climacell/config_flow.py @@ -4,23 +4,36 @@ from __future__ import annotations import logging from typing import Any -from pyclimacell import ClimaCell -from pyclimacell.const import REALTIME +from pyclimacell import ClimaCellV3 from pyclimacell.exceptions import ( CantConnectException, InvalidAPIKeyException, RateLimitedException, ) +from pyclimacell.pyclimacell import ClimaCellV4 import voluptuous as vol from homeassistant import config_entries, core -from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME +from homeassistant.const import ( + CONF_API_KEY, + CONF_API_VERSION, + CONF_LATITUDE, + CONF_LONGITUDE, + CONF_NAME, +) from homeassistant.core import callback from homeassistant.helpers.aiohttp_client import async_get_clientsession import homeassistant.helpers.config_validation as cv from homeassistant.helpers.typing import HomeAssistantType -from .const import CONF_TIMESTEP, DEFAULT_NAME, DEFAULT_TIMESTEP, DOMAIN +from .const import ( + CC_ATTR_TEMPERATURE, + CC_V3_ATTR_TEMPERATURE, + CONF_TIMESTEP, + DEFAULT_NAME, + DEFAULT_TIMESTEP, + DOMAIN, +) _LOGGER = logging.getLogger(__name__) @@ -43,6 +56,7 @@ def _get_config_schema( CONF_NAME, default=input_dict.get(CONF_NAME, DEFAULT_NAME) ): str, vol.Required(CONF_API_KEY, default=input_dict.get(CONF_API_KEY)): str, + vol.Required(CONF_API_VERSION, default=4): vol.In([3, 4]), vol.Inclusive( CONF_LATITUDE, "location", @@ -85,7 +99,7 @@ class ClimaCellOptionsConfigFlow(config_entries.OptionsFlow): vol.Required( CONF_TIMESTEP, default=self._config_entry.options.get(CONF_TIMESTEP, DEFAULT_TIMESTEP), - ): vol.All(vol.Coerce(int), vol.Range(min=1, max=60)), + ): vol.In([1, 5, 15, 30]), } return self.async_show_form( @@ -119,12 +133,18 @@ class ClimaCellConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): self._abort_if_unique_id_configured() try: - await ClimaCell( + if user_input[CONF_API_VERSION] == 3: + api_class = ClimaCellV3 + field = CC_V3_ATTR_TEMPERATURE + else: + api_class = ClimaCellV4 + field = CC_ATTR_TEMPERATURE + await api_class( user_input[CONF_API_KEY], str(user_input.get(CONF_LATITUDE, self.hass.config.latitude)), str(user_input.get(CONF_LONGITUDE, self.hass.config.longitude)), session=async_get_clientsession(self.hass), - ).realtime(ClimaCell.first_field(REALTIME)) + ).realtime([field]) return self.async_create_entry( title=user_input[CONF_NAME], data=user_input diff --git a/homeassistant/components/climacell/const.py b/homeassistant/components/climacell/const.py index f2d0a596121..01d85dcc161 100644 --- a/homeassistant/components/climacell/const.py +++ b/homeassistant/components/climacell/const.py @@ -1,4 +1,5 @@ """Constants for the ClimaCell integration.""" +from pyclimacell.const import DAILY, HOURLY, NOWCAST, WeatherCode from homeassistant.components.weather import ( ATTR_CONDITION_CLEAR_NIGHT, @@ -16,15 +17,8 @@ from homeassistant.components.weather import ( ) CONF_TIMESTEP = "timestep" - -DAILY = "daily" -HOURLY = "hourly" -NOWCAST = "nowcast" FORECAST_TYPES = [DAILY, HOURLY, NOWCAST] -CURRENT = "current" -FORECASTS = "forecasts" - DEFAULT_NAME = "ClimaCell" DEFAULT_TIMESTEP = 15 DEFAULT_FORECAST_TYPE = DAILY @@ -33,7 +27,58 @@ ATTRIBUTION = "Powered by ClimaCell" MAX_REQUESTS_PER_DAY = 1000 +CLEAR_CONDITIONS = {"night": ATTR_CONDITION_CLEAR_NIGHT, "day": ATTR_CONDITION_SUNNY} + +MAX_FORECASTS = { + DAILY: 14, + HOURLY: 24, + NOWCAST: 30, +} + +# V4 constants CONDITIONS = { + WeatherCode.WIND: ATTR_CONDITION_WINDY, + WeatherCode.LIGHT_WIND: ATTR_CONDITION_WINDY, + WeatherCode.STRONG_WIND: ATTR_CONDITION_WINDY, + WeatherCode.FREEZING_RAIN: ATTR_CONDITION_SNOWY_RAINY, + WeatherCode.HEAVY_FREEZING_RAIN: ATTR_CONDITION_SNOWY_RAINY, + WeatherCode.LIGHT_FREEZING_RAIN: ATTR_CONDITION_SNOWY_RAINY, + WeatherCode.FREEZING_DRIZZLE: ATTR_CONDITION_SNOWY_RAINY, + WeatherCode.ICE_PELLETS: ATTR_CONDITION_HAIL, + WeatherCode.HEAVY_ICE_PELLETS: ATTR_CONDITION_HAIL, + WeatherCode.LIGHT_ICE_PELLETS: ATTR_CONDITION_HAIL, + WeatherCode.SNOW: ATTR_CONDITION_SNOWY, + WeatherCode.HEAVY_SNOW: ATTR_CONDITION_SNOWY, + WeatherCode.LIGHT_SNOW: ATTR_CONDITION_SNOWY, + WeatherCode.FLURRIES: ATTR_CONDITION_SNOWY, + WeatherCode.THUNDERSTORM: ATTR_CONDITION_LIGHTNING, + WeatherCode.RAIN: ATTR_CONDITION_POURING, + WeatherCode.HEAVY_RAIN: ATTR_CONDITION_RAINY, + WeatherCode.LIGHT_RAIN: ATTR_CONDITION_RAINY, + WeatherCode.DRIZZLE: ATTR_CONDITION_RAINY, + WeatherCode.FOG: ATTR_CONDITION_FOG, + WeatherCode.LIGHT_FOG: ATTR_CONDITION_FOG, + WeatherCode.CLOUDY: ATTR_CONDITION_CLOUDY, + WeatherCode.MOSTLY_CLOUDY: ATTR_CONDITION_CLOUDY, + WeatherCode.PARTLY_CLOUDY: ATTR_CONDITION_PARTLYCLOUDY, +} + +CC_ATTR_TIMESTAMP = "startTime" +CC_ATTR_TEMPERATURE = "temperature" +CC_ATTR_TEMPERATURE_HIGH = "temperatureMax" +CC_ATTR_TEMPERATURE_LOW = "temperatureMin" +CC_ATTR_PRESSURE = "pressureSeaLevel" +CC_ATTR_HUMIDITY = "humidity" +CC_ATTR_WIND_SPEED = "windSpeed" +CC_ATTR_WIND_DIRECTION = "windDirection" +CC_ATTR_OZONE = "pollutantO3" +CC_ATTR_CONDITION = "weatherCode" +CC_ATTR_VISIBILITY = "visibility" +CC_ATTR_PRECIPITATION = "precipitationIntensityAvg" +CC_ATTR_PRECIPITATION_PROBABILITY = "precipitationProbability" + +# V3 constants +CONDITIONS_V3 = { "breezy": ATTR_CONDITION_WINDY, "freezing_rain_heavy": ATTR_CONDITION_SNOWY_RAINY, "freezing_rain": ATTR_CONDITION_SNOWY_RAINY, @@ -58,24 +103,17 @@ CONDITIONS = { "partly_cloudy": ATTR_CONDITION_PARTLYCLOUDY, } -CLEAR_CONDITIONS = {"night": ATTR_CONDITION_CLEAR_NIGHT, "day": ATTR_CONDITION_SUNNY} - -CC_ATTR_TIMESTAMP = "observation_time" -CC_ATTR_TEMPERATURE = "temp" -CC_ATTR_TEMPERATURE_HIGH = "max" -CC_ATTR_TEMPERATURE_LOW = "min" -CC_ATTR_PRESSURE = "baro_pressure" -CC_ATTR_HUMIDITY = "humidity" -CC_ATTR_WIND_SPEED = "wind_speed" -CC_ATTR_WIND_DIRECTION = "wind_direction" -CC_ATTR_OZONE = "o3" -CC_ATTR_CONDITION = "weather_code" -CC_ATTR_VISIBILITY = "visibility" -CC_ATTR_PRECIPITATION = "precipitation" -CC_ATTR_PRECIPITATION_DAILY = "precipitation_accumulation" -CC_ATTR_PRECIPITATION_PROBABILITY = "precipitation_probability" -CC_ATTR_PM_2_5 = "pm25" -CC_ATTR_PM_10 = "pm10" -CC_ATTR_CARBON_MONOXIDE = "co" -CC_ATTR_SULPHUR_DIOXIDE = "so2" -CC_ATTR_NITROGEN_DIOXIDE = "no2" +CC_V3_ATTR_TIMESTAMP = "observation_time" +CC_V3_ATTR_TEMPERATURE = "temp" +CC_V3_ATTR_TEMPERATURE_HIGH = "max" +CC_V3_ATTR_TEMPERATURE_LOW = "min" +CC_V3_ATTR_PRESSURE = "baro_pressure" +CC_V3_ATTR_HUMIDITY = "humidity" +CC_V3_ATTR_WIND_SPEED = "wind_speed" +CC_V3_ATTR_WIND_DIRECTION = "wind_direction" +CC_V3_ATTR_OZONE = "o3" +CC_V3_ATTR_CONDITION = "weather_code" +CC_V3_ATTR_VISIBILITY = "visibility" +CC_V3_ATTR_PRECIPITATION = "precipitation" +CC_V3_ATTR_PRECIPITATION_DAILY = "precipitation_accumulation" +CC_V3_ATTR_PRECIPITATION_PROBABILITY = "precipitation_probability" diff --git a/homeassistant/components/climacell/manifest.json b/homeassistant/components/climacell/manifest.json index f410c2275a9..1df0b3613bb 100644 --- a/homeassistant/components/climacell/manifest.json +++ b/homeassistant/components/climacell/manifest.json @@ -3,6 +3,6 @@ "name": "ClimaCell", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/climacell", - "requirements": ["pyclimacell==0.14.0"], + "requirements": ["pyclimacell==0.18.0"], "codeowners": ["@raman325"] } diff --git a/homeassistant/components/climacell/strings.json b/homeassistant/components/climacell/strings.json index be80ac4e506..f4347d254b7 100644 --- a/homeassistant/components/climacell/strings.json +++ b/homeassistant/components/climacell/strings.json @@ -7,6 +7,7 @@ "data": { "name": "[%key:common::config_flow::data::name%]", "api_key": "[%key:common::config_flow::data::api_key%]", + "api_version": "API Version", "latitude": "[%key:common::config_flow::data::latitude%]", "longitude": "[%key:common::config_flow::data::longitude%]" } @@ -25,8 +26,7 @@ "title": "Update [%key:component::climacell::title%] Options", "description": "If you choose to enable the `nowcast` forecast entity, you can configure the number of minutes between each forecast. The number of forecasts provided depends on the number of minutes chosen between forecasts.", "data": { - "timestep": "Min. Between NowCast Forecasts", - "forecast_types": "Forecast Type(s)" + "timestep": "Min. Between NowCast Forecasts" } } } diff --git a/homeassistant/components/climacell/weather.py b/homeassistant/components/climacell/weather.py index b9da5431dd0..012f987171e 100644 --- a/homeassistant/components/climacell/weather.py +++ b/homeassistant/components/climacell/weather.py @@ -5,6 +5,8 @@ from datetime import datetime import logging from typing import Any, Callable +from pyclimacell.const import CURRENT, DAILY, FORECASTS, HOURLY, NOWCAST, WeatherCode + from homeassistant.components.weather import ( ATTR_FORECAST_CONDITION, ATTR_FORECAST_PRECIPITATION, @@ -18,6 +20,7 @@ from homeassistant.components.weather import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( + CONF_API_VERSION, LENGTH_FEET, LENGTH_KILOMETERS, LENGTH_METERS, @@ -33,13 +36,12 @@ from homeassistant.util import dt as dt_util from homeassistant.util.distance import convert as distance_convert from homeassistant.util.pressure import convert as pressure_convert -from . import ClimaCellDataUpdateCoordinator, ClimaCellEntity +from . import ClimaCellEntity from .const import ( CC_ATTR_CONDITION, CC_ATTR_HUMIDITY, CC_ATTR_OZONE, CC_ATTR_PRECIPITATION, - CC_ATTR_PRECIPITATION_DAILY, CC_ATTR_PRECIPITATION_PROBABILITY, CC_ATTR_PRESSURE, CC_ATTR_TEMPERATURE, @@ -49,16 +51,26 @@ from .const import ( CC_ATTR_VISIBILITY, CC_ATTR_WIND_DIRECTION, CC_ATTR_WIND_SPEED, + CC_V3_ATTR_CONDITION, + CC_V3_ATTR_HUMIDITY, + CC_V3_ATTR_OZONE, + CC_V3_ATTR_PRECIPITATION, + CC_V3_ATTR_PRECIPITATION_DAILY, + CC_V3_ATTR_PRECIPITATION_PROBABILITY, + CC_V3_ATTR_PRESSURE, + CC_V3_ATTR_TEMPERATURE, + CC_V3_ATTR_TEMPERATURE_HIGH, + CC_V3_ATTR_TEMPERATURE_LOW, + CC_V3_ATTR_TIMESTAMP, + CC_V3_ATTR_VISIBILITY, + CC_V3_ATTR_WIND_DIRECTION, + CC_V3_ATTR_WIND_SPEED, CLEAR_CONDITIONS, CONDITIONS, + CONDITIONS_V3, CONF_TIMESTEP, - CURRENT, - DAILY, - DEFAULT_FORECAST_TYPE, DOMAIN, - FORECASTS, - HOURLY, - NOWCAST, + MAX_FORECASTS, ) # mypy: allow-untyped-defs, no-check-untyped-defs @@ -66,57 +78,6 @@ from .const import ( _LOGGER = logging.getLogger(__name__) -def _translate_condition(condition: str | None, sun_is_up: bool = True) -> str | None: - """Translate ClimaCell condition into an HA condition.""" - if not condition: - return None - if "clear" in condition.lower(): - if sun_is_up: - return CLEAR_CONDITIONS["day"] - return CLEAR_CONDITIONS["night"] - return CONDITIONS[condition] - - -def _forecast_dict( - hass: HomeAssistantType, - forecast_dt: datetime, - use_datetime: bool, - condition: str, - precipitation: float | None, - precipitation_probability: float | None, - temp: float | None, - temp_low: float | None, - wind_direction: float | None, - wind_speed: float | None, -) -> dict[str, Any]: - """Return formatted Forecast dict from ClimaCell forecast data.""" - if use_datetime: - translated_condition = _translate_condition(condition, is_up(hass, forecast_dt)) - else: - translated_condition = _translate_condition(condition, True) - - if hass.config.units.is_metric: - if precipitation: - precipitation = ( - distance_convert(precipitation / 12, LENGTH_FEET, LENGTH_METERS) * 1000 - ) - if wind_speed: - wind_speed = distance_convert(wind_speed, LENGTH_MILES, LENGTH_KILOMETERS) - - data = { - ATTR_FORECAST_TIME: forecast_dt.isoformat(), - ATTR_FORECAST_CONDITION: translated_condition, - ATTR_FORECAST_PRECIPITATION: precipitation, - ATTR_FORECAST_PRECIPITATION_PROBABILITY: precipitation_probability, - ATTR_FORECAST_TEMP: temp, - ATTR_FORECAST_TEMP_LOW: temp_low, - ATTR_FORECAST_WIND_BEARING: wind_direction, - ATTR_FORECAST_WIND_SPEED: wind_speed, - } - - return {k: v for k, v in data.items() if v is not None} - - async def async_setup_entry( hass: HomeAssistantType, config_entry: ConfigEntry, @@ -124,49 +85,97 @@ async def async_setup_entry( ) -> None: """Set up a config entry.""" coordinator = hass.data[DOMAIN][config_entry.entry_id] + api_version = config_entry.data[CONF_API_VERSION] + api_class = ClimaCellV3WeatherEntity if api_version == 3 else ClimaCellWeatherEntity entities = [ - ClimaCellWeatherEntity(config_entry, coordinator, forecast_type) + api_class(config_entry, coordinator, forecast_type, api_version) for forecast_type in [DAILY, HOURLY, NOWCAST] ] async_add_entities(entities) -class ClimaCellWeatherEntity(ClimaCellEntity, WeatherEntity): - """Entity that talks to ClimaCell API to retrieve weather data.""" +class BaseClimaCellWeatherEntity(ClimaCellEntity, WeatherEntity): + """Base ClimaCell weather entity.""" - def __init__( + @staticmethod + def _translate_condition( + condition: int | None, sun_is_up: bool = True + ) -> str | None: + """Translate ClimaCell condition into an HA condition.""" + raise NotImplementedError() + + def _forecast_dict( self, - config_entry: ConfigEntry, - coordinator: ClimaCellDataUpdateCoordinator, - forecast_type: str, - ) -> None: - """Initialize ClimaCell weather entity.""" - super().__init__(config_entry, coordinator) - self.forecast_type = forecast_type + forecast_dt: datetime, + use_datetime: bool, + condition: str, + precipitation: float | None, + precipitation_probability: float | None, + temp: float | None, + temp_low: float | None, + wind_direction: float | None, + wind_speed: float | None, + ) -> dict[str, Any]: + """Return formatted Forecast dict from ClimaCell forecast data.""" + if use_datetime: + translated_condition = self._translate_condition( + condition, is_up(self.hass, forecast_dt) + ) + else: + translated_condition = self._translate_condition(condition, True) - @property - def entity_registry_enabled_default(self) -> bool: - """Return if the entity should be enabled when first added to the entity registry.""" - if self.forecast_type == DEFAULT_FORECAST_TYPE: - return True + if self.hass.config.units.is_metric: + if precipitation: + precipitation = ( + distance_convert(precipitation / 12, LENGTH_FEET, LENGTH_METERS) + * 1000 + ) + if wind_speed: + wind_speed = distance_convert( + wind_speed, LENGTH_MILES, LENGTH_KILOMETERS + ) - return False + data = { + ATTR_FORECAST_TIME: forecast_dt.isoformat(), + ATTR_FORECAST_CONDITION: translated_condition, + ATTR_FORECAST_PRECIPITATION: precipitation, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: precipitation_probability, + ATTR_FORECAST_TEMP: temp, + ATTR_FORECAST_TEMP_LOW: temp_low, + ATTR_FORECAST_WIND_BEARING: wind_direction, + ATTR_FORECAST_WIND_SPEED: wind_speed, + } - @property - def name(self) -> str: - """Return the name of the entity.""" - return f"{super().name} - {self.forecast_type.title()}" + return {k: v for k, v in data.items() if v is not None} - @property - def unique_id(self) -> str: - """Return the unique id of the entity.""" - return f"{super().unique_id}_{self.forecast_type}" + +class ClimaCellWeatherEntity(BaseClimaCellWeatherEntity): + """Entity that talks to ClimaCell v4 API to retrieve weather data.""" + + @staticmethod + def _translate_condition( + condition: int | None, sun_is_up: bool = True + ) -> str | None: + """Translate ClimaCell condition into an HA condition.""" + if condition is None: + return None + # We won't guard here, instead we will fail hard + condition = WeatherCode(condition) + if condition in (WeatherCode.CLEAR, WeatherCode.MOSTLY_CLEAR): + if sun_is_up: + return CLEAR_CONDITIONS["day"] + return CLEAR_CONDITIONS["night"] + return CONDITIONS[condition] + + def _get_current_property(self, property_name: str) -> int | str | float | None: + """Get property from current conditions.""" + return self.coordinator.data.get(CURRENT, {}).get(property_name) @property def temperature(self): """Return the platform temperature.""" - return self._get_cc_value(self.coordinator.data[CURRENT], CC_ATTR_TEMPERATURE) + return self._get_current_property(CC_ATTR_TEMPERATURE) @property def temperature_unit(self): @@ -176,7 +185,7 @@ class ClimaCellWeatherEntity(ClimaCellEntity, WeatherEntity): @property def pressure(self): """Return the pressure.""" - pressure = self._get_cc_value(self.coordinator.data[CURRENT], CC_ATTR_PRESSURE) + pressure = self._get_current_property(CC_ATTR_PRESSURE) if self.hass.config.units.is_metric and pressure: return pressure_convert(pressure, PRESSURE_INHG, PRESSURE_HPA) return pressure @@ -184,13 +193,156 @@ class ClimaCellWeatherEntity(ClimaCellEntity, WeatherEntity): @property def humidity(self): """Return the humidity.""" - return self._get_cc_value(self.coordinator.data[CURRENT], CC_ATTR_HUMIDITY) + return self._get_current_property(CC_ATTR_HUMIDITY) + + @property + def wind_speed(self): + """Return the wind speed.""" + wind_speed = self._get_current_property(CC_ATTR_WIND_SPEED) + if self.hass.config.units.is_metric and wind_speed: + return distance_convert(wind_speed, LENGTH_MILES, LENGTH_KILOMETERS) + return wind_speed + + @property + def wind_bearing(self): + """Return the wind bearing.""" + return self._get_current_property(CC_ATTR_WIND_DIRECTION) + + @property + def ozone(self): + """Return the O3 (ozone) level.""" + return self._get_current_property(CC_ATTR_OZONE) + + @property + def condition(self): + """Return the condition.""" + return self._translate_condition( + self._get_current_property(CC_ATTR_CONDITION), + is_up(self.hass), + ) + + @property + def visibility(self): + """Return the visibility.""" + visibility = self._get_current_property(CC_ATTR_VISIBILITY) + if self.hass.config.units.is_metric and visibility: + return distance_convert(visibility, LENGTH_MILES, LENGTH_KILOMETERS) + return visibility + + @property + def forecast(self): + """Return the forecast.""" + # Check if forecasts are available + raw_forecasts = self.coordinator.data.get(FORECASTS, {}).get(self.forecast_type) + if not raw_forecasts: + return None + + forecasts = [] + max_forecasts = MAX_FORECASTS[self.forecast_type] + forecast_count = 0 + + # Set default values (in cases where keys don't exist), None will be + # returned. Override properties per forecast type as needed + for forecast in raw_forecasts: + forecast_dt = dt_util.parse_datetime(forecast[CC_ATTR_TIMESTAMP]) + + # Throw out past data + if forecast_dt.date() < dt_util.utcnow().date(): + continue + + values = forecast["values"] + use_datetime = True + + condition = values.get(CC_ATTR_CONDITION) + precipitation = values.get(CC_ATTR_PRECIPITATION) + precipitation_probability = values.get(CC_ATTR_PRECIPITATION_PROBABILITY) + + temp = values.get(CC_ATTR_TEMPERATURE_HIGH) + temp_low = values.get(CC_ATTR_TEMPERATURE_LOW) + wind_direction = values.get(CC_ATTR_WIND_DIRECTION) + wind_speed = values.get(CC_ATTR_WIND_SPEED) + + if self.forecast_type == DAILY: + use_datetime = False + if precipitation: + precipitation = precipitation * 24 + elif self.forecast_type == NOWCAST: + # Precipitation is forecasted in CONF_TIMESTEP increments but in a + # per hour rate, so value needs to be converted to an amount. + if precipitation: + precipitation = ( + precipitation / 60 * self._config_entry.options[CONF_TIMESTEP] + ) + + forecasts.append( + self._forecast_dict( + forecast_dt, + use_datetime, + condition, + precipitation, + precipitation_probability, + temp, + temp_low, + wind_direction, + wind_speed, + ) + ) + + forecast_count += 1 + if forecast_count == max_forecasts: + break + + return forecasts + + +class ClimaCellV3WeatherEntity(BaseClimaCellWeatherEntity): + """Entity that talks to ClimaCell v3 API to retrieve weather data.""" + + @staticmethod + def _translate_condition( + condition: str | None, sun_is_up: bool = True + ) -> str | None: + """Translate ClimaCell condition into an HA condition.""" + if not condition: + return None + if "clear" in condition.lower(): + if sun_is_up: + return CLEAR_CONDITIONS["day"] + return CLEAR_CONDITIONS["night"] + return CONDITIONS_V3[condition] + + @property + def temperature(self): + """Return the platform temperature.""" + return self._get_cc_value( + self.coordinator.data[CURRENT], CC_V3_ATTR_TEMPERATURE + ) + + @property + def temperature_unit(self): + """Return the unit of measurement.""" + return TEMP_FAHRENHEIT + + @property + def pressure(self): + """Return the pressure.""" + pressure = self._get_cc_value( + self.coordinator.data[CURRENT], CC_V3_ATTR_PRESSURE + ) + if self.hass.config.units.is_metric and pressure: + return pressure_convert(pressure, PRESSURE_INHG, PRESSURE_HPA) + return pressure + + @property + def humidity(self): + """Return the humidity.""" + return self._get_cc_value(self.coordinator.data[CURRENT], CC_V3_ATTR_HUMIDITY) @property def wind_speed(self): """Return the wind speed.""" wind_speed = self._get_cc_value( - self.coordinator.data[CURRENT], CC_ATTR_WIND_SPEED + self.coordinator.data[CURRENT], CC_V3_ATTR_WIND_SPEED ) if self.hass.config.units.is_metric and wind_speed: return distance_convert(wind_speed, LENGTH_MILES, LENGTH_KILOMETERS) @@ -200,19 +352,19 @@ class ClimaCellWeatherEntity(ClimaCellEntity, WeatherEntity): def wind_bearing(self): """Return the wind bearing.""" return self._get_cc_value( - self.coordinator.data[CURRENT], CC_ATTR_WIND_DIRECTION + self.coordinator.data[CURRENT], CC_V3_ATTR_WIND_DIRECTION ) @property def ozone(self): """Return the O3 (ozone) level.""" - return self._get_cc_value(self.coordinator.data[CURRENT], CC_ATTR_OZONE) + return self._get_cc_value(self.coordinator.data[CURRENT], CC_V3_ATTR_OZONE) @property def condition(self): """Return the condition.""" - return _translate_condition( - self._get_cc_value(self.coordinator.data[CURRENT], CC_ATTR_CONDITION), + return self._translate_condition( + self._get_cc_value(self.coordinator.data[CURRENT], CC_V3_ATTR_CONDITION), is_up(self.hass), ) @@ -220,7 +372,7 @@ class ClimaCellWeatherEntity(ClimaCellEntity, WeatherEntity): def visibility(self): """Return the visibility.""" visibility = self._get_cc_value( - self.coordinator.data[CURRENT], CC_ATTR_VISIBILITY + self.coordinator.data[CURRENT], CC_V3_ATTR_VISIBILITY ) if self.hass.config.units.is_metric and visibility: return distance_convert(visibility, LENGTH_MILES, LENGTH_KILOMETERS) @@ -230,46 +382,47 @@ class ClimaCellWeatherEntity(ClimaCellEntity, WeatherEntity): def forecast(self): """Return the forecast.""" # Check if forecasts are available - if not self.coordinator.data[FORECASTS].get(self.forecast_type): + raw_forecasts = self.coordinator.data.get(FORECASTS, {}).get(self.forecast_type) + if not raw_forecasts: return None forecasts = [] # Set default values (in cases where keys don't exist), None will be # returned. Override properties per forecast type as needed - for forecast in self.coordinator.data[FORECASTS][self.forecast_type]: + for forecast in raw_forecasts: forecast_dt = dt_util.parse_datetime( - self._get_cc_value(forecast, CC_ATTR_TIMESTAMP) + self._get_cc_value(forecast, CC_V3_ATTR_TIMESTAMP) ) use_datetime = True - condition = self._get_cc_value(forecast, CC_ATTR_CONDITION) - precipitation = self._get_cc_value(forecast, CC_ATTR_PRECIPITATION) + condition = self._get_cc_value(forecast, CC_V3_ATTR_CONDITION) + precipitation = self._get_cc_value(forecast, CC_V3_ATTR_PRECIPITATION) precipitation_probability = self._get_cc_value( - forecast, CC_ATTR_PRECIPITATION_PROBABILITY + forecast, CC_V3_ATTR_PRECIPITATION_PROBABILITY ) - temp = self._get_cc_value(forecast, CC_ATTR_TEMPERATURE) + temp = self._get_cc_value(forecast, CC_V3_ATTR_TEMPERATURE) temp_low = None - wind_direction = self._get_cc_value(forecast, CC_ATTR_WIND_DIRECTION) - wind_speed = self._get_cc_value(forecast, CC_ATTR_WIND_SPEED) + wind_direction = self._get_cc_value(forecast, CC_V3_ATTR_WIND_DIRECTION) + wind_speed = self._get_cc_value(forecast, CC_V3_ATTR_WIND_SPEED) if self.forecast_type == DAILY: use_datetime = False forecast_dt = dt_util.start_of_local_day(forecast_dt) precipitation = self._get_cc_value( - forecast, CC_ATTR_PRECIPITATION_DAILY + forecast, CC_V3_ATTR_PRECIPITATION_DAILY ) temp = next( ( - self._get_cc_value(item, CC_ATTR_TEMPERATURE_HIGH) - for item in forecast[CC_ATTR_TEMPERATURE] + self._get_cc_value(item, CC_V3_ATTR_TEMPERATURE_HIGH) + for item in forecast[CC_V3_ATTR_TEMPERATURE] if "max" in item ), temp, ) temp_low = next( ( - self._get_cc_value(item, CC_ATTR_TEMPERATURE_LOW) - for item in forecast[CC_ATTR_TEMPERATURE] + self._get_cc_value(item, CC_V3_ATTR_TEMPERATURE_LOW) + for item in forecast[CC_V3_ATTR_TEMPERATURE] if "min" in item ), temp_low, @@ -282,8 +435,7 @@ class ClimaCellWeatherEntity(ClimaCellEntity, WeatherEntity): ) forecasts.append( - _forecast_dict( - self.hass, + self._forecast_dict( forecast_dt, use_datetime, condition, diff --git a/requirements_all.txt b/requirements_all.txt index 22e136f255a..50e2bfc40bb 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1310,7 +1310,7 @@ pychromecast==9.1.1 pycketcasts==1.0.0 # homeassistant.components.climacell -pyclimacell==0.14.0 +pyclimacell==0.18.0 # homeassistant.components.cmus pycmus==0.1.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index d573457b0f5..0dce23f3374 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -702,7 +702,7 @@ pycfdns==1.2.1 pychromecast==9.1.1 # homeassistant.components.climacell -pyclimacell==0.14.0 +pyclimacell==0.18.0 # homeassistant.components.comfoconnect pycomfoconnect==0.4 diff --git a/tests/components/climacell/conftest.py b/tests/components/climacell/conftest.py index 3666243b4b4..d4c77c58879 100644 --- a/tests/components/climacell/conftest.py +++ b/tests/components/climacell/conftest.py @@ -1,8 +1,11 @@ """Configure py.test.""" +import json from unittest.mock import patch import pytest +from tests.common import load_fixture + @pytest.fixture(name="skip_notifications", autouse=True) def skip_notifications_fixture(): @@ -17,7 +20,10 @@ def skip_notifications_fixture(): def climacell_config_flow_connect(): """Mock valid climacell config flow setup.""" with patch( - "homeassistant.components.climacell.config_flow.ClimaCell.realtime", + "homeassistant.components.climacell.config_flow.ClimaCellV3.realtime", + return_value={}, + ), patch( + "homeassistant.components.climacell.config_flow.ClimaCellV4.realtime", return_value={}, ): yield @@ -27,16 +33,19 @@ def climacell_config_flow_connect(): def climacell_config_entry_update_fixture(): """Mock valid climacell config entry setup.""" with patch( - "homeassistant.components.climacell.ClimaCell.realtime", - return_value={}, + "homeassistant.components.climacell.ClimaCellV3.realtime", + return_value=json.loads(load_fixture("climacell/v3_realtime.json")), ), patch( - "homeassistant.components.climacell.ClimaCell.forecast_hourly", - return_value=[], + "homeassistant.components.climacell.ClimaCellV3.forecast_hourly", + return_value=json.loads(load_fixture("climacell/v3_forecast_hourly.json")), ), patch( - "homeassistant.components.climacell.ClimaCell.forecast_daily", - return_value=[], + "homeassistant.components.climacell.ClimaCellV3.forecast_daily", + return_value=json.loads(load_fixture("climacell/v3_forecast_daily.json")), ), patch( - "homeassistant.components.climacell.ClimaCell.forecast_nowcast", - return_value=[], + "homeassistant.components.climacell.ClimaCellV3.forecast_nowcast", + return_value=json.loads(load_fixture("climacell/v3_forecast_nowcast.json")), + ), patch( + "homeassistant.components.climacell.ClimaCellV4.realtime_and_all_forecasts", + return_value=json.loads(load_fixture("climacell/v4.json")), ): yield diff --git a/tests/components/climacell/const.py b/tests/components/climacell/const.py index ada0ebd1eb5..be933ecde29 100644 --- a/tests/components/climacell/const.py +++ b/tests/components/climacell/const.py @@ -1,9 +1,38 @@ """Constants for climacell tests.""" -from homeassistant.const import CONF_API_KEY +from homeassistant.const import ( + CONF_API_KEY, + CONF_API_VERSION, + CONF_LATITUDE, + CONF_LONGITUDE, + CONF_NAME, +) API_KEY = "aa" MIN_CONFIG = { CONF_API_KEY: API_KEY, } + +V1_ENTRY_DATA = { + CONF_NAME: "ClimaCell", + CONF_API_KEY: API_KEY, + CONF_LATITUDE: 80, + CONF_LONGITUDE: 80, +} + +API_V3_ENTRY_DATA = { + CONF_NAME: "ClimaCell", + CONF_API_KEY: API_KEY, + CONF_LATITUDE: 80, + CONF_LONGITUDE: 80, + CONF_API_VERSION: 3, +} + +API_V4_ENTRY_DATA = { + CONF_NAME: "ClimaCell", + CONF_API_KEY: API_KEY, + CONF_LATITUDE: 80, + CONF_LONGITUDE: 80, + CONF_API_VERSION: 4, +} diff --git a/tests/components/climacell/test_config_flow.py b/tests/components/climacell/test_config_flow.py index a34bf6fd0fd..6cd5fb85794 100644 --- a/tests/components/climacell/test_config_flow.py +++ b/tests/components/climacell/test_config_flow.py @@ -21,7 +21,13 @@ from homeassistant.components.climacell.const import ( DOMAIN, ) from homeassistant.config_entries import SOURCE_USER -from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME +from homeassistant.const import ( + CONF_API_KEY, + CONF_API_VERSION, + CONF_LATITUDE, + CONF_LONGITUDE, + CONF_NAME, +) from homeassistant.helpers.typing import HomeAssistantType from .const import API_KEY, MIN_CONFIG @@ -48,6 +54,32 @@ async def test_user_flow_minimum_fields(hass: HomeAssistantType) -> None: assert result["title"] == DEFAULT_NAME assert result["data"][CONF_NAME] == DEFAULT_NAME assert result["data"][CONF_API_KEY] == API_KEY + assert result["data"][CONF_API_VERSION] == 4 + assert result["data"][CONF_LATITUDE] == hass.config.latitude + assert result["data"][CONF_LONGITUDE] == hass.config.longitude + + +async def test_user_flow_v3(hass: HomeAssistantType) -> None: + """Test user config flow with v3 API.""" + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_USER} + ) + assert result["type"] == data_entry_flow.RESULT_TYPE_FORM + assert result["step_id"] == "user" + + data = _get_config_schema(hass, MIN_CONFIG)(MIN_CONFIG) + data[CONF_API_VERSION] = 3 + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + user_input=data, + ) + + assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY + assert result["title"] == DEFAULT_NAME + assert result["data"][CONF_NAME] == DEFAULT_NAME + assert result["data"][CONF_API_KEY] == API_KEY + assert result["data"][CONF_API_VERSION] == 3 assert result["data"][CONF_LATITUDE] == hass.config.latitude assert result["data"][CONF_LONGITUDE] == hass.config.longitude @@ -60,6 +92,7 @@ async def test_user_flow_same_unique_ids(hass: HomeAssistantType) -> None: data=user_input, source=SOURCE_USER, unique_id=_get_unique_id(hass, user_input), + version=2, ).add_to_hass(hass) result = await hass.config_entries.flow.async_init( @@ -75,7 +108,7 @@ async def test_user_flow_same_unique_ids(hass: HomeAssistantType) -> None: async def test_user_flow_cannot_connect(hass: HomeAssistantType) -> None: """Test user config flow when ClimaCell can't connect.""" with patch( - "homeassistant.components.climacell.config_flow.ClimaCell.realtime", + "homeassistant.components.climacell.config_flow.ClimaCellV4.realtime", side_effect=CantConnectException, ): result = await hass.config_entries.flow.async_init( @@ -91,7 +124,7 @@ async def test_user_flow_cannot_connect(hass: HomeAssistantType) -> None: async def test_user_flow_invalid_api(hass: HomeAssistantType) -> None: """Test user config flow when API key is invalid.""" with patch( - "homeassistant.components.climacell.config_flow.ClimaCell.realtime", + "homeassistant.components.climacell.config_flow.ClimaCellV4.realtime", side_effect=InvalidAPIKeyException, ): result = await hass.config_entries.flow.async_init( @@ -107,7 +140,7 @@ async def test_user_flow_invalid_api(hass: HomeAssistantType) -> None: async def test_user_flow_rate_limited(hass: HomeAssistantType) -> None: """Test user config flow when API key is rate limited.""" with patch( - "homeassistant.components.climacell.config_flow.ClimaCell.realtime", + "homeassistant.components.climacell.config_flow.ClimaCellV4.realtime", side_effect=RateLimitedException, ): result = await hass.config_entries.flow.async_init( @@ -123,7 +156,7 @@ async def test_user_flow_rate_limited(hass: HomeAssistantType) -> None: async def test_user_flow_unknown_exception(hass: HomeAssistantType) -> None: """Test user config flow when unknown error occurs.""" with patch( - "homeassistant.components.climacell.config_flow.ClimaCell.realtime", + "homeassistant.components.climacell.config_flow.ClimaCellV4.realtime", side_effect=UnknownException, ): result = await hass.config_entries.flow.async_init( @@ -144,6 +177,7 @@ async def test_options_flow(hass: HomeAssistantType) -> None: data=user_config, source=SOURCE_USER, unique_id=_get_unique_id(hass, user_config), + version=1, ) entry.add_to_hass(hass) diff --git a/tests/components/climacell/test_init.py b/tests/components/climacell/test_init.py index f3d7e490090..33a18d553f3 100644 --- a/tests/components/climacell/test_init.py +++ b/tests/components/climacell/test_init.py @@ -7,11 +7,12 @@ from homeassistant.components.climacell.config_flow import ( _get_config_schema, _get_unique_id, ) -from homeassistant.components.climacell.const import DOMAIN +from homeassistant.components.climacell.const import CONF_TIMESTEP, DOMAIN from homeassistant.components.weather import DOMAIN as WEATHER_DOMAIN +from homeassistant.const import CONF_API_VERSION from homeassistant.helpers.typing import HomeAssistantType -from .const import MIN_CONFIG +from .const import API_V3_ENTRY_DATA, MIN_CONFIG, V1_ENTRY_DATA from tests.common import MockConfigEntry @@ -23,10 +24,12 @@ async def test_load_and_unload( climacell_config_entry_update: pytest.fixture, ) -> None: """Test loading and unloading entry.""" + data = _get_config_schema(hass)(MIN_CONFIG) config_entry = MockConfigEntry( domain=DOMAIN, - data=_get_config_schema(hass)(MIN_CONFIG), - unique_id=_get_unique_id(hass, _get_config_schema(hass)(MIN_CONFIG)), + data=data, + unique_id=_get_unique_id(hass, data), + version=1, ) config_entry.add_to_hass(hass) assert await hass.config_entries.async_setup(config_entry.entry_id) @@ -36,3 +39,53 @@ async def test_load_and_unload( assert await hass.config_entries.async_remove(config_entry.entry_id) await hass.async_block_till_done() assert len(hass.states.async_entity_ids(WEATHER_DOMAIN)) == 0 + + +async def test_v3_load_and_unload( + hass: HomeAssistantType, + climacell_config_entry_update: pytest.fixture, +) -> None: + """Test loading and unloading v3 entry.""" + data = _get_config_schema(hass)(API_V3_ENTRY_DATA) + config_entry = MockConfigEntry( + domain=DOMAIN, + data=data, + unique_id=_get_unique_id(hass, data), + version=1, + ) + config_entry.add_to_hass(hass) + assert await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + assert len(hass.states.async_entity_ids(WEATHER_DOMAIN)) == 1 + + assert await hass.config_entries.async_remove(config_entry.entry_id) + await hass.async_block_till_done() + assert len(hass.states.async_entity_ids(WEATHER_DOMAIN)) == 0 + + +@pytest.mark.parametrize( + "old_timestep, new_timestep", [(2, 1), (7, 5), (20, 15), (21, 30)] +) +async def test_migrate_timestep( + hass: HomeAssistantType, + climacell_config_entry_update: pytest.fixture, + old_timestep: int, + new_timestep: int, +) -> None: + """Test migration to standardized timestep.""" + config_entry = MockConfigEntry( + domain=DOMAIN, + data=V1_ENTRY_DATA, + options={CONF_TIMESTEP: old_timestep}, + unique_id=_get_unique_id(hass, V1_ENTRY_DATA), + version=1, + ) + config_entry.add_to_hass(hass) + assert await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + assert config_entry.version == 1 + assert ( + CONF_API_VERSION in config_entry.data + and config_entry.data[CONF_API_VERSION] == 3 + ) + assert config_entry.options[CONF_TIMESTEP] == new_timestep diff --git a/tests/components/climacell/test_weather.py b/tests/components/climacell/test_weather.py new file mode 100644 index 00000000000..c49ad8b3c48 --- /dev/null +++ b/tests/components/climacell/test_weather.py @@ -0,0 +1,382 @@ +"""Tests for Climacell weather entity.""" +from datetime import datetime +import logging +from typing import Any, Dict +from unittest.mock import patch + +import pytest +import pytz + +from homeassistant.components.climacell.config_flow import ( + _get_config_schema, + _get_unique_id, +) +from homeassistant.components.climacell.const import ATTRIBUTION, DOMAIN +from homeassistant.components.weather import ( + ATTR_CONDITION_CLOUDY, + ATTR_CONDITION_RAINY, + ATTR_CONDITION_SNOWY, + ATTR_CONDITION_SUNNY, + ATTR_FORECAST, + ATTR_FORECAST_CONDITION, + ATTR_FORECAST_PRECIPITATION, + ATTR_FORECAST_PRECIPITATION_PROBABILITY, + ATTR_FORECAST_TEMP, + ATTR_FORECAST_TEMP_LOW, + ATTR_FORECAST_TIME, + ATTR_FORECAST_WIND_BEARING, + ATTR_FORECAST_WIND_SPEED, + ATTR_WEATHER_HUMIDITY, + ATTR_WEATHER_OZONE, + ATTR_WEATHER_PRESSURE, + ATTR_WEATHER_TEMPERATURE, + ATTR_WEATHER_VISIBILITY, + ATTR_WEATHER_WIND_BEARING, + ATTR_WEATHER_WIND_SPEED, + DOMAIN as WEATHER_DOMAIN, +) +from homeassistant.const import ATTR_ATTRIBUTION, ATTR_FRIENDLY_NAME +from homeassistant.core import State +from homeassistant.helpers.entity_registry import async_get +from homeassistant.helpers.typing import HomeAssistantType + +from .const import API_V3_ENTRY_DATA, API_V4_ENTRY_DATA + +from tests.common import MockConfigEntry + +_LOGGER = logging.getLogger(__name__) + + +async def _enable_entity(hass: HomeAssistantType, entity_name: str) -> None: + """Enable disabled entity.""" + ent_reg = async_get(hass) + entry = ent_reg.async_get(entity_name) + updated_entry = ent_reg.async_update_entity( + entry.entity_id, **{"disabled_by": None} + ) + assert updated_entry != entry + assert updated_entry.disabled is False + + +async def _setup(hass: HomeAssistantType, config: Dict[str, Any]) -> State: + """Set up entry and return entity state.""" + with patch( + "homeassistant.util.dt.utcnow", + return_value=datetime(2021, 3, 6, 23, 59, 59, tzinfo=pytz.UTC), + ): + data = _get_config_schema(hass)(config) + config_entry = MockConfigEntry( + domain=DOMAIN, + data=data, + unique_id=_get_unique_id(hass, data), + version=1, + ) + config_entry.add_to_hass(hass) + assert await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + await _enable_entity(hass, "weather.climacell_hourly") + await _enable_entity(hass, "weather.climacell_nowcast") + await hass.async_block_till_done() + assert len(hass.states.async_entity_ids(WEATHER_DOMAIN)) == 3 + + return hass.states.get("weather.climacell_daily") + + +async def test_v3_weather( + hass: HomeAssistantType, + climacell_config_entry_update: pytest.fixture, +) -> None: + """Test v3 weather data.""" + weather_state = await _setup(hass, API_V3_ENTRY_DATA) + assert weather_state.state == ATTR_CONDITION_SUNNY + assert weather_state.attributes[ATTR_ATTRIBUTION] == ATTRIBUTION + assert weather_state.attributes[ATTR_FORECAST] == [ + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_SUNNY, + ATTR_FORECAST_TIME: "2021-03-07T00:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 0, + ATTR_FORECAST_TEMP: 7, + ATTR_FORECAST_TEMP_LOW: -5, + }, + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_CLOUDY, + ATTR_FORECAST_TIME: "2021-03-08T00:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 0, + ATTR_FORECAST_TEMP: 10, + ATTR_FORECAST_TEMP_LOW: -4, + }, + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_CLOUDY, + ATTR_FORECAST_TIME: "2021-03-09T00:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 0, + ATTR_FORECAST_TEMP: 19, + ATTR_FORECAST_TEMP_LOW: 0, + }, + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_CLOUDY, + ATTR_FORECAST_TIME: "2021-03-10T00:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 0, + ATTR_FORECAST_TEMP: 18, + ATTR_FORECAST_TEMP_LOW: 3, + }, + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_CLOUDY, + ATTR_FORECAST_TIME: "2021-03-11T00:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 5, + ATTR_FORECAST_TEMP: 20, + ATTR_FORECAST_TEMP_LOW: 9, + }, + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_CLOUDY, + ATTR_FORECAST_TIME: "2021-03-12T00:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0.04572, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 25, + ATTR_FORECAST_TEMP: 20, + ATTR_FORECAST_TEMP_LOW: 12, + }, + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_CLOUDY, + ATTR_FORECAST_TIME: "2021-03-13T00:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 25, + ATTR_FORECAST_TEMP: 16, + ATTR_FORECAST_TEMP_LOW: 7, + }, + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_RAINY, + ATTR_FORECAST_TIME: "2021-03-14T00:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 1.07442, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 75, + ATTR_FORECAST_TEMP: 6, + ATTR_FORECAST_TEMP_LOW: 3, + }, + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_SNOWY, + ATTR_FORECAST_TIME: "2021-03-15T00:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 7.305040000000001, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 95, + ATTR_FORECAST_TEMP: 1, + ATTR_FORECAST_TEMP_LOW: 0, + }, + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_CLOUDY, + ATTR_FORECAST_TIME: "2021-03-16T00:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0.00508, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 5, + ATTR_FORECAST_TEMP: 6, + ATTR_FORECAST_TEMP_LOW: -2, + }, + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_CLOUDY, + ATTR_FORECAST_TIME: "2021-03-17T00:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 0, + ATTR_FORECAST_TEMP: 11, + ATTR_FORECAST_TEMP_LOW: 1, + }, + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_CLOUDY, + ATTR_FORECAST_TIME: "2021-03-18T00:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 5, + ATTR_FORECAST_TEMP: 12, + ATTR_FORECAST_TEMP_LOW: 6, + }, + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_CLOUDY, + ATTR_FORECAST_TIME: "2021-03-19T00:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0.1778, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 45, + ATTR_FORECAST_TEMP: 9, + ATTR_FORECAST_TEMP_LOW: 5, + }, + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_RAINY, + ATTR_FORECAST_TIME: "2021-03-20T00:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 1.2319, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 55, + ATTR_FORECAST_TEMP: 5, + ATTR_FORECAST_TEMP_LOW: 3, + }, + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_CLOUDY, + ATTR_FORECAST_TIME: "2021-03-21T00:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0.043179999999999996, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 20, + ATTR_FORECAST_TEMP: 7, + ATTR_FORECAST_TEMP_LOW: 1, + }, + ] + assert weather_state.attributes[ATTR_FRIENDLY_NAME] == "ClimaCell - Daily" + assert weather_state.attributes[ATTR_WEATHER_HUMIDITY] == 24 + assert weather_state.attributes[ATTR_WEATHER_OZONE] == 52.625 + assert weather_state.attributes[ATTR_WEATHER_PRESSURE] == 1028.124632345 + assert weather_state.attributes[ATTR_WEATHER_TEMPERATURE] == 7 + assert weather_state.attributes[ATTR_WEATHER_VISIBILITY] == 9.994026240000002 + assert weather_state.attributes[ATTR_WEATHER_WIND_BEARING] == 320.31 + assert weather_state.attributes[ATTR_WEATHER_WIND_SPEED] == 14.62893696 + + +async def test_v4_weather( + hass: HomeAssistantType, + climacell_config_entry_update: pytest.fixture, +) -> None: + """Test v4 weather data.""" + weather_state = await _setup(hass, API_V4_ENTRY_DATA) + assert weather_state.state == ATTR_CONDITION_SUNNY + assert weather_state.attributes[ATTR_ATTRIBUTION] == ATTRIBUTION + assert weather_state.attributes[ATTR_FORECAST] == [ + { + ATTR_FORECAST_CONDITION: ATTR_CONDITION_SUNNY, + ATTR_FORECAST_TIME: "2021-03-07T11:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 0, + ATTR_FORECAST_TEMP: 8, + ATTR_FORECAST_TEMP_LOW: -3, + ATTR_FORECAST_WIND_BEARING: 239.6, + ATTR_FORECAST_WIND_SPEED: 15.272674560000002, + }, + { + ATTR_FORECAST_CONDITION: "cloudy", + ATTR_FORECAST_TIME: "2021-03-08T11:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 0, + ATTR_FORECAST_TEMP: 10, + ATTR_FORECAST_TEMP_LOW: -3, + ATTR_FORECAST_WIND_BEARING: 262.82, + ATTR_FORECAST_WIND_SPEED: 11.65165056, + }, + { + ATTR_FORECAST_CONDITION: "cloudy", + ATTR_FORECAST_TIME: "2021-03-09T11:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 0, + ATTR_FORECAST_TEMP: 19, + ATTR_FORECAST_TEMP_LOW: 0, + ATTR_FORECAST_WIND_BEARING: 229.3, + ATTR_FORECAST_WIND_SPEED: 11.3458752, + }, + { + ATTR_FORECAST_CONDITION: "cloudy", + ATTR_FORECAST_TIME: "2021-03-10T11:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 0, + ATTR_FORECAST_TEMP: 18, + ATTR_FORECAST_TEMP_LOW: 3, + ATTR_FORECAST_WIND_BEARING: 149.91, + ATTR_FORECAST_WIND_SPEED: 17.123420160000002, + }, + { + ATTR_FORECAST_CONDITION: "cloudy", + ATTR_FORECAST_TIME: "2021-03-11T11:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 0, + ATTR_FORECAST_TEMP: 19, + ATTR_FORECAST_TEMP_LOW: 9, + ATTR_FORECAST_WIND_BEARING: 210.45, + ATTR_FORECAST_WIND_SPEED: 25.250607360000004, + }, + { + ATTR_FORECAST_CONDITION: "rainy", + ATTR_FORECAST_TIME: "2021-03-12T11:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0.12192000000000001, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 25, + ATTR_FORECAST_TEMP: 20, + ATTR_FORECAST_TEMP_LOW: 12, + ATTR_FORECAST_WIND_BEARING: 217.98, + ATTR_FORECAST_WIND_SPEED: 19.794931200000004, + }, + { + ATTR_FORECAST_CONDITION: "cloudy", + ATTR_FORECAST_TIME: "2021-03-13T11:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 25, + ATTR_FORECAST_TEMP: 12, + ATTR_FORECAST_TEMP_LOW: 6, + ATTR_FORECAST_WIND_BEARING: 58.79, + ATTR_FORECAST_WIND_SPEED: 15.642823680000001, + }, + { + ATTR_FORECAST_CONDITION: "snowy", + ATTR_FORECAST_TIME: "2021-03-14T10:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 23.95728, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 95, + ATTR_FORECAST_TEMP: 6, + ATTR_FORECAST_TEMP_LOW: 1, + ATTR_FORECAST_WIND_BEARING: 70.25, + ATTR_FORECAST_WIND_SPEED: 26.15184, + }, + { + ATTR_FORECAST_CONDITION: "snowy", + ATTR_FORECAST_TIME: "2021-03-15T10:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 1.46304, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 55, + ATTR_FORECAST_TEMP: 6, + ATTR_FORECAST_TEMP_LOW: -1, + ATTR_FORECAST_WIND_BEARING: 84.47, + ATTR_FORECAST_WIND_SPEED: 25.57247616, + }, + { + ATTR_FORECAST_CONDITION: "cloudy", + ATTR_FORECAST_TIME: "2021-03-16T10:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 0, + ATTR_FORECAST_TEMP: 6, + ATTR_FORECAST_TEMP_LOW: -2, + ATTR_FORECAST_WIND_BEARING: 103.85, + ATTR_FORECAST_WIND_SPEED: 10.79869824, + }, + { + ATTR_FORECAST_CONDITION: "cloudy", + ATTR_FORECAST_TIME: "2021-03-17T10:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 0, + ATTR_FORECAST_TEMP: 11, + ATTR_FORECAST_TEMP_LOW: 1, + ATTR_FORECAST_WIND_BEARING: 145.41, + ATTR_FORECAST_WIND_SPEED: 11.69993088, + }, + { + ATTR_FORECAST_CONDITION: "cloudy", + ATTR_FORECAST_TIME: "2021-03-18T10:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 0, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 10, + ATTR_FORECAST_TEMP: 12, + ATTR_FORECAST_TEMP_LOW: 5, + ATTR_FORECAST_WIND_BEARING: 62.99, + ATTR_FORECAST_WIND_SPEED: 10.58948352, + }, + { + ATTR_FORECAST_CONDITION: "rainy", + ATTR_FORECAST_TIME: "2021-03-19T10:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 2.92608, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 55, + ATTR_FORECAST_TEMP: 9, + ATTR_FORECAST_TEMP_LOW: 4, + ATTR_FORECAST_WIND_BEARING: 68.54, + ATTR_FORECAST_WIND_SPEED: 22.38597504, + }, + { + ATTR_FORECAST_CONDITION: "snowy", + ATTR_FORECAST_TIME: "2021-03-20T10:00:00+00:00", + ATTR_FORECAST_PRECIPITATION: 1.2192, + ATTR_FORECAST_PRECIPITATION_PROBABILITY: 33.3, + ATTR_FORECAST_TEMP: 5, + ATTR_FORECAST_TEMP_LOW: 2, + ATTR_FORECAST_WIND_BEARING: 56.98, + ATTR_FORECAST_WIND_SPEED: 27.922118400000002, + }, + ] + assert weather_state.attributes[ATTR_FRIENDLY_NAME] == "ClimaCell - Daily" + assert weather_state.attributes[ATTR_WEATHER_HUMIDITY] == 23 + assert weather_state.attributes[ATTR_WEATHER_OZONE] == 46.53 + assert weather_state.attributes[ATTR_WEATHER_PRESSURE] == 1027.7690615000001 + assert weather_state.attributes[ATTR_WEATHER_TEMPERATURE] == 7 + assert weather_state.attributes[ATTR_WEATHER_VISIBILITY] == 13.116153600000002 + assert weather_state.attributes[ATTR_WEATHER_WIND_BEARING] == 315.14 + assert weather_state.attributes[ATTR_WEATHER_WIND_SPEED] == 15.01517952 diff --git a/tests/fixtures/climacell/v3_forecast_daily.json b/tests/fixtures/climacell/v3_forecast_daily.json new file mode 100644 index 00000000000..18f2d77e0cf --- /dev/null +++ b/tests/fixtures/climacell/v3_forecast_daily.json @@ -0,0 +1,992 @@ +[ + { + "temp": [ + { + "observation_time": "2021-03-07T11:00:00Z", + "min": { + "value": 23.47, + "units": "F" + } + }, + { + "observation_time": "2021-03-07T21:00:00Z", + "max": { + "value": 44.88, + "units": "F" + } + } + ], + "precipitation_accumulation": { + "value": 0, + "units": "in" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": [ + { + "observation_time": "2021-03-08T00:00:00Z", + "min": { + "value": 2.58, + "units": "mph" + } + }, + { + "observation_time": "2021-03-07T19:00:00Z", + "max": { + "value": 7.67, + "units": "mph" + } + } + ], + "wind_direction": [ + { + "observation_time": "2021-03-08T00:00:00Z", + "min": { + "value": 72.1, + "units": "degrees" + } + }, + { + "observation_time": "2021-03-07T19:00:00Z", + "max": { + "value": 313.49, + "units": "degrees" + } + } + ], + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-07" + }, + "lat": 38.90694, + "lon": -77.03012 + }, + { + "temp": [ + { + "observation_time": "2021-03-08T11:00:00Z", + "min": { + "value": 24.79, + "units": "F" + } + }, + { + "observation_time": "2021-03-08T21:00:00Z", + "max": { + "value": 49.42, + "units": "F" + } + } + ], + "precipitation_accumulation": { + "value": 0, + "units": "in" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": [ + { + "observation_time": "2021-03-08T22:00:00Z", + "min": { + "value": 1.97, + "units": "mph" + } + }, + { + "observation_time": "2021-03-08T13:00:00Z", + "max": { + "value": 7.24, + "units": "mph" + } + } + ], + "wind_direction": [ + { + "observation_time": "2021-03-08T22:00:00Z", + "min": { + "value": 268.74, + "units": "degrees" + } + }, + { + "observation_time": "2021-03-08T13:00:00Z", + "max": { + "value": 324.8, + "units": "degrees" + } + } + ], + "weather_code": { + "value": "cloudy" + }, + "observation_time": { + "value": "2021-03-08" + }, + "lat": 38.90694, + "lon": -77.03012 + }, + { + "temp": [ + { + "observation_time": "2021-03-09T11:00:00Z", + "min": { + "value": 31.48, + "units": "F" + } + }, + { + "observation_time": "2021-03-09T21:00:00Z", + "max": { + "value": 66.98, + "units": "F" + } + } + ], + "precipitation_accumulation": { + "value": 0, + "units": "in" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": [ + { + "observation_time": "2021-03-09T22:00:00Z", + "min": { + "value": 3.35, + "units": "mph" + } + }, + { + "observation_time": "2021-03-09T19:00:00Z", + "max": { + "value": 7.05, + "units": "mph" + } + } + ], + "wind_direction": [ + { + "observation_time": "2021-03-09T22:00:00Z", + "min": { + "value": 279.37, + "units": "degrees" + } + }, + { + "observation_time": "2021-03-09T19:00:00Z", + "max": { + "value": 253.12, + "units": "degrees" + } + } + ], + "weather_code": { + "value": "mostly_cloudy" + }, + "observation_time": { + "value": "2021-03-09" + }, + "lat": 38.90694, + "lon": -77.03012 + }, + { + "temp": [ + { + "observation_time": "2021-03-10T11:00:00Z", + "min": { + "value": 37.32, + "units": "F" + } + }, + { + "observation_time": "2021-03-10T20:00:00Z", + "max": { + "value": 65.28, + "units": "F" + } + } + ], + "precipitation_accumulation": { + "value": 0, + "units": "in" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": [ + { + "observation_time": "2021-03-10T05:00:00Z", + "min": { + "value": 2.13, + "units": "mph" + } + }, + { + "observation_time": "2021-03-10T21:00:00Z", + "max": { + "value": 9.42, + "units": "mph" + } + } + ], + "wind_direction": [ + { + "observation_time": "2021-03-10T05:00:00Z", + "min": { + "value": 342.01, + "units": "degrees" + } + }, + { + "observation_time": "2021-03-10T21:00:00Z", + "max": { + "value": 193.22, + "units": "degrees" + } + } + ], + "weather_code": { + "value": "cloudy" + }, + "observation_time": { + "value": "2021-03-10" + }, + "lat": 38.90694, + "lon": -77.03012 + }, + { + "temp": [ + { + "observation_time": "2021-03-11T12:00:00Z", + "min": { + "value": 48.69, + "units": "F" + } + }, + { + "observation_time": "2021-03-11T21:00:00Z", + "max": { + "value": 67.37, + "units": "F" + } + } + ], + "precipitation_accumulation": { + "value": 0, + "units": "in" + }, + "precipitation_probability": { + "value": 5, + "units": "%" + }, + "wind_speed": [ + { + "observation_time": "2021-03-11T02:00:00Z", + "min": { + "value": 8.82, + "units": "mph" + } + }, + { + "observation_time": "2021-03-12T01:00:00Z", + "max": { + "value": 14.47, + "units": "mph" + } + } + ], + "wind_direction": [ + { + "observation_time": "2021-03-11T02:00:00Z", + "min": { + "value": 176.84, + "units": "degrees" + } + }, + { + "observation_time": "2021-03-12T01:00:00Z", + "max": { + "value": 210.63, + "units": "degrees" + } + } + ], + "weather_code": { + "value": "cloudy" + }, + "observation_time": { + "value": "2021-03-11" + }, + "lat": 38.90694, + "lon": -77.03012 + }, + { + "temp": [ + { + "observation_time": "2021-03-12T12:00:00Z", + "min": { + "value": 53.83, + "units": "F" + } + }, + { + "observation_time": "2021-03-12T18:00:00Z", + "max": { + "value": 67.91, + "units": "F" + } + } + ], + "precipitation_accumulation": { + "value": 0.0018, + "units": "in" + }, + "precipitation_probability": { + "value": 25, + "units": "%" + }, + "wind_speed": [ + { + "observation_time": "2021-03-13T00:00:00Z", + "min": { + "value": 4.98, + "units": "mph" + } + }, + { + "observation_time": "2021-03-12T02:00:00Z", + "max": { + "value": 15.69, + "units": "mph" + } + } + ], + "wind_direction": [ + { + "observation_time": "2021-03-13T00:00:00Z", + "min": { + "value": 329.35, + "units": "degrees" + } + }, + { + "observation_time": "2021-03-12T02:00:00Z", + "max": { + "value": 211.47, + "units": "degrees" + } + } + ], + "weather_code": { + "value": "cloudy" + }, + "observation_time": { + "value": "2021-03-12" + }, + "lat": 38.90694, + "lon": -77.03012 + }, + { + "temp": [ + { + "observation_time": "2021-03-14T00:00:00Z", + "min": { + "value": 45.48, + "units": "F" + } + }, + { + "observation_time": "2021-03-13T03:00:00Z", + "max": { + "value": 60.42, + "units": "F" + } + } + ], + "precipitation_accumulation": { + "value": 0, + "units": "in" + }, + "precipitation_probability": { + "value": 25, + "units": "%" + }, + "wind_speed": [ + { + "observation_time": "2021-03-13T03:00:00Z", + "min": { + "value": 2.91, + "units": "mph" + } + }, + { + "observation_time": "2021-03-13T21:00:00Z", + "max": { + "value": 9.72, + "units": "mph" + } + } + ], + "wind_direction": [ + { + "observation_time": "2021-03-13T03:00:00Z", + "min": { + "value": 202.04, + "units": "degrees" + } + }, + { + "observation_time": "2021-03-13T21:00:00Z", + "max": { + "value": 64.38, + "units": "degrees" + } + } + ], + "weather_code": { + "value": "cloudy" + }, + "observation_time": { + "value": "2021-03-13" + }, + "lat": 38.90694, + "lon": -77.03012 + }, + { + "temp": [ + { + "observation_time": "2021-03-15T00:00:00Z", + "min": { + "value": 37.81, + "units": "F" + } + }, + { + "observation_time": "2021-03-14T03:00:00Z", + "max": { + "value": 43.58, + "units": "F" + } + } + ], + "precipitation_accumulation": { + "value": 0.0423, + "units": "in" + }, + "precipitation_probability": { + "value": 75, + "units": "%" + }, + "wind_speed": [ + { + "observation_time": "2021-03-14T06:00:00Z", + "min": { + "value": 5.34, + "units": "mph" + } + }, + { + "observation_time": "2021-03-14T21:00:00Z", + "max": { + "value": 16.25, + "units": "mph" + } + } + ], + "wind_direction": [ + { + "observation_time": "2021-03-14T06:00:00Z", + "min": { + "value": 57.52, + "units": "degrees" + } + }, + { + "observation_time": "2021-03-14T21:00:00Z", + "max": { + "value": 83.23, + "units": "degrees" + } + } + ], + "weather_code": { + "value": "rain_light" + }, + "observation_time": { + "value": "2021-03-14" + }, + "lat": 38.90694, + "lon": -77.03012 + }, + { + "temp": [ + { + "observation_time": "2021-03-16T00:00:00Z", + "min": { + "value": 32.31, + "units": "F" + } + }, + { + "observation_time": "2021-03-15T09:00:00Z", + "max": { + "value": 34.21, + "units": "F" + } + } + ], + "precipitation_accumulation": { + "value": 0.2876, + "units": "in" + }, + "precipitation_probability": { + "value": 95, + "units": "%" + }, + "wind_speed": [ + { + "observation_time": "2021-03-16T00:00:00Z", + "min": { + "value": 11.7, + "units": "mph" + } + }, + { + "observation_time": "2021-03-15T18:00:00Z", + "max": { + "value": 15.89, + "units": "mph" + } + } + ], + "wind_direction": [ + { + "observation_time": "2021-03-16T00:00:00Z", + "min": { + "value": 63.67, + "units": "degrees" + } + }, + { + "observation_time": "2021-03-15T18:00:00Z", + "max": { + "value": 59.49, + "units": "degrees" + } + } + ], + "weather_code": { + "value": "snow_heavy" + }, + "observation_time": { + "value": "2021-03-15" + }, + "lat": 38.90694, + "lon": -77.03012 + }, + { + "temp": [ + { + "observation_time": "2021-03-16T12:00:00Z", + "min": { + "value": 29.1, + "units": "F" + } + }, + { + "observation_time": "2021-03-16T21:00:00Z", + "max": { + "value": 43, + "units": "F" + } + } + ], + "precipitation_accumulation": { + "value": 0.0002, + "units": "in" + }, + "precipitation_probability": { + "value": 5, + "units": "%" + }, + "wind_speed": [ + { + "observation_time": "2021-03-16T18:00:00Z", + "min": { + "value": 4.98, + "units": "mph" + } + }, + { + "observation_time": "2021-03-16T03:00:00Z", + "max": { + "value": 9.77, + "units": "mph" + } + } + ], + "wind_direction": [ + { + "observation_time": "2021-03-16T18:00:00Z", + "min": { + "value": 80.47, + "units": "degrees" + } + }, + { + "observation_time": "2021-03-16T03:00:00Z", + "max": { + "value": 58.98, + "units": "degrees" + } + } + ], + "weather_code": { + "value": "cloudy" + }, + "observation_time": { + "value": "2021-03-16" + }, + "lat": 38.90694, + "lon": -77.03012 + }, + { + "temp": [ + { + "observation_time": "2021-03-17T12:00:00Z", + "min": { + "value": 34.32, + "units": "F" + } + }, + { + "observation_time": "2021-03-17T21:00:00Z", + "max": { + "value": 52.4, + "units": "F" + } + } + ], + "precipitation_accumulation": { + "value": 0, + "units": "in" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": [ + { + "observation_time": "2021-03-18T00:00:00Z", + "min": { + "value": 4.49, + "units": "mph" + } + }, + { + "observation_time": "2021-03-17T03:00:00Z", + "max": { + "value": 6.71, + "units": "mph" + } + } + ], + "wind_direction": [ + { + "observation_time": "2021-03-18T00:00:00Z", + "min": { + "value": 116.64, + "units": "degrees" + } + }, + { + "observation_time": "2021-03-17T03:00:00Z", + "max": { + "value": 111.51, + "units": "degrees" + } + } + ], + "weather_code": { + "value": "cloudy" + }, + "observation_time": { + "value": "2021-03-17" + }, + "lat": 38.90694, + "lon": -77.03012 + }, + { + "temp": [ + { + "observation_time": "2021-03-18T12:00:00Z", + "min": { + "value": 41.99, + "units": "F" + } + }, + { + "observation_time": "2021-03-18T21:00:00Z", + "max": { + "value": 54.07, + "units": "F" + } + } + ], + "precipitation_accumulation": { + "value": 0, + "units": "in" + }, + "precipitation_probability": { + "value": 5, + "units": "%" + }, + "wind_speed": [ + { + "observation_time": "2021-03-18T06:00:00Z", + "min": { + "value": 2.77, + "units": "mph" + } + }, + { + "observation_time": "2021-03-18T03:00:00Z", + "max": { + "value": 5.22, + "units": "mph" + } + } + ], + "wind_direction": [ + { + "observation_time": "2021-03-18T06:00:00Z", + "min": { + "value": 119.5, + "units": "degrees" + } + }, + { + "observation_time": "2021-03-18T03:00:00Z", + "max": { + "value": 135.5, + "units": "degrees" + } + } + ], + "weather_code": { + "value": "cloudy" + }, + "observation_time": { + "value": "2021-03-18" + }, + "lat": 38.90694, + "lon": -77.03012 + }, + { + "temp": [ + { + "observation_time": "2021-03-19T12:00:00Z", + "min": { + "value": 40.48, + "units": "F" + } + }, + { + "observation_time": "2021-03-19T18:00:00Z", + "max": { + "value": 48.94, + "units": "F" + } + } + ], + "precipitation_accumulation": { + "value": 0.007, + "units": "in" + }, + "precipitation_probability": { + "value": 45, + "units": "%" + }, + "wind_speed": [ + { + "observation_time": "2021-03-19T03:00:00Z", + "min": { + "value": 5.43, + "units": "mph" + } + }, + { + "observation_time": "2021-03-20T00:00:00Z", + "max": { + "value": 11.1, + "units": "mph" + } + } + ], + "wind_direction": [ + { + "observation_time": "2021-03-19T03:00:00Z", + "min": { + "value": 50.18, + "units": "degrees" + } + }, + { + "observation_time": "2021-03-20T00:00:00Z", + "max": { + "value": 86.96, + "units": "degrees" + } + } + ], + "weather_code": { + "value": "cloudy" + }, + "observation_time": { + "value": "2021-03-19" + }, + "lat": 38.90694, + "lon": -77.03012 + }, + { + "temp": [ + { + "observation_time": "2021-03-21T00:00:00Z", + "min": { + "value": 37.56, + "units": "F" + } + }, + { + "observation_time": "2021-03-20T03:00:00Z", + "max": { + "value": 41.05, + "units": "F" + } + } + ], + "precipitation_accumulation": { + "value": 0.0485, + "units": "in" + }, + "precipitation_probability": { + "value": 55, + "units": "%" + }, + "wind_speed": [ + { + "observation_time": "2021-03-20T03:00:00Z", + "min": { + "value": 10.9, + "units": "mph" + } + }, + { + "observation_time": "2021-03-20T21:00:00Z", + "max": { + "value": 17.35, + "units": "mph" + } + } + ], + "wind_direction": [ + { + "observation_time": "2021-03-20T03:00:00Z", + "min": { + "value": 70.56, + "units": "degrees" + } + }, + { + "observation_time": "2021-03-20T21:00:00Z", + "max": { + "value": 58.55, + "units": "degrees" + } + } + ], + "weather_code": { + "value": "drizzle" + }, + "observation_time": { + "value": "2021-03-20" + }, + "lat": 38.90694, + "lon": -77.03012 + }, + { + "temp": [ + { + "observation_time": "2021-03-21T12:00:00Z", + "min": { + "value": 33.66, + "units": "F" + } + }, + { + "observation_time": "2021-03-21T21:00:00Z", + "max": { + "value": 44.3, + "units": "F" + } + } + ], + "precipitation_accumulation": { + "value": 0.0017, + "units": "in" + }, + "precipitation_probability": { + "value": 20, + "units": "%" + }, + "wind_speed": [ + { + "observation_time": "2021-03-22T00:00:00Z", + "min": { + "value": 8.65, + "units": "mph" + } + }, + { + "observation_time": "2021-03-21T03:00:00Z", + "max": { + "value": 16.53, + "units": "mph" + } + } + ], + "wind_direction": [ + { + "observation_time": "2021-03-22T00:00:00Z", + "min": { + "value": 64.92, + "units": "degrees" + } + }, + { + "observation_time": "2021-03-21T03:00:00Z", + "max": { + "value": 57.74, + "units": "degrees" + } + } + ], + "weather_code": { + "value": "cloudy" + }, + "observation_time": { + "value": "2021-03-21" + }, + "lat": 38.90694, + "lon": -77.03012 + } +] \ No newline at end of file diff --git a/tests/fixtures/climacell/v3_forecast_hourly.json b/tests/fixtures/climacell/v3_forecast_hourly.json new file mode 100644 index 00000000000..a550c7f4302 --- /dev/null +++ b/tests/fixtures/climacell/v3_forecast_hourly.json @@ -0,0 +1,752 @@ +[ + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 42.75, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 8.99, + "units": "mph" + }, + "wind_direction": { + "value": 320.22, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-07T18:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 44.29, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 9.65, + "units": "mph" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-07T19:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 45.3, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 9.28, + "units": "mph" + }, + "wind_direction": { + "value": 322.01, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-07T20:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 45.26, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 9.12, + "units": "mph" + }, + "wind_direction": { + "value": 323.71, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-07T21:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 44.83, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 7.27, + "units": "mph" + }, + "wind_direction": { + "value": 319.88, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-07T22:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 41.7, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 4.37, + "units": "mph" + }, + "wind_direction": { + "value": 320.69, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-07T23:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 38.04, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 5.45, + "units": "mph" + }, + "wind_direction": { + "value": 351.54, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-08T00:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 35.88, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 5.31, + "units": "mph" + }, + "wind_direction": { + "value": 20.6, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-08T01:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 34.34, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 5.78, + "units": "mph" + }, + "wind_direction": { + "value": 11.22, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-08T02:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 33.3, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 5.73, + "units": "mph" + }, + "wind_direction": { + "value": 15.46, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-08T03:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 31.74, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 4.44, + "units": "mph" + }, + "wind_direction": { + "value": 26.07, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-08T04:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 29.98, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 4.33, + "units": "mph" + }, + "wind_direction": { + "value": 23.7, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-08T05:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 27.34, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 4.7, + "units": "mph" + }, + "wind_direction": { + "value": 354.56, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-08T06:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 26.61, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 4.94, + "units": "mph" + }, + "wind_direction": { + "value": 349.63, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-08T07:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 25.96, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 4.61, + "units": "mph" + }, + "wind_direction": { + "value": 336.74, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-08T08:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 25.72, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 4.22, + "units": "mph" + }, + "wind_direction": { + "value": 332.71, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-08T09:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 25.68, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 4.56, + "units": "mph" + }, + "wind_direction": { + "value": 328.58, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-08T10:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 31.02, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 2.8, + "units": "mph" + }, + "wind_direction": { + "value": 322.27, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-08T11:00:00.000Z" + } + }, + { + "lon": -77.03012, + "lat": 38.90694, + "temp": { + "value": 31.04, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 2.82, + "units": "mph" + }, + "wind_direction": { + "value": 325.27, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-08T12:00:00.000Z" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 29.95, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 7.24, + "units": "mph" + }, + "wind_direction": { + "value": 324.8, + "units": "degrees" + }, + "weather_code": { + "value": "mostly_clear" + }, + "observation_time": { + "value": "2021-03-08T13:00:00.000Z" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 34.02, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 6.28, + "units": "mph" + }, + "wind_direction": { + "value": 335.16, + "units": "degrees" + }, + "weather_code": { + "value": "partly_cloudy" + }, + "observation_time": { + "value": "2021-03-08T14:00:00.000Z" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 37.78, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 5.8, + "units": "mph" + }, + "wind_direction": { + "value": 324.49, + "units": "degrees" + }, + "weather_code": { + "value": "cloudy" + }, + "observation_time": { + "value": "2021-03-08T15:00:00.000Z" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 40.57, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 5.5, + "units": "mph" + }, + "wind_direction": { + "value": 310.68, + "units": "degrees" + }, + "weather_code": { + "value": "mostly_cloudy" + }, + "observation_time": { + "value": "2021-03-08T16:00:00.000Z" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 42.83, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 5.47, + "units": "mph" + }, + "wind_direction": { + "value": 304.18, + "units": "degrees" + }, + "weather_code": { + "value": "mostly_clear" + }, + "observation_time": { + "value": "2021-03-08T17:00:00.000Z" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 45.07, + "units": "F" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "precipitation_probability": { + "value": 0, + "units": "%" + }, + "wind_speed": { + "value": 4.88, + "units": "mph" + }, + "wind_direction": { + "value": 301.19, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "observation_time": { + "value": "2021-03-08T18:00:00.000Z" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/climacell/v3_forecast_nowcast.json b/tests/fixtures/climacell/v3_forecast_nowcast.json new file mode 100644 index 00000000000..23372eae0f9 --- /dev/null +++ b/tests/fixtures/climacell/v3_forecast_nowcast.json @@ -0,0 +1,782 @@ +[ + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.14, + "units": "F" + }, + "wind_speed": { + "value": 9.58, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 320.22, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T18:54:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.17, + "units": "F" + }, + "wind_speed": { + "value": 9.59, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 320.22, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T18:55:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.19, + "units": "F" + }, + "wind_speed": { + "value": 9.6, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 320.22, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T18:56:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.22, + "units": "F" + }, + "wind_speed": { + "value": 9.61, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 320.22, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T18:57:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.24, + "units": "F" + }, + "wind_speed": { + "value": 9.62, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 320.22, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T18:58:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.27, + "units": "F" + }, + "wind_speed": { + "value": 9.64, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 320.22, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T18:59:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.29, + "units": "F" + }, + "wind_speed": { + "value": 9.65, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:00:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.31, + "units": "F" + }, + "wind_speed": { + "value": 9.64, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:01:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.33, + "units": "F" + }, + "wind_speed": { + "value": 9.63, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:02:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.34, + "units": "F" + }, + "wind_speed": { + "value": 9.63, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:03:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.36, + "units": "F" + }, + "wind_speed": { + "value": 9.62, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:04:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.38, + "units": "F" + }, + "wind_speed": { + "value": 9.61, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:05:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.4, + "units": "F" + }, + "wind_speed": { + "value": 9.61, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:06:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.41, + "units": "F" + }, + "wind_speed": { + "value": 9.6, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:07:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.43, + "units": "F" + }, + "wind_speed": { + "value": 9.6, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:08:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.45, + "units": "F" + }, + "wind_speed": { + "value": 9.59, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:09:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.46, + "units": "F" + }, + "wind_speed": { + "value": 9.58, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:10:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.48, + "units": "F" + }, + "wind_speed": { + "value": 9.58, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:11:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.5, + "units": "F" + }, + "wind_speed": { + "value": 9.57, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:12:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.51, + "units": "F" + }, + "wind_speed": { + "value": 9.57, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:13:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.53, + "units": "F" + }, + "wind_speed": { + "value": 9.56, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:14:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.55, + "units": "F" + }, + "wind_speed": { + "value": 9.55, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:15:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.56, + "units": "F" + }, + "wind_speed": { + "value": 9.55, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:16:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.58, + "units": "F" + }, + "wind_speed": { + "value": 9.54, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:17:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.6, + "units": "F" + }, + "wind_speed": { + "value": 9.54, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:18:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.61, + "units": "F" + }, + "wind_speed": { + "value": 9.53, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:19:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.63, + "units": "F" + }, + "wind_speed": { + "value": 9.52, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:20:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.65, + "units": "F" + }, + "wind_speed": { + "value": 9.52, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:21:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.66, + "units": "F" + }, + "wind_speed": { + "value": 9.51, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:22:06.493Z" + }, + "weather_code": { + "value": "clear" + } + }, + { + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 44.68, + "units": "F" + }, + "wind_speed": { + "value": 9.51, + "units": "mph" + }, + "precipitation": { + "value": 0, + "units": "in/hr" + }, + "wind_direction": { + "value": 326.14, + "units": "degrees" + }, + "observation_time": { + "value": "2021-03-07T19:23:06.493Z" + }, + "weather_code": { + "value": "clear" + } + } +] \ No newline at end of file diff --git a/tests/fixtures/climacell/v3_realtime.json b/tests/fixtures/climacell/v3_realtime.json new file mode 100644 index 00000000000..8ed05fe5383 --- /dev/null +++ b/tests/fixtures/climacell/v3_realtime.json @@ -0,0 +1,38 @@ +{ + "lat": 38.90694, + "lon": -77.03012, + "temp": { + "value": 43.93, + "units": "F" + }, + "wind_speed": { + "value": 9.09, + "units": "mph" + }, + "baro_pressure": { + "value": 30.3605, + "units": "inHg" + }, + "visibility": { + "value": 6.21, + "units": "mi" + }, + "humidity": { + "value": 24.5, + "units": "%" + }, + "wind_direction": { + "value": 320.31, + "units": "degrees" + }, + "weather_code": { + "value": "clear" + }, + "o3": { + "value": 52.625, + "units": "ppb" + }, + "observation_time": { + "value": "2021-03-07T18:54:06.055Z" + } +} \ No newline at end of file diff --git a/tests/fixtures/climacell/v4.json b/tests/fixtures/climacell/v4.json new file mode 100644 index 00000000000..d667284a4ad --- /dev/null +++ b/tests/fixtures/climacell/v4.json @@ -0,0 +1,2360 @@ +{ + "current": { + "temperature": 44.13, + "humidity": 22.71, + "pressureSeaLevel": 30.35, + "windSpeed": 9.33, + "windDirection": 315.14, + "weatherCode": 1000, + "visibility": 8.15, + "pollutantO3": 46.53 + }, + "forecasts": { + "nowcast": [ + { + "startTime": "2021-03-07T17:48:00Z", + "values": { + "temperatureMin": 44.13, + "temperatureMax": 44.13, + "windSpeed": 9.33, + "windDirection": 315.14, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T17:53:00Z", + "values": { + "temperatureMin": 43.9, + "temperatureMax": 43.9, + "windSpeed": 9.31, + "windDirection": 315.14, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T17:58:00Z", + "values": { + "temperatureMin": 43.68, + "temperatureMax": 43.68, + "windSpeed": 9.28, + "windDirection": 315.14, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T18:03:00Z", + "values": { + "temperatureMin": 43.66, + "temperatureMax": 43.66, + "windSpeed": 9.26, + "windDirection": 315.14, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T18:08:00Z", + "values": { + "temperatureMin": 43.79, + "temperatureMax": 43.79, + "windSpeed": 9.22, + "windDirection": 315.14, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T18:13:00Z", + "values": { + "temperatureMin": 43.92, + "temperatureMax": 43.92, + "windSpeed": 9.17, + "windDirection": 315.14, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T18:18:00Z", + "values": { + "temperatureMin": 44.04, + "temperatureMax": 44.04, + "windSpeed": 9.13, + "windDirection": 315.14, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T18:23:00Z", + "values": { + "temperatureMin": 44.17, + "temperatureMax": 44.17, + "windSpeed": 9.06, + "windDirection": 315.14, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T18:28:00Z", + "values": { + "temperatureMin": 44.31, + "temperatureMax": 44.31, + "windSpeed": 9.02, + "windDirection": 315.14, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T18:33:00Z", + "values": { + "temperatureMin": 44.44, + "temperatureMax": 44.44, + "windSpeed": 8.97, + "windDirection": 321.71, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T18:38:00Z", + "values": { + "temperatureMin": 44.56, + "temperatureMax": 44.56, + "windSpeed": 8.93, + "windDirection": 321.71, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T18:43:00Z", + "values": { + "temperatureMin": 44.69, + "temperatureMax": 44.69, + "windSpeed": 8.88, + "windDirection": 321.71, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T18:48:00Z", + "values": { + "temperatureMin": 44.82, + "temperatureMax": 44.82, + "windSpeed": 8.84, + "windDirection": 321.71, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T18:53:00Z", + "values": { + "temperatureMin": 44.94, + "temperatureMax": 44.94, + "windSpeed": 8.79, + "windDirection": 321.71, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T18:58:00Z", + "values": { + "temperatureMin": 45.07, + "temperatureMax": 45.07, + "windSpeed": 8.75, + "windDirection": 321.71, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T19:03:00Z", + "values": { + "temperatureMin": 45.16, + "temperatureMax": 45.16, + "windSpeed": 8.75, + "windDirection": 321.71, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T19:08:00Z", + "values": { + "temperatureMin": 45.23, + "temperatureMax": 45.23, + "windSpeed": 8.75, + "windDirection": 321.71, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T19:13:00Z", + "values": { + "temperatureMin": 45.28, + "temperatureMax": 45.28, + "windSpeed": 8.77, + "windDirection": 321.71, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T19:18:00Z", + "values": { + "temperatureMin": 45.36, + "temperatureMax": 45.36, + "windSpeed": 8.79, + "windDirection": 321.71, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T19:23:00Z", + "values": { + "temperatureMin": 45.43, + "temperatureMax": 45.43, + "windSpeed": 8.81, + "windDirection": 321.71, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T19:28:00Z", + "values": { + "temperatureMin": 45.5, + "temperatureMax": 45.5, + "windSpeed": 8.81, + "windDirection": 321.71, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T19:33:00Z", + "values": { + "temperatureMin": 45.55, + "temperatureMax": 45.55, + "windSpeed": 8.84, + "windDirection": 323.38, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T19:38:00Z", + "values": { + "temperatureMin": 45.63, + "temperatureMax": 45.63, + "windSpeed": 8.86, + "windDirection": 323.38, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T19:43:00Z", + "values": { + "temperatureMin": 45.7, + "temperatureMax": 45.7, + "windSpeed": 8.88, + "windDirection": 323.38, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T19:48:00Z", + "values": { + "temperatureMin": 45.75, + "temperatureMax": 45.75, + "windSpeed": 8.9, + "windDirection": 323.38, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T19:53:00Z", + "values": { + "temperatureMin": 45.82, + "temperatureMax": 45.82, + "windSpeed": 8.9, + "windDirection": 323.38, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T19:58:00Z", + "values": { + "temperatureMin": 45.9, + "temperatureMax": 45.9, + "windSpeed": 8.93, + "windDirection": 323.38, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T20:03:00Z", + "values": { + "temperatureMin": 45.88, + "temperatureMax": 45.88, + "windSpeed": 8.97, + "windDirection": 323.38, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T20:08:00Z", + "values": { + "temperatureMin": 45.82, + "temperatureMax": 45.82, + "windSpeed": 9.02, + "windDirection": 323.38, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T20:13:00Z", + "values": { + "temperatureMin": 45.75, + "temperatureMax": 45.75, + "windSpeed": 9.06, + "windDirection": 323.38, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T20:18:00Z", + "values": { + "temperatureMin": 45.7, + "temperatureMax": 45.7, + "windSpeed": 9.1, + "windDirection": 323.38, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T20:23:00Z", + "values": { + "temperatureMin": 45.63, + "temperatureMax": 45.63, + "windSpeed": 9.15, + "windDirection": 323.38, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T20:28:00Z", + "values": { + "temperatureMin": 45.57, + "temperatureMax": 45.57, + "windSpeed": 9.19, + "windDirection": 323.38, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T20:33:00Z", + "values": { + "temperatureMin": 45.5, + "temperatureMax": 45.5, + "windSpeed": 9.24, + "windDirection": 318.43, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T20:38:00Z", + "values": { + "temperatureMin": 45.45, + "temperatureMax": 45.45, + "windSpeed": 9.28, + "windDirection": 318.43, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T20:43:00Z", + "values": { + "temperatureMin": 45.39, + "temperatureMax": 45.39, + "windSpeed": 9.33, + "windDirection": 318.43, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T20:48:00Z", + "values": { + "temperatureMin": 45.32, + "temperatureMax": 45.32, + "windSpeed": 9.37, + "windDirection": 318.43, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T20:53:00Z", + "values": { + "temperatureMin": 45.27, + "temperatureMax": 45.27, + "windSpeed": 9.42, + "windDirection": 318.43, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T20:58:00Z", + "values": { + "temperatureMin": 45.19, + "temperatureMax": 45.19, + "windSpeed": 9.46, + "windDirection": 318.43, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T21:03:00Z", + "values": { + "temperatureMin": 45.14, + "temperatureMax": 45.14, + "windSpeed": 9.4, + "windDirection": 318.43, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T21:08:00Z", + "values": { + "temperatureMin": 45.07, + "temperatureMax": 45.07, + "windSpeed": 9.24, + "windDirection": 318.43, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T21:13:00Z", + "values": { + "temperatureMin": 45.01, + "temperatureMax": 45.01, + "windSpeed": 9.08, + "windDirection": 318.43, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T21:18:00Z", + "values": { + "temperatureMin": 44.94, + "temperatureMax": 44.94, + "windSpeed": 8.95, + "windDirection": 318.43, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T21:23:00Z", + "values": { + "temperatureMin": 44.89, + "temperatureMax": 44.89, + "windSpeed": 8.79, + "windDirection": 318.43, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T21:28:00Z", + "values": { + "temperatureMin": 44.82, + "temperatureMax": 44.82, + "windSpeed": 8.63, + "windDirection": 318.43, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T21:33:00Z", + "values": { + "temperatureMin": 44.76, + "temperatureMax": 44.76, + "windSpeed": 8.5, + "windDirection": 320.9, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T21:38:00Z", + "values": { + "temperatureMin": 44.69, + "temperatureMax": 44.69, + "windSpeed": 8.34, + "windDirection": 320.9, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T21:43:00Z", + "values": { + "temperatureMin": 44.64, + "temperatureMax": 44.64, + "windSpeed": 8.19, + "windDirection": 320.9, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T21:48:00Z", + "values": { + "temperatureMin": 44.56, + "temperatureMax": 44.56, + "windSpeed": 8.05, + "windDirection": 320.9, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T21:53:00Z", + "values": { + "temperatureMin": 44.51, + "temperatureMax": 44.51, + "windSpeed": 7.9, + "windDirection": 320.9, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T21:58:00Z", + "values": { + "temperatureMin": 44.44, + "temperatureMax": 44.44, + "windSpeed": 7.74, + "windDirection": 320.9, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T22:03:00Z", + "values": { + "temperatureMin": 44.26, + "temperatureMax": 44.26, + "windSpeed": 7.47, + "windDirection": 320.9, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T22:08:00Z", + "values": { + "temperatureMin": 44.01, + "temperatureMax": 44.01, + "windSpeed": 7.14, + "windDirection": 320.9, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T22:13:00Z", + "values": { + "temperatureMin": 43.74, + "temperatureMax": 43.74, + "windSpeed": 6.78, + "windDirection": 320.9, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T22:18:00Z", + "values": { + "temperatureMin": 43.48, + "temperatureMax": 43.48, + "windSpeed": 6.44, + "windDirection": 320.9, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T22:23:00Z", + "values": { + "temperatureMin": 43.23, + "temperatureMax": 43.23, + "windSpeed": 6.08, + "windDirection": 320.9, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T22:28:00Z", + "values": { + "temperatureMin": 42.98, + "temperatureMax": 42.98, + "windSpeed": 5.75, + "windDirection": 320.9, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T22:33:00Z", + "values": { + "temperatureMin": 42.71, + "temperatureMax": 42.71, + "windSpeed": 5.39, + "windDirection": 322.11, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T22:38:00Z", + "values": { + "temperatureMin": 42.46, + "temperatureMax": 42.46, + "windSpeed": 5.06, + "windDirection": 322.11, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T22:43:00Z", + "values": { + "temperatureMin": 42.21, + "temperatureMax": 42.21, + "windSpeed": 4.7, + "windDirection": 322.11, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T22:48:00Z", + "values": { + "temperatureMin": 41.94, + "temperatureMax": 41.94, + "windSpeed": 4.36, + "windDirection": 322.11, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T22:53:00Z", + "values": { + "temperatureMin": 41.68, + "temperatureMax": 41.68, + "windSpeed": 4, + "windDirection": 322.11, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T22:58:00Z", + "values": { + "temperatureMin": 41.43, + "temperatureMax": 41.43, + "windSpeed": 3.67, + "windDirection": 322.11, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T23:03:00Z", + "values": { + "temperatureMin": 41.16, + "temperatureMax": 41.16, + "windSpeed": 3.6, + "windDirection": 322.11, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T23:08:00Z", + "values": { + "temperatureMin": 40.91, + "temperatureMax": 40.91, + "windSpeed": 3.76, + "windDirection": 322.11, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T23:13:00Z", + "values": { + "temperatureMin": 40.66, + "temperatureMax": 40.66, + "windSpeed": 3.91, + "windDirection": 322.11, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T23:18:00Z", + "values": { + "temperatureMin": 40.41, + "temperatureMax": 40.41, + "windSpeed": 4.05, + "windDirection": 322.11, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T23:23:00Z", + "values": { + "temperatureMin": 40.14, + "temperatureMax": 40.14, + "windSpeed": 4.21, + "windDirection": 322.11, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T23:28:00Z", + "values": { + "temperatureMin": 39.88, + "temperatureMax": 39.88, + "windSpeed": 4.36, + "windDirection": 322.11, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T23:33:00Z", + "values": { + "temperatureMin": 39.63, + "temperatureMax": 39.63, + "windSpeed": 4.5, + "windDirection": 295.94, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T23:38:00Z", + "values": { + "temperatureMin": 39.38, + "temperatureMax": 39.38, + "windSpeed": 4.65, + "windDirection": 295.94, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T23:43:00Z", + "values": { + "temperatureMin": 39.11, + "temperatureMax": 39.11, + "windSpeed": 4.79, + "windDirection": 295.94, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + } + ], + "hourly": [ + { + "startTime": "2021-03-07T17:48:00Z", + "values": { + "temperatureMin": 44.13, + "temperatureMax": 44.13, + "windSpeed": 9.33, + "windDirection": 315.14, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T18:48:00Z", + "values": { + "temperatureMin": 44.82, + "temperatureMax": 44.82, + "windSpeed": 8.84, + "windDirection": 321.71, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T19:48:00Z", + "values": { + "temperatureMin": 45.75, + "temperatureMax": 45.75, + "windSpeed": 8.9, + "windDirection": 323.38, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T20:48:00Z", + "values": { + "temperatureMin": 45.32, + "temperatureMax": 45.32, + "windSpeed": 9.37, + "windDirection": 318.43, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T21:48:00Z", + "values": { + "temperatureMin": 44.56, + "temperatureMax": 44.56, + "windSpeed": 8.05, + "windDirection": 320.9, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T22:48:00Z", + "values": { + "temperatureMin": 41.94, + "temperatureMax": 41.94, + "windSpeed": 4.36, + "windDirection": 322.11, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-07T23:48:00Z", + "values": { + "temperatureMin": 38.86, + "temperatureMax": 38.86, + "windSpeed": 4.94, + "windDirection": 295.94, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T00:48:00Z", + "values": { + "temperatureMin": 36.18, + "temperatureMax": 36.18, + "windSpeed": 5.59, + "windDirection": 11.94, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T01:48:00Z", + "values": { + "temperatureMin": 34.3, + "temperatureMax": 34.3, + "windSpeed": 5.57, + "windDirection": 13.68, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T02:48:00Z", + "values": { + "temperatureMin": 32.88, + "temperatureMax": 32.88, + "windSpeed": 5.41, + "windDirection": 14.93, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T03:48:00Z", + "values": { + "temperatureMin": 31.91, + "temperatureMax": 31.91, + "windSpeed": 4.61, + "windDirection": 26.07, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T04:48:00Z", + "values": { + "temperatureMin": 29.17, + "temperatureMax": 29.17, + "windSpeed": 2.59, + "windDirection": 51.27, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T05:48:00Z", + "values": { + "temperatureMin": 27.37, + "temperatureMax": 27.37, + "windSpeed": 3.31, + "windDirection": 343.25, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T06:48:00Z", + "values": { + "temperatureMin": 26.73, + "temperatureMax": 26.73, + "windSpeed": 4.27, + "windDirection": 341.46, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T07:48:00Z", + "values": { + "temperatureMin": 26.38, + "temperatureMax": 26.38, + "windSpeed": 3.53, + "windDirection": 322.34, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T08:48:00Z", + "values": { + "temperatureMin": 26.15, + "temperatureMax": 26.15, + "windSpeed": 3.65, + "windDirection": 294.69, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T09:48:00Z", + "values": { + "temperatureMin": 30.07, + "temperatureMax": 30.07, + "windSpeed": 3.2, + "windDirection": 325.32, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T10:48:00Z", + "values": { + "temperatureMin": 31.03, + "temperatureMax": 31.03, + "windSpeed": 2.84, + "windDirection": 322.27, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T11:48:00Z", + "values": { + "temperatureMin": 27.23, + "temperatureMax": 27.23, + "windSpeed": 5.59, + "windDirection": 310.14, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T12:48:00Z", + "values": { + "temperatureMin": 29.21, + "temperatureMax": 29.21, + "windSpeed": 7.05, + "windDirection": 324.8, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T13:48:00Z", + "values": { + "temperatureMin": 33.19, + "temperatureMax": 33.19, + "windSpeed": 6.46, + "windDirection": 335.16, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T14:48:00Z", + "values": { + "temperatureMin": 37.02, + "temperatureMax": 37.02, + "windSpeed": 5.88, + "windDirection": 324.49, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T15:48:00Z", + "values": { + "temperatureMin": 40.01, + "temperatureMax": 40.01, + "windSpeed": 5.55, + "windDirection": 310.68, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T16:48:00Z", + "values": { + "temperatureMin": 42.37, + "temperatureMax": 42.37, + "windSpeed": 5.46, + "windDirection": 304.18, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T17:48:00Z", + "values": { + "temperatureMin": 44.62, + "temperatureMax": 44.62, + "windSpeed": 4.99, + "windDirection": 301.19, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T18:48:00Z", + "values": { + "temperatureMin": 46.78, + "temperatureMax": 46.78, + "windSpeed": 4.72, + "windDirection": 295.05, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T19:48:00Z", + "values": { + "temperatureMin": 48.42, + "temperatureMax": 48.42, + "windSpeed": 4.81, + "windDirection": 287.4, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T20:48:00Z", + "values": { + "temperatureMin": 49.28, + "temperatureMax": 49.28, + "windSpeed": 4.74, + "windDirection": 282.48, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T21:48:00Z", + "values": { + "temperatureMin": 48.72, + "temperatureMax": 48.72, + "windSpeed": 2.51, + "windDirection": 268.74, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T22:48:00Z", + "values": { + "temperatureMin": 44.37, + "temperatureMax": 44.37, + "windSpeed": 3.56, + "windDirection": 180.04, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T23:48:00Z", + "values": { + "temperatureMin": 39.9, + "temperatureMax": 39.9, + "windSpeed": 4.68, + "windDirection": 177.89, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T00:48:00Z", + "values": { + "temperatureMin": 37.87, + "temperatureMax": 37.87, + "windSpeed": 5.21, + "windDirection": 197.47, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T01:48:00Z", + "values": { + "temperatureMin": 36.91, + "temperatureMax": 36.91, + "windSpeed": 5.46, + "windDirection": 209.77, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T02:48:00Z", + "values": { + "temperatureMin": 36.64, + "temperatureMax": 36.64, + "windSpeed": 6.11, + "windDirection": 210.14, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T03:48:00Z", + "values": { + "temperatureMin": 36.63, + "temperatureMax": 36.63, + "windSpeed": 6.4, + "windDirection": 216, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T04:48:00Z", + "values": { + "temperatureMin": 36.23, + "temperatureMax": 36.23, + "windSpeed": 6.22, + "windDirection": 223.92, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T05:48:00Z", + "values": { + "temperatureMin": 35.58, + "temperatureMax": 35.58, + "windSpeed": 5.75, + "windDirection": 229.68, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T06:48:00Z", + "values": { + "temperatureMin": 34.68, + "temperatureMax": 34.68, + "windSpeed": 5.21, + "windDirection": 235.24, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T07:48:00Z", + "values": { + "temperatureMin": 33.69, + "temperatureMax": 33.69, + "windSpeed": 4.81, + "windDirection": 237.24, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T08:48:00Z", + "values": { + "temperatureMin": 32.74, + "temperatureMax": 32.74, + "windSpeed": 4.52, + "windDirection": 239.35, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T09:48:00Z", + "values": { + "temperatureMin": 32.05, + "temperatureMax": 32.05, + "windSpeed": 4.32, + "windDirection": 245.68, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T10:48:00Z", + "values": { + "temperatureMin": 31.57, + "temperatureMax": 31.57, + "windSpeed": 4.14, + "windDirection": 248.11, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T11:48:00Z", + "values": { + "temperatureMin": 32.92, + "temperatureMax": 32.92, + "windSpeed": 4.32, + "windDirection": 249.54, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T12:48:00Z", + "values": { + "temperatureMin": 38.5, + "temperatureMax": 38.5, + "windSpeed": 4.7, + "windDirection": 253.3, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T13:48:00Z", + "values": { + "temperatureMin": 46.08, + "temperatureMax": 46.08, + "windSpeed": 4.41, + "windDirection": 258.49, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T14:48:00Z", + "values": { + "temperatureMin": 53.26, + "temperatureMax": 53.26, + "windSpeed": 4.9, + "windDirection": 260.49, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T15:48:00Z", + "values": { + "temperatureMin": 58.15, + "temperatureMax": 58.15, + "windSpeed": 5.55, + "windDirection": 261.29, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T16:48:00Z", + "values": { + "temperatureMin": 61.56, + "temperatureMax": 61.56, + "windSpeed": 6.35, + "windDirection": 264.3, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T17:48:00Z", + "values": { + "temperatureMin": 64, + "temperatureMax": 64, + "windSpeed": 6.6, + "windDirection": 257.54, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T18:48:00Z", + "values": { + "temperatureMin": 65.79, + "temperatureMax": 65.79, + "windSpeed": 6.96, + "windDirection": 253.12, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T19:48:00Z", + "values": { + "temperatureMin": 66.74, + "temperatureMax": 66.74, + "windSpeed": 6.8, + "windDirection": 259.46, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T20:48:00Z", + "values": { + "temperatureMin": 66.96, + "temperatureMax": 66.96, + "windSpeed": 6.33, + "windDirection": 294.25, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T21:48:00Z", + "values": { + "temperatureMin": 64.35, + "temperatureMax": 64.35, + "windSpeed": 3.91, + "windDirection": 279.37, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T22:48:00Z", + "values": { + "temperatureMin": 61.07, + "temperatureMax": 61.07, + "windSpeed": 3.65, + "windDirection": 218.19, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T23:48:00Z", + "values": { + "temperatureMin": 56.3, + "temperatureMax": 56.3, + "windSpeed": 4.09, + "windDirection": 208.3, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T00:48:00Z", + "values": { + "temperatureMin": 53.19, + "temperatureMax": 53.19, + "windSpeed": 4.21, + "windDirection": 216.42, + "weatherCode": 1102, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T01:48:00Z", + "values": { + "temperatureMin": 51.94, + "temperatureMax": 51.94, + "windSpeed": 3.38, + "windDirection": 257.19, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T02:48:00Z", + "values": { + "temperatureMin": 49.82, + "temperatureMax": 49.82, + "windSpeed": 2.71, + "windDirection": 288.85, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T03:48:00Z", + "values": { + "temperatureMin": 48.24, + "temperatureMax": 48.24, + "windSpeed": 2.8, + "windDirection": 334.41, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T04:48:00Z", + "values": { + "temperatureMin": 47.44, + "temperatureMax": 47.44, + "windSpeed": 2.26, + "windDirection": 342.01, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T05:48:00Z", + "values": { + "temperatureMin": 45.59, + "temperatureMax": 45.59, + "windSpeed": 2.35, + "windDirection": 2.43, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T06:48:00Z", + "values": { + "temperatureMin": 43.43, + "temperatureMax": 43.43, + "windSpeed": 2.3, + "windDirection": 336.56, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T07:48:00Z", + "values": { + "temperatureMin": 41.11, + "temperatureMax": 41.11, + "windSpeed": 2.71, + "windDirection": 4.41, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T08:48:00Z", + "values": { + "temperatureMin": 39.58, + "temperatureMax": 39.58, + "windSpeed": 3.4, + "windDirection": 21.26, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T09:48:00Z", + "values": { + "temperatureMin": 39.85, + "temperatureMax": 39.85, + "windSpeed": 3.31, + "windDirection": 22.76, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T10:48:00Z", + "values": { + "temperatureMin": 37.85, + "temperatureMax": 37.85, + "windSpeed": 4.03, + "windDirection": 29.3, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T11:48:00Z", + "values": { + "temperatureMin": 38.97, + "temperatureMax": 38.97, + "windSpeed": 3.15, + "windDirection": 21.82, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T12:48:00Z", + "values": { + "temperatureMin": 44.31, + "temperatureMax": 44.31, + "windSpeed": 3.53, + "windDirection": 14.25, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T13:48:00Z", + "values": { + "temperatureMin": 50.25, + "temperatureMax": 50.25, + "windSpeed": 2.82, + "windDirection": 42.41, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T14:48:00Z", + "values": { + "temperatureMin": 54.97, + "temperatureMax": 54.97, + "windSpeed": 2.53, + "windDirection": 87.81, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T15:48:00Z", + "values": { + "temperatureMin": 58.46, + "temperatureMax": 58.46, + "windSpeed": 3.09, + "windDirection": 125.82, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T16:48:00Z", + "values": { + "temperatureMin": 61.21, + "temperatureMax": 61.21, + "windSpeed": 4.03, + "windDirection": 157.54, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T17:48:00Z", + "values": { + "temperatureMin": 63.36, + "temperatureMax": 63.36, + "windSpeed": 5.21, + "windDirection": 166.66, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T18:48:00Z", + "values": { + "temperatureMin": 64.83, + "temperatureMax": 64.83, + "windSpeed": 6.93, + "windDirection": 189.24, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T19:48:00Z", + "values": { + "temperatureMin": 65.23, + "temperatureMax": 65.23, + "windSpeed": 8.95, + "windDirection": 194.58, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T20:48:00Z", + "values": { + "temperatureMin": 64.98, + "temperatureMax": 64.98, + "windSpeed": 9.4, + "windDirection": 193.22, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T21:48:00Z", + "values": { + "temperatureMin": 64.06, + "temperatureMax": 64.06, + "windSpeed": 8.55, + "windDirection": 186.39, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T22:48:00Z", + "values": { + "temperatureMin": 61.9, + "temperatureMax": 61.9, + "windSpeed": 7.49, + "windDirection": 171.81, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T23:48:00Z", + "values": { + "temperatureMin": 59.4, + "temperatureMax": 59.4, + "windSpeed": 7.54, + "windDirection": 165.51, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T00:48:00Z", + "values": { + "temperatureMin": 57.63, + "temperatureMax": 57.63, + "windSpeed": 8.12, + "windDirection": 171.94, + "weatherCode": 1102, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T01:48:00Z", + "values": { + "temperatureMin": 56.17, + "temperatureMax": 56.17, + "windSpeed": 8.7, + "windDirection": 176.84, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T02:48:00Z", + "values": { + "temperatureMin": 55.36, + "temperatureMax": 55.36, + "windSpeed": 9.42, + "windDirection": 184.14, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T03:48:00Z", + "values": { + "temperatureMin": 54.88, + "temperatureMax": 54.88, + "windSpeed": 10, + "windDirection": 195.54, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T04:48:00Z", + "values": { + "temperatureMin": 54.14, + "temperatureMax": 54.14, + "windSpeed": 10.4, + "windDirection": 200.56, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T05:48:00Z", + "values": { + "temperatureMin": 53.46, + "temperatureMax": 53.46, + "windSpeed": 10.04, + "windDirection": 198.08, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T06:48:00Z", + "values": { + "temperatureMin": 52.11, + "temperatureMax": 52.11, + "windSpeed": 10.02, + "windDirection": 199.54, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T07:48:00Z", + "values": { + "temperatureMin": 51.64, + "temperatureMax": 51.64, + "windSpeed": 10.51, + "windDirection": 202.73, + "weatherCode": 1102, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T08:48:00Z", + "values": { + "temperatureMin": 50.79, + "temperatureMax": 50.79, + "windSpeed": 10.38, + "windDirection": 203.35, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T09:48:00Z", + "values": { + "temperatureMin": 49.93, + "temperatureMax": 49.93, + "windSpeed": 9.51, + "windDirection": 210.36, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T10:48:00Z", + "values": { + "temperatureMin": 49.1, + "temperatureMax": 49.1, + "windSpeed": 8.61, + "windDirection": 210.6, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T11:48:00Z", + "values": { + "temperatureMin": 48.42, + "temperatureMax": 48.42, + "windSpeed": 9.15, + "windDirection": 211.29, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T12:48:00Z", + "values": { + "temperatureMin": 48.9, + "temperatureMax": 48.9, + "windSpeed": 10.25, + "windDirection": 215.59, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T13:48:00Z", + "values": { + "temperatureMin": 50.54, + "temperatureMax": 50.54, + "windSpeed": 10.18, + "windDirection": 215.48, + "weatherCode": 1102, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T14:48:00Z", + "values": { + "temperatureMin": 53.19, + "temperatureMax": 53.19, + "windSpeed": 9.4, + "windDirection": 208.76, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T15:48:00Z", + "values": { + "temperatureMin": 56.19, + "temperatureMax": 56.19, + "windSpeed": 9.73, + "windDirection": 197.59, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T16:48:00Z", + "values": { + "temperatureMin": 59.34, + "temperatureMax": 59.34, + "windSpeed": 10.69, + "windDirection": 204.29, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T17:48:00Z", + "values": { + "temperatureMin": 62.35, + "temperatureMax": 62.35, + "windSpeed": 11.81, + "windDirection": 204.56, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T18:48:00Z", + "values": { + "temperatureMin": 64.6, + "temperatureMax": 64.6, + "windSpeed": 13.09, + "windDirection": 206.85, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T19:48:00Z", + "values": { + "temperatureMin": 65.91, + "temperatureMax": 65.91, + "windSpeed": 13.82, + "windDirection": 204.82, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T20:48:00Z", + "values": { + "temperatureMin": 66.22, + "temperatureMax": 66.22, + "windSpeed": 14.54, + "windDirection": 208.43, + "weatherCode": 1100, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T21:48:00Z", + "values": { + "temperatureMin": 65.46, + "temperatureMax": 65.46, + "windSpeed": 13.2, + "windDirection": 208.3, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T22:48:00Z", + "values": { + "temperatureMin": 64.35, + "temperatureMax": 64.35, + "windSpeed": 12.35, + "windDirection": 208.58, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T23:48:00Z", + "values": { + "temperatureMin": 62.85, + "temperatureMax": 62.85, + "windSpeed": 12.86, + "windDirection": 205.39, + "weatherCode": 1101, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-12T00:48:00Z", + "values": { + "temperatureMin": 61.75, + "temperatureMax": 61.75, + "windSpeed": 14.7, + "windDirection": 209.51, + "weatherCode": 1102, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-12T01:48:00Z", + "values": { + "temperatureMin": 61.2, + "temperatureMax": 61.2, + "windSpeed": 15.57, + "windDirection": 211.47, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-12T02:48:00Z", + "values": { + "temperatureMin": 60.46, + "temperatureMax": 60.46, + "windSpeed": 14.94, + "windDirection": 211.57, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-12T03:48:00Z", + "values": { + "temperatureMin": 59.94, + "temperatureMax": 59.94, + "windSpeed": 14.29, + "windDirection": 208.93, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-12T04:48:00Z", + "values": { + "temperatureMin": 59.52, + "temperatureMax": 59.52, + "windSpeed": 14.36, + "windDirection": 217.91, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + } + ], + "daily": [ + { + "startTime": "2021-03-07T11:00:00Z", + "values": { + "temperatureMin": 26.11, + "temperatureMax": 45.93, + "windSpeed": 9.49, + "windDirection": 239.6, + "weatherCode": 1000, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-08T11:00:00Z", + "values": { + "temperatureMin": 26.28, + "temperatureMax": 49.42, + "windSpeed": 7.24, + "windDirection": 262.82, + "weatherCode": 1102, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-09T11:00:00Z", + "values": { + "temperatureMin": 31.48, + "temperatureMax": 66.98, + "windSpeed": 7.05, + "windDirection": 229.3, + "weatherCode": 1102, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-10T11:00:00Z", + "values": { + "temperatureMin": 37.32, + "temperatureMax": 65.28, + "windSpeed": 10.64, + "windDirection": 149.91, + "weatherCode": 1102, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-11T11:00:00Z", + "values": { + "temperatureMin": 48.29, + "temperatureMax": 66.25, + "windSpeed": 15.69, + "windDirection": 210.45, + "weatherCode": 1102, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-12T11:00:00Z", + "values": { + "temperatureMin": 53.83, + "temperatureMax": 67.91, + "windSpeed": 12.3, + "windDirection": 217.98, + "weatherCode": 4000, + "precipitationIntensityAvg": 0.0002, + "precipitationProbability": 25 + } + }, + { + "startTime": "2021-03-13T11:00:00Z", + "values": { + "temperatureMin": 42.91, + "temperatureMax": 54.48, + "windSpeed": 9.72, + "windDirection": 58.79, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 25 + } + }, + { + "startTime": "2021-03-14T10:00:00Z", + "values": { + "temperatureMin": 33.35, + "temperatureMax": 42.91, + "windSpeed": 16.25, + "windDirection": 70.25, + "weatherCode": 5101, + "precipitationIntensityAvg": 0.0393, + "precipitationProbability": 95 + } + }, + { + "startTime": "2021-03-15T10:00:00Z", + "values": { + "temperatureMin": 29.35, + "temperatureMax": 43.67, + "windSpeed": 15.89, + "windDirection": 84.47, + "weatherCode": 5001, + "precipitationIntensityAvg": 0.0024, + "precipitationProbability": 55 + } + }, + { + "startTime": "2021-03-16T10:00:00Z", + "values": { + "temperatureMin": 29.1, + "temperatureMax": 43, + "windSpeed": 6.71, + "windDirection": 103.85, + "weatherCode": 1102, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-17T10:00:00Z", + "values": { + "temperatureMin": 34.32, + "temperatureMax": 52.4, + "windSpeed": 7.27, + "windDirection": 145.41, + "weatherCode": 1102, + "precipitationIntensityAvg": 0, + "precipitationProbability": 0 + } + }, + { + "startTime": "2021-03-18T10:00:00Z", + "values": { + "temperatureMin": 41.32, + "temperatureMax": 54.07, + "windSpeed": 6.58, + "windDirection": 62.99, + "weatherCode": 1001, + "precipitationIntensityAvg": 0, + "precipitationProbability": 10 + } + }, + { + "startTime": "2021-03-19T10:00:00Z", + "values": { + "temperatureMin": 39.4, + "temperatureMax": 48.94, + "windSpeed": 13.91, + "windDirection": 68.54, + "weatherCode": 4000, + "precipitationIntensityAvg": 0.0048, + "precipitationProbability": 55 + } + }, + { + "startTime": "2021-03-20T10:00:00Z", + "values": { + "temperatureMin": 35.06, + "temperatureMax": 40.12, + "windSpeed": 17.35, + "windDirection": 56.98, + "weatherCode": 5001, + "precipitationIntensityAvg": 0.002, + "precipitationProbability": 33.3 + } + }, + { + "startTime": "2021-03-21T10:00:00Z", + "values": { + "temperatureMin": 33.66, + "temperatureMax": 66.54, + "windSpeed": 15.93, + "windDirection": 82.57, + "weatherCode": 5001, + "precipitationIntensityAvg": 0.0004, + "precipitationProbability": 45 + } + } + ] + } +} \ No newline at end of file