Improve tests for AccuWeather integration (#38621)
* Add more tests * Add tests for sensor platform * Add more tests * More tests * Simplify parsing of attributes * Change Quality scale to platinum * Patch the library in the manual update entity test * Add unsupported condition icon test * Do not patch _async_get_data * Apply suggestions from code review * Update config_flow.py * Apply suggestions from code review * Apply suggestions from code review * Apply suggestions from code review * Update tests/components/accuweather/test_weather.py * Apply suggestions from code review * Add return_value Co-authored-by: Chris Talkington <chris@talkingtontech.com>
This commit is contained in:
parent
ca3842b150
commit
a7e19c8896
9 changed files with 1844 additions and 11 deletions
|
@ -8,10 +8,6 @@ omit =
|
|||
homeassistant/scripts/*.py
|
||||
|
||||
# omit pieces of code that rely on external devices being present
|
||||
homeassistant/components/accuweather/__init__.py
|
||||
homeassistant/components/accuweather/const.py
|
||||
homeassistant/components/accuweather/sensor.py
|
||||
homeassistant/components/accuweather/weather.py
|
||||
homeassistant/components/acer_projector/switch.py
|
||||
homeassistant/components/actiontec/device_tracker.py
|
||||
homeassistant/components/acmeda/__init__.py
|
||||
|
|
|
@ -34,7 +34,7 @@ class AccuWeatherFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
if user_input is not None:
|
||||
websession = async_get_clientsession(self.hass)
|
||||
try:
|
||||
with timeout(10):
|
||||
async with timeout(10):
|
||||
accuweather = AccuWeather(
|
||||
user_input[CONF_API_KEY],
|
||||
websession,
|
||||
|
|
|
@ -4,5 +4,6 @@
|
|||
"documentation": "https://www.home-assistant.io/integrations/accuweather/",
|
||||
"requirements": ["accuweather==0.0.9"],
|
||||
"codeowners": ["@bieniu"],
|
||||
"config_flow": true
|
||||
"config_flow": true,
|
||||
"quality_scale": "platinum"
|
||||
}
|
||||
|
|
|
@ -154,11 +154,7 @@ class AccuWeatherSensor(Entity):
|
|||
def device_state_attributes(self):
|
||||
"""Return the state attributes."""
|
||||
if self.forecast_day is not None:
|
||||
if self.kind == "WindGustDay":
|
||||
self._attrs["direction"] = self.coordinator.data[ATTR_FORECAST][
|
||||
self.forecast_day
|
||||
][self.kind]["Direction"]["English"]
|
||||
elif self.kind == "WindGustNight":
|
||||
if self.kind in ["WindGustDay", "WindGustNight"]:
|
||||
self._attrs["direction"] = self.coordinator.data[ATTR_FORECAST][
|
||||
self.forecast_day
|
||||
][self.kind]["Direction"]["English"]
|
||||
|
|
|
@ -1 +1,48 @@
|
|||
"""Tests for AccuWeather."""
|
||||
import json
|
||||
|
||||
from homeassistant.components.accuweather.const import DOMAIN
|
||||
|
||||
from tests.async_mock import patch
|
||||
from tests.common import MockConfigEntry, load_fixture
|
||||
|
||||
|
||||
async def init_integration(
|
||||
hass, forecast=False, unsupported_icon=False
|
||||
) -> MockConfigEntry:
|
||||
"""Set up the AccuWeather integration in Home Assistant."""
|
||||
options = {}
|
||||
if forecast:
|
||||
options["forecast"] = True
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title="Home",
|
||||
unique_id="0123456",
|
||||
data={
|
||||
"api_key": "32-character-string-1234567890qw",
|
||||
"latitude": 55.55,
|
||||
"longitude": 122.12,
|
||||
"name": "Home",
|
||||
},
|
||||
options=options,
|
||||
)
|
||||
|
||||
current = json.loads(load_fixture("accuweather/current_conditions_data.json"))
|
||||
forecast = json.loads(load_fixture("accuweather/forecast_data.json"))
|
||||
|
||||
if unsupported_icon:
|
||||
current["WeatherIcon"] = 999
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.accuweather.AccuWeather.async_get_current_conditions",
|
||||
return_value=current,
|
||||
), patch(
|
||||
"homeassistant.components.accuweather.AccuWeather.async_get_forecast",
|
||||
return_value=forecast,
|
||||
):
|
||||
entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
return entry
|
||||
|
|
59
tests/components/accuweather/test_init.py
Normal file
59
tests/components/accuweather/test_init.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
"""Test init of AccuWeather integration."""
|
||||
from homeassistant.components.accuweather.const import DOMAIN
|
||||
from homeassistant.config_entries import (
|
||||
ENTRY_STATE_LOADED,
|
||||
ENTRY_STATE_NOT_LOADED,
|
||||
ENTRY_STATE_SETUP_RETRY,
|
||||
)
|
||||
from homeassistant.const import STATE_UNAVAILABLE
|
||||
|
||||
from tests.async_mock import patch
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.components.accuweather import init_integration
|
||||
|
||||
|
||||
async def test_async_setup_entry(hass):
|
||||
"""Test a successful setup entry."""
|
||||
await init_integration(hass)
|
||||
|
||||
state = hass.states.get("weather.home")
|
||||
assert state is not None
|
||||
assert state.state != STATE_UNAVAILABLE
|
||||
assert state.state == "sunny"
|
||||
|
||||
|
||||
async def test_config_not_ready(hass):
|
||||
"""Test for setup failure if connection to AccuWeather is missing."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title="Home",
|
||||
unique_id="0123456",
|
||||
data={
|
||||
"api_key": "32-character-string-1234567890qw",
|
||||
"latitude": 55.55,
|
||||
"longitude": 122.12,
|
||||
"name": "Home",
|
||||
},
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.accuweather.AccuWeather._async_get_data",
|
||||
side_effect=ConnectionError(),
|
||||
):
|
||||
entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
assert entry.state == ENTRY_STATE_SETUP_RETRY
|
||||
|
||||
|
||||
async def test_unload_entry(hass):
|
||||
"""Test successful unload of entry."""
|
||||
entry = await init_integration(hass)
|
||||
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||
assert entry.state == ENTRY_STATE_LOADED
|
||||
|
||||
assert await hass.config_entries.async_unload(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state == ENTRY_STATE_NOT_LOADED
|
||||
assert not hass.data.get(DOMAIN)
|
598
tests/components/accuweather/test_sensor.py
Normal file
598
tests/components/accuweather/test_sensor.py
Normal file
|
@ -0,0 +1,598 @@
|
|||
"""Test sensor of AccuWeather integration."""
|
||||
from datetime import timedelta
|
||||
import json
|
||||
|
||||
from homeassistant.components.accuweather.const import (
|
||||
ATTRIBUTION,
|
||||
CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
DOMAIN,
|
||||
LENGTH_MILIMETERS,
|
||||
)
|
||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||
from homeassistant.const import (
|
||||
ATTR_ATTRIBUTION,
|
||||
ATTR_DEVICE_CLASS,
|
||||
ATTR_ENTITY_ID,
|
||||
ATTR_ICON,
|
||||
ATTR_UNIT_OF_MEASUREMENT,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
LENGTH_METERS,
|
||||
SPEED_KILOMETERS_PER_HOUR,
|
||||
STATE_UNAVAILABLE,
|
||||
TEMP_CELSIUS,
|
||||
TIME_HOURS,
|
||||
UNIT_PERCENTAGE,
|
||||
UV_INDEX,
|
||||
)
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
||||
from tests.async_mock import patch
|
||||
from tests.common import async_fire_time_changed, load_fixture
|
||||
from tests.components.accuweather import init_integration
|
||||
|
||||
|
||||
async def test_sensor_without_forecast(hass):
|
||||
"""Test states of the sensor without forecast."""
|
||||
await init_integration(hass)
|
||||
registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
|
||||
state = hass.states.get("sensor.home_cloud_ceiling")
|
||||
assert state
|
||||
assert state.state == "3200"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:weather-fog"
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == LENGTH_METERS
|
||||
|
||||
entry = registry.async_get("sensor.home_cloud_ceiling")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-ceiling"
|
||||
|
||||
state = hass.states.get("sensor.home_precipitation")
|
||||
assert state
|
||||
assert state.state == "0.0"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == LENGTH_MILIMETERS
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:weather-rainy"
|
||||
assert state.attributes.get("type") is None
|
||||
|
||||
entry = registry.async_get("sensor.home_precipitation")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-precipitation"
|
||||
|
||||
state = hass.states.get("sensor.home_pressure_tendency")
|
||||
assert state
|
||||
assert state.state == "falling"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:gauge"
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == "accuweather__pressure_tendency"
|
||||
|
||||
entry = registry.async_get("sensor.home_pressure_tendency")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-pressuretendency"
|
||||
|
||||
state = hass.states.get("sensor.home_realfeel_temperature")
|
||||
assert state
|
||||
assert state.state == "25.1"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TEMP_CELSIUS
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TEMPERATURE
|
||||
|
||||
entry = registry.async_get("sensor.home_realfeel_temperature")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-realfeeltemperature"
|
||||
|
||||
state = hass.states.get("sensor.home_uv_index")
|
||||
assert state
|
||||
assert state.state == "6"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UV_INDEX
|
||||
assert state.attributes.get("level") == "High"
|
||||
|
||||
entry = registry.async_get("sensor.home_uv_index")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-uvindex"
|
||||
|
||||
|
||||
async def test_sensor_with_forecast(hass):
|
||||
"""Test states of the sensor with forecast."""
|
||||
await init_integration(hass, forecast=True)
|
||||
registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
|
||||
state = hass.states.get("sensor.home_hours_of_sun_0d")
|
||||
assert state
|
||||
assert state.state == "7.2"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:weather-partly-cloudy"
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TIME_HOURS
|
||||
|
||||
entry = registry.async_get("sensor.home_hours_of_sun_0d")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-hoursofsun-0"
|
||||
|
||||
state = hass.states.get("sensor.home_realfeel_temperature_max_0d")
|
||||
assert state
|
||||
assert state.state == "29.8"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TEMP_CELSIUS
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TEMPERATURE
|
||||
|
||||
entry = registry.async_get("sensor.home_realfeel_temperature_max_0d")
|
||||
assert entry
|
||||
|
||||
state = hass.states.get("sensor.home_realfeel_temperature_min_0d")
|
||||
assert state
|
||||
assert state.state == "15.1"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TEMP_CELSIUS
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TEMPERATURE
|
||||
|
||||
entry = registry.async_get("sensor.home_realfeel_temperature_min_0d")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-realfeeltemperaturemin-0"
|
||||
|
||||
state = hass.states.get("sensor.home_thunderstorm_probability_day_0d")
|
||||
assert state
|
||||
assert state.state == "40"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:weather-lightning"
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE
|
||||
|
||||
entry = registry.async_get("sensor.home_thunderstorm_probability_day_0d")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-thunderstormprobabilityday-0"
|
||||
|
||||
state = hass.states.get("sensor.home_thunderstorm_probability_night_0d")
|
||||
assert state
|
||||
assert state.state == "40"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:weather-lightning"
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE
|
||||
|
||||
entry = registry.async_get("sensor.home_thunderstorm_probability_night_0d")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-thunderstormprobabilitynight-0"
|
||||
|
||||
state = hass.states.get("sensor.home_uv_index_0d")
|
||||
assert state
|
||||
assert state.state == "5"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:weather-sunny"
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UV_INDEX
|
||||
assert state.attributes.get("level") == "Moderate"
|
||||
|
||||
entry = registry.async_get("sensor.home_uv_index_0d")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-uvindex-0"
|
||||
|
||||
|
||||
async def test_sensor_disabled(hass):
|
||||
"""Test sensor disabled by default."""
|
||||
await init_integration(hass)
|
||||
registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
|
||||
entry = registry.async_get("sensor.home_apparent_temperature")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-apparenttemperature"
|
||||
assert entry.disabled
|
||||
assert entry.disabled_by == "integration"
|
||||
|
||||
# Test enabling entity
|
||||
updated_entry = registry.async_update_entity(
|
||||
entry.entity_id, **{"disabled_by": None}
|
||||
)
|
||||
|
||||
assert updated_entry != entry
|
||||
assert updated_entry.disabled is False
|
||||
|
||||
|
||||
async def test_sensor_enabled_without_forecast(hass):
|
||||
"""Test enabling an advanced sensor."""
|
||||
registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-apparenttemperature",
|
||||
suggested_object_id="home_apparent_temperature",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-cloudcover",
|
||||
suggested_object_id="home_cloud_cover",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-dewpoint",
|
||||
suggested_object_id="home_dew_point",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-realfeeltemperatureshade",
|
||||
suggested_object_id="home_realfeel_temperature_shade",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-wetbulbtemperature",
|
||||
suggested_object_id="home_wet_bulb_temperature",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-windchilltemperature",
|
||||
suggested_object_id="home_wind_chill_temperature",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-windgust",
|
||||
suggested_object_id="home_wind_gust",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-cloudcoverday-0",
|
||||
suggested_object_id="home_cloud_cover_day_0d",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-cloudcovernight-0",
|
||||
suggested_object_id="home_cloud_cover_night_0d",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-grass-0",
|
||||
suggested_object_id="home_grass_pollen_0d",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-mold-0",
|
||||
suggested_object_id="home_mold_pollen_0d",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-ozone-0",
|
||||
suggested_object_id="home_ozone_0d",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-ragweed-0",
|
||||
suggested_object_id="home_ragweed_pollen_0d",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-realfeeltemperatureshademax-0",
|
||||
suggested_object_id="home_realfeel_temperature_shade_max_0d",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-realfeeltemperatureshademin-0",
|
||||
suggested_object_id="home_realfeel_temperature_shade_min_0d",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-tree-0",
|
||||
suggested_object_id="home_tree_pollen_0d",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-windgustday-0",
|
||||
suggested_object_id="home_wind_gust_day_0d",
|
||||
disabled_by=None,
|
||||
)
|
||||
registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
"0123456-windgustnight-0",
|
||||
suggested_object_id="home_wind_gust_night_0d",
|
||||
disabled_by=None,
|
||||
)
|
||||
|
||||
await init_integration(hass, forecast=True)
|
||||
|
||||
state = hass.states.get("sensor.home_apparent_temperature")
|
||||
assert state
|
||||
assert state.state == "22.8"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TEMP_CELSIUS
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TEMPERATURE
|
||||
|
||||
entry = registry.async_get("sensor.home_apparent_temperature")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-apparenttemperature"
|
||||
|
||||
state = hass.states.get("sensor.home_cloud_cover")
|
||||
assert state
|
||||
assert state.state == "10"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:weather-cloudy"
|
||||
|
||||
entry = registry.async_get("sensor.home_cloud_cover")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-cloudcover"
|
||||
|
||||
state = hass.states.get("sensor.home_dew_point")
|
||||
assert state
|
||||
assert state.state == "16.2"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TEMP_CELSIUS
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TEMPERATURE
|
||||
|
||||
entry = registry.async_get("sensor.home_dew_point")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-dewpoint"
|
||||
|
||||
state = hass.states.get("sensor.home_realfeel_temperature_shade")
|
||||
assert state
|
||||
assert state.state == "21.1"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TEMP_CELSIUS
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TEMPERATURE
|
||||
|
||||
entry = registry.async_get("sensor.home_realfeel_temperature_shade")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-realfeeltemperatureshade"
|
||||
|
||||
state = hass.states.get("sensor.home_wet_bulb_temperature")
|
||||
assert state
|
||||
assert state.state == "18.6"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TEMP_CELSIUS
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TEMPERATURE
|
||||
|
||||
entry = registry.async_get("sensor.home_wet_bulb_temperature")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-wetbulbtemperature"
|
||||
|
||||
state = hass.states.get("sensor.home_wind_chill_temperature")
|
||||
assert state
|
||||
assert state.state == "22.8"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TEMP_CELSIUS
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TEMPERATURE
|
||||
|
||||
entry = registry.async_get("sensor.home_wind_chill_temperature")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-windchilltemperature"
|
||||
|
||||
state = hass.states.get("sensor.home_wind_gust")
|
||||
assert state
|
||||
assert state.state == "20.3"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == SPEED_KILOMETERS_PER_HOUR
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:weather-windy"
|
||||
|
||||
entry = registry.async_get("sensor.home_wind_gust")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-windgust"
|
||||
|
||||
state = hass.states.get("sensor.home_cloud_cover_day_0d")
|
||||
assert state
|
||||
assert state.state == "58"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:weather-cloudy"
|
||||
|
||||
entry = registry.async_get("sensor.home_cloud_cover_day_0d")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-cloudcoverday-0"
|
||||
|
||||
state = hass.states.get("sensor.home_cloud_cover_night_0d")
|
||||
assert state
|
||||
assert state.state == "65"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PERCENTAGE
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:weather-cloudy"
|
||||
|
||||
entry = registry.async_get("sensor.home_cloud_cover_night_0d")
|
||||
assert entry
|
||||
|
||||
state = hass.states.get("sensor.home_grass_pollen_0d")
|
||||
assert state
|
||||
assert state.state == "0"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert (
|
||||
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
|
||||
== CONCENTRATION_PARTS_PER_CUBIC_METER
|
||||
)
|
||||
assert state.attributes.get("level") == "Low"
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:grass"
|
||||
|
||||
entry = registry.async_get("sensor.home_grass_pollen_0d")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-grass-0"
|
||||
|
||||
state = hass.states.get("sensor.home_mold_pollen_0d")
|
||||
assert state
|
||||
assert state.state == "0"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert (
|
||||
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
|
||||
== CONCENTRATION_PARTS_PER_CUBIC_METER
|
||||
)
|
||||
assert state.attributes.get("level") == "Low"
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:blur"
|
||||
|
||||
entry = registry.async_get("sensor.home_mold_pollen_0d")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-mold-0"
|
||||
|
||||
state = hass.states.get("sensor.home_ozone_0d")
|
||||
assert state
|
||||
assert state.state == "32"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get("level") == "Good"
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:vector-triangle"
|
||||
|
||||
entry = registry.async_get("sensor.home_ozone_0d")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-ozone-0"
|
||||
|
||||
state = hass.states.get("sensor.home_ragweed_pollen_0d")
|
||||
assert state
|
||||
assert state.state == "0"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert (
|
||||
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
|
||||
== CONCENTRATION_PARTS_PER_CUBIC_METER
|
||||
)
|
||||
assert state.attributes.get("level") == "Low"
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:sprout"
|
||||
|
||||
entry = registry.async_get("sensor.home_ragweed_pollen_0d")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-ragweed-0"
|
||||
|
||||
state = hass.states.get("sensor.home_realfeel_temperature_shade_max_0d")
|
||||
assert state
|
||||
assert state.state == "28.0"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TEMP_CELSIUS
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TEMPERATURE
|
||||
|
||||
entry = registry.async_get("sensor.home_realfeel_temperature_shade_max_0d")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-realfeeltemperatureshademax-0"
|
||||
|
||||
state = hass.states.get("sensor.home_realfeel_temperature_shade_min_0d")
|
||||
assert state
|
||||
assert state.state == "15.1"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TEMP_CELSIUS
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TEMPERATURE
|
||||
|
||||
entry = registry.async_get("sensor.home_realfeel_temperature_shade_min_0d")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-realfeeltemperatureshademin-0"
|
||||
|
||||
state = hass.states.get("sensor.home_tree_pollen_0d")
|
||||
assert state
|
||||
assert state.state == "0"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert (
|
||||
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
|
||||
== CONCENTRATION_PARTS_PER_CUBIC_METER
|
||||
)
|
||||
assert state.attributes.get("level") == "Low"
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:tree-outline"
|
||||
|
||||
entry = registry.async_get("sensor.home_tree_pollen_0d")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-tree-0"
|
||||
|
||||
state = hass.states.get("sensor.home_wind_gust_day_0d")
|
||||
assert state
|
||||
assert state.state == "29.6"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == SPEED_KILOMETERS_PER_HOUR
|
||||
assert state.attributes.get("direction") == "S"
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:weather-windy"
|
||||
|
||||
entry = registry.async_get("sensor.home_wind_gust_day_0d")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-windgustday-0"
|
||||
|
||||
state = hass.states.get("sensor.home_wind_gust_night_0d")
|
||||
assert state
|
||||
assert state.state == "18.5"
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == SPEED_KILOMETERS_PER_HOUR
|
||||
assert state.attributes.get("direction") == "WSW"
|
||||
assert state.attributes.get(ATTR_ICON) == "mdi:weather-windy"
|
||||
|
||||
entry = registry.async_get("sensor.home_wind_gust_night_0d")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456-windgustnight-0"
|
||||
|
||||
|
||||
async def test_availability(hass):
|
||||
"""Ensure that we mark the entities unavailable correctly when service is offline."""
|
||||
await init_integration(hass)
|
||||
|
||||
state = hass.states.get("sensor.home_cloud_ceiling")
|
||||
assert state
|
||||
assert state.state != STATE_UNAVAILABLE
|
||||
assert state.state == "3200"
|
||||
|
||||
future = utcnow() + timedelta(minutes=60)
|
||||
with patch(
|
||||
"homeassistant.components.accuweather.AccuWeather.async_get_current_conditions",
|
||||
side_effect=ConnectionError(),
|
||||
):
|
||||
async_fire_time_changed(hass, future)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.home_cloud_ceiling")
|
||||
assert state
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
future = utcnow() + timedelta(minutes=120)
|
||||
with patch(
|
||||
"homeassistant.components.accuweather.AccuWeather.async_get_current_conditions",
|
||||
return_value=json.loads(
|
||||
load_fixture("accuweather/current_conditions_data.json")
|
||||
),
|
||||
):
|
||||
async_fire_time_changed(hass, future)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.home_cloud_ceiling")
|
||||
assert state
|
||||
assert state.state != STATE_UNAVAILABLE
|
||||
assert state.state == "3200"
|
||||
|
||||
|
||||
async def test_manual_update_entity(hass):
|
||||
"""Test manual update entity via service homeasasistant/update_entity."""
|
||||
await init_integration(hass, forecast=True)
|
||||
|
||||
await async_setup_component(hass, "homeassistant", {})
|
||||
|
||||
current = json.loads(load_fixture("accuweather/current_conditions_data.json"))
|
||||
forecast = json.loads(load_fixture("accuweather/forecast_data.json"))
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.accuweather.AccuWeather.async_get_current_conditions",
|
||||
return_value=current,
|
||||
) as mock_current, patch(
|
||||
"homeassistant.components.accuweather.AccuWeather.async_get_forecast",
|
||||
return_value=forecast,
|
||||
) as mock_forecast:
|
||||
await hass.services.async_call(
|
||||
"homeassistant",
|
||||
"update_entity",
|
||||
{ATTR_ENTITY_ID: ["sensor.home_cloud_ceiling"]},
|
||||
blocking=True,
|
||||
)
|
||||
assert mock_current.call_count == 1
|
||||
assert mock_forecast.call_count == 1
|
155
tests/components/accuweather/test_weather.py
Normal file
155
tests/components/accuweather/test_weather.py
Normal file
|
@ -0,0 +1,155 @@
|
|||
"""Test weather of AccuWeather integration."""
|
||||
from datetime import timedelta
|
||||
import json
|
||||
|
||||
from homeassistant.components.accuweather.const import ATTRIBUTION
|
||||
from homeassistant.components.weather import (
|
||||
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,
|
||||
)
|
||||
from homeassistant.const import ATTR_ATTRIBUTION, ATTR_ENTITY_ID, STATE_UNAVAILABLE
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
||||
from tests.async_mock import patch
|
||||
from tests.common import async_fire_time_changed, load_fixture
|
||||
from tests.components.accuweather import init_integration
|
||||
|
||||
|
||||
async def test_weather_without_forecast(hass):
|
||||
"""Test states of the weather without forecast."""
|
||||
await init_integration(hass)
|
||||
registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
|
||||
state = hass.states.get("weather.home")
|
||||
assert state
|
||||
assert state.state == "sunny"
|
||||
assert not state.attributes.get(ATTR_FORECAST)
|
||||
assert state.attributes.get(ATTR_WEATHER_HUMIDITY) == 67
|
||||
assert not state.attributes.get(ATTR_WEATHER_OZONE)
|
||||
assert state.attributes.get(ATTR_WEATHER_PRESSURE) == 1012.0
|
||||
assert state.attributes.get(ATTR_WEATHER_TEMPERATURE) == 22.6
|
||||
assert state.attributes.get(ATTR_WEATHER_VISIBILITY) == 16.1
|
||||
assert state.attributes.get(ATTR_WEATHER_WIND_BEARING) == 180
|
||||
assert state.attributes.get(ATTR_WEATHER_WIND_SPEED) == 14.5
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
|
||||
entry = registry.async_get("weather.home")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456"
|
||||
|
||||
|
||||
async def test_weather_with_forecast(hass):
|
||||
"""Test states of the weather with forecast."""
|
||||
await init_integration(hass, forecast=True)
|
||||
registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
|
||||
state = hass.states.get("weather.home")
|
||||
assert state
|
||||
assert state.state == "sunny"
|
||||
assert state.attributes.get(ATTR_WEATHER_HUMIDITY) == 67
|
||||
assert state.attributes.get(ATTR_WEATHER_OZONE) == 32
|
||||
assert state.attributes.get(ATTR_WEATHER_PRESSURE) == 1012.0
|
||||
assert state.attributes.get(ATTR_WEATHER_TEMPERATURE) == 22.6
|
||||
assert state.attributes.get(ATTR_WEATHER_VISIBILITY) == 16.1
|
||||
assert state.attributes.get(ATTR_WEATHER_WIND_BEARING) == 180
|
||||
assert state.attributes.get(ATTR_WEATHER_WIND_SPEED) == 14.5
|
||||
assert state.attributes.get(ATTR_ATTRIBUTION) == ATTRIBUTION
|
||||
forecast = state.attributes.get(ATTR_FORECAST)[0]
|
||||
assert forecast.get(ATTR_FORECAST_CONDITION) == "lightning-rainy"
|
||||
assert forecast.get(ATTR_FORECAST_PRECIPITATION) == 4.8
|
||||
assert forecast.get(ATTR_FORECAST_PRECIPITATION_PROBABILITY) == 58
|
||||
assert forecast.get(ATTR_FORECAST_TEMP) == 29.5
|
||||
assert forecast.get(ATTR_FORECAST_TEMP_LOW) == 15.4
|
||||
assert forecast.get(ATTR_FORECAST_TIME) == "2020-07-26T05:00:00+00:00"
|
||||
assert forecast.get(ATTR_FORECAST_WIND_BEARING) == 166
|
||||
assert forecast.get(ATTR_FORECAST_WIND_SPEED) == 13.0
|
||||
|
||||
entry = registry.async_get("weather.home")
|
||||
assert entry
|
||||
assert entry.unique_id == "0123456"
|
||||
|
||||
|
||||
async def test_availability(hass):
|
||||
"""Ensure that we mark the entities unavailable correctly when service is offline."""
|
||||
await init_integration(hass)
|
||||
|
||||
state = hass.states.get("weather.home")
|
||||
assert state
|
||||
assert state.state != STATE_UNAVAILABLE
|
||||
assert state.state == "sunny"
|
||||
|
||||
future = utcnow() + timedelta(minutes=60)
|
||||
with patch(
|
||||
"homeassistant.components.accuweather.AccuWeather._async_get_data",
|
||||
side_effect=ConnectionError(),
|
||||
):
|
||||
async_fire_time_changed(hass, future)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("weather.home")
|
||||
assert state
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
future = utcnow() + timedelta(minutes=120)
|
||||
with patch(
|
||||
"homeassistant.components.accuweather.AccuWeather.async_get_current_conditions",
|
||||
return_value=json.loads(
|
||||
load_fixture("accuweather/current_conditions_data.json")
|
||||
),
|
||||
):
|
||||
async_fire_time_changed(hass, future)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("weather.home")
|
||||
assert state
|
||||
assert state.state != STATE_UNAVAILABLE
|
||||
assert state.state == "sunny"
|
||||
|
||||
|
||||
async def test_manual_update_entity(hass):
|
||||
"""Test manual update entity via service homeasasistant/update_entity."""
|
||||
await init_integration(hass, forecast=True)
|
||||
|
||||
await async_setup_component(hass, "homeassistant", {})
|
||||
|
||||
current = json.loads(load_fixture("accuweather/current_conditions_data.json"))
|
||||
forecast = json.loads(load_fixture("accuweather/forecast_data.json"))
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.accuweather.AccuWeather.async_get_current_conditions",
|
||||
return_value=current,
|
||||
) as mock_current, patch(
|
||||
"homeassistant.components.accuweather.AccuWeather.async_get_forecast",
|
||||
return_value=forecast,
|
||||
) as mock_forecast:
|
||||
await hass.services.async_call(
|
||||
"homeassistant",
|
||||
"update_entity",
|
||||
{ATTR_ENTITY_ID: ["weather.home"]},
|
||||
blocking=True,
|
||||
)
|
||||
assert mock_current.call_count == 1
|
||||
assert mock_forecast.call_count == 1
|
||||
|
||||
|
||||
async def test_unsupported_condition_icon_data(hass):
|
||||
"""Test with unsupported condition icon data."""
|
||||
await init_integration(hass, forecast=True, unsupported_icon=True)
|
||||
|
||||
state = hass.states.get("weather.home")
|
||||
assert state.attributes.get(ATTR_FORECAST_CONDITION) is None
|
981
tests/fixtures/accuweather/forecast_data.json
vendored
Normal file
981
tests/fixtures/accuweather/forecast_data.json
vendored
Normal file
|
@ -0,0 +1,981 @@
|
|||
[
|
||||
{
|
||||
"Date": "2020-07-26T07:00:00+02:00",
|
||||
"EpochDate": 1595739600,
|
||||
"HoursOfSun": 7.2,
|
||||
"DegreeDaySummary": {
|
||||
"Heating": {
|
||||
"Value": 0.0,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"Cooling": {
|
||||
"Value": 4.0,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
}
|
||||
},
|
||||
"Ozone": {
|
||||
"Value": 32,
|
||||
"Category": "Good",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Grass": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Mold": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Ragweed": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Tree": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"UVIndex": {
|
||||
"Value": 5,
|
||||
"Category": "Moderate",
|
||||
"CategoryValue": 2
|
||||
},
|
||||
"TemperatureMin": {
|
||||
"Value": 15.4,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"TemperatureMax": {
|
||||
"Value": 29.5,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureMin": {
|
||||
"Value": 15.1,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureMax": {
|
||||
"Value": 29.8,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureShadeMin": {
|
||||
"Value": 15.1,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureShadeMax": {
|
||||
"Value": 28.0,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"IconDay": 17,
|
||||
"IconPhraseDay": "Partly sunny w/ t-storms",
|
||||
"HasPrecipitationDay": true,
|
||||
"PrecipitationTypeDay": "Rain",
|
||||
"PrecipitationIntensityDay": "Moderate",
|
||||
"ShortPhraseDay": "A shower and t-storm around",
|
||||
"LongPhraseDay": "Clouds and sunshine with a couple of showers and a thunderstorm around late this afternoon",
|
||||
"PrecipitationProbabilityDay": 60,
|
||||
"ThunderstormProbabilityDay": 40,
|
||||
"RainProbabilityDay": 60,
|
||||
"SnowProbabilityDay": 0,
|
||||
"IceProbabilityDay": 0,
|
||||
"WindDay": {
|
||||
"Speed": {
|
||||
"Value": 13.0,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 166,
|
||||
"Localized": "SSE",
|
||||
"English": "SSE"
|
||||
}
|
||||
},
|
||||
"WindGustDay": {
|
||||
"Speed": {
|
||||
"Value": 29.6,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 178,
|
||||
"Localized": "S",
|
||||
"English": "S"
|
||||
}
|
||||
},
|
||||
"TotalLiquidDay": {
|
||||
"Value": 2.5,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"RainDay": {
|
||||
"Value": 2.5,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"SnowDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "cm",
|
||||
"UnitType": 4
|
||||
},
|
||||
"IceDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"HoursOfPrecipitationDay": 1.0,
|
||||
"HoursOfRainDay": 1.0,
|
||||
"HoursOfSnowDay": 0.0,
|
||||
"HoursOfIceDay": 0.0,
|
||||
"CloudCoverDay": 58,
|
||||
"IconNight": 41,
|
||||
"IconPhraseNight": "Partly cloudy w/ t-storms",
|
||||
"HasPrecipitationNight": true,
|
||||
"PrecipitationTypeNight": "Rain",
|
||||
"PrecipitationIntensityNight": "Moderate",
|
||||
"ShortPhraseNight": "Partly cloudy",
|
||||
"LongPhraseNight": "Partly cloudy",
|
||||
"PrecipitationProbabilityNight": 57,
|
||||
"ThunderstormProbabilityNight": 40,
|
||||
"RainProbabilityNight": 57,
|
||||
"SnowProbabilityNight": 0,
|
||||
"IceProbabilityNight": 0,
|
||||
"WindNight": {
|
||||
"Speed": {
|
||||
"Value": 7.4,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 289,
|
||||
"Localized": "WNW",
|
||||
"English": "WNW"
|
||||
}
|
||||
},
|
||||
"WindGustNight": {
|
||||
"Speed": {
|
||||
"Value": 18.5,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 256,
|
||||
"Localized": "WSW",
|
||||
"English": "WSW"
|
||||
}
|
||||
},
|
||||
"TotalLiquidNight": {
|
||||
"Value": 2.3,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"RainNight": {
|
||||
"Value": 2.3,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"SnowNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "cm",
|
||||
"UnitType": 4
|
||||
},
|
||||
"IceNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"HoursOfPrecipitationNight": 1.0,
|
||||
"HoursOfRainNight": 1.0,
|
||||
"HoursOfSnowNight": 0.0,
|
||||
"HoursOfIceNight": 0.0,
|
||||
"CloudCoverNight": 65
|
||||
},
|
||||
{
|
||||
"Date": "2020-07-27T07:00:00+02:00",
|
||||
"EpochDate": 1595826000,
|
||||
"HoursOfSun": 7.4,
|
||||
"DegreeDaySummary": {
|
||||
"Heating": {
|
||||
"Value": 0.0,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"Cooling": {
|
||||
"Value": 3.0,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
}
|
||||
},
|
||||
"Ozone": {
|
||||
"Value": 39,
|
||||
"Category": "Good",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Grass": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Mold": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Ragweed": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Tree": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"UVIndex": {
|
||||
"Value": 7,
|
||||
"Category": "High",
|
||||
"CategoryValue": 3
|
||||
},
|
||||
"TemperatureMin": {
|
||||
"Value": 15.9,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"TemperatureMax": {
|
||||
"Value": 26.2,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureMin": {
|
||||
"Value": 15.8,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureMax": {
|
||||
"Value": 28.9,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureShadeMin": {
|
||||
"Value": 15.8,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureShadeMax": {
|
||||
"Value": 25.0,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"IconDay": 4,
|
||||
"IconPhraseDay": "Intermittent clouds",
|
||||
"HasPrecipitationDay": false,
|
||||
"ShortPhraseDay": "Clouds and sun",
|
||||
"LongPhraseDay": "Clouds and sun",
|
||||
"PrecipitationProbabilityDay": 25,
|
||||
"ThunderstormProbabilityDay": 24,
|
||||
"RainProbabilityDay": 25,
|
||||
"SnowProbabilityDay": 0,
|
||||
"IceProbabilityDay": 0,
|
||||
"WindDay": {
|
||||
"Speed": {
|
||||
"Value": 9.3,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 297,
|
||||
"Localized": "WNW",
|
||||
"English": "WNW"
|
||||
}
|
||||
},
|
||||
"WindGustDay": {
|
||||
"Speed": {
|
||||
"Value": 14.8,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 317,
|
||||
"Localized": "NW",
|
||||
"English": "NW"
|
||||
}
|
||||
},
|
||||
"TotalLiquidDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"RainDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"SnowDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "cm",
|
||||
"UnitType": 4
|
||||
},
|
||||
"IceDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"HoursOfPrecipitationDay": 0.0,
|
||||
"HoursOfRainDay": 0.0,
|
||||
"HoursOfSnowDay": 0.0,
|
||||
"HoursOfIceDay": 0.0,
|
||||
"CloudCoverDay": 52,
|
||||
"IconNight": 36,
|
||||
"IconPhraseNight": "Intermittent clouds",
|
||||
"HasPrecipitationNight": false,
|
||||
"ShortPhraseNight": "Partly cloudy",
|
||||
"LongPhraseNight": "Partly cloudy",
|
||||
"PrecipitationProbabilityNight": 6,
|
||||
"ThunderstormProbabilityNight": 0,
|
||||
"RainProbabilityNight": 6,
|
||||
"SnowProbabilityNight": 0,
|
||||
"IceProbabilityNight": 0,
|
||||
"WindNight": {
|
||||
"Speed": {
|
||||
"Value": 7.4,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 162,
|
||||
"Localized": "SSE",
|
||||
"English": "SSE"
|
||||
}
|
||||
},
|
||||
"WindGustNight": {
|
||||
"Speed": {
|
||||
"Value": 14.8,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 175,
|
||||
"Localized": "S",
|
||||
"English": "S"
|
||||
}
|
||||
},
|
||||
"TotalLiquidNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"RainNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"SnowNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "cm",
|
||||
"UnitType": 4
|
||||
},
|
||||
"IceNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"HoursOfPrecipitationNight": 0.0,
|
||||
"HoursOfRainNight": 0.0,
|
||||
"HoursOfSnowNight": 0.0,
|
||||
"HoursOfIceNight": 0.0,
|
||||
"CloudCoverNight": 63
|
||||
},
|
||||
{
|
||||
"Date": "2020-07-28T07:00:00+02:00",
|
||||
"EpochDate": 1595912400,
|
||||
"HoursOfSun": 5.7,
|
||||
"DegreeDaySummary": {
|
||||
"Heating": {
|
||||
"Value": 0.0,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"Cooling": {
|
||||
"Value": 6.0,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
}
|
||||
},
|
||||
"Ozone": {
|
||||
"Value": 29,
|
||||
"Category": "Good",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Grass": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Mold": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Ragweed": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Tree": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"UVIndex": {
|
||||
"Value": 7,
|
||||
"Category": "High",
|
||||
"CategoryValue": 3
|
||||
},
|
||||
"TemperatureMin": {
|
||||
"Value": 16.8,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"TemperatureMax": {
|
||||
"Value": 31.7,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureMin": {
|
||||
"Value": 16.7,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureMax": {
|
||||
"Value": 31.6,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureShadeMin": {
|
||||
"Value": 16.7,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureShadeMax": {
|
||||
"Value": 30.0,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"IconDay": 4,
|
||||
"IconPhraseDay": "Intermittent clouds",
|
||||
"HasPrecipitationDay": false,
|
||||
"ShortPhraseDay": "Partly sunny and very warm",
|
||||
"LongPhraseDay": "Very warm with a blend of sun and clouds",
|
||||
"PrecipitationProbabilityDay": 10,
|
||||
"ThunderstormProbabilityDay": 4,
|
||||
"RainProbabilityDay": 10,
|
||||
"SnowProbabilityDay": 0,
|
||||
"IceProbabilityDay": 0,
|
||||
"WindDay": {
|
||||
"Speed": {
|
||||
"Value": 16.7,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 198,
|
||||
"Localized": "SSW",
|
||||
"English": "SSW"
|
||||
}
|
||||
},
|
||||
"WindGustDay": {
|
||||
"Speed": {
|
||||
"Value": 24.1,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 198,
|
||||
"Localized": "SSW",
|
||||
"English": "SSW"
|
||||
}
|
||||
},
|
||||
"TotalLiquidDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"RainDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"SnowDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "cm",
|
||||
"UnitType": 4
|
||||
},
|
||||
"IceDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"HoursOfPrecipitationDay": 0.0,
|
||||
"HoursOfRainDay": 0.0,
|
||||
"HoursOfSnowDay": 0.0,
|
||||
"HoursOfIceDay": 0.0,
|
||||
"CloudCoverDay": 65,
|
||||
"IconNight": 36,
|
||||
"IconPhraseNight": "Intermittent clouds",
|
||||
"HasPrecipitationNight": false,
|
||||
"ShortPhraseNight": "Partly cloudy",
|
||||
"LongPhraseNight": "Partly cloudy",
|
||||
"PrecipitationProbabilityNight": 25,
|
||||
"ThunderstormProbabilityNight": 24,
|
||||
"RainProbabilityNight": 25,
|
||||
"SnowProbabilityNight": 0,
|
||||
"IceProbabilityNight": 0,
|
||||
"WindNight": {
|
||||
"Speed": {
|
||||
"Value": 9.3,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 265,
|
||||
"Localized": "W",
|
||||
"English": "W"
|
||||
}
|
||||
},
|
||||
"WindGustNight": {
|
||||
"Speed": {
|
||||
"Value": 22.2,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 271,
|
||||
"Localized": "W",
|
||||
"English": "W"
|
||||
}
|
||||
},
|
||||
"TotalLiquidNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"RainNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"SnowNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "cm",
|
||||
"UnitType": 4
|
||||
},
|
||||
"IceNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"HoursOfPrecipitationNight": 0.0,
|
||||
"HoursOfRainNight": 0.0,
|
||||
"HoursOfSnowNight": 0.0,
|
||||
"HoursOfIceNight": 0.0,
|
||||
"CloudCoverNight": 53
|
||||
},
|
||||
{
|
||||
"Date": "2020-07-29T07:00:00+02:00",
|
||||
"EpochDate": 1595998800,
|
||||
"HoursOfSun": 9.4,
|
||||
"DegreeDaySummary": {
|
||||
"Heating": {
|
||||
"Value": 0.0,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"Cooling": {
|
||||
"Value": 0.0,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
}
|
||||
},
|
||||
"Ozone": {
|
||||
"Value": 18,
|
||||
"Category": "Good",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Grass": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Mold": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Ragweed": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Tree": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"UVIndex": {
|
||||
"Value": 6,
|
||||
"Category": "High",
|
||||
"CategoryValue": 3
|
||||
},
|
||||
"TemperatureMin": {
|
||||
"Value": 11.7,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"TemperatureMax": {
|
||||
"Value": 24.0,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureMin": {
|
||||
"Value": 10.1,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureMax": {
|
||||
"Value": 26.5,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureShadeMin": {
|
||||
"Value": 10.1,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureShadeMax": {
|
||||
"Value": 22.5,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"IconDay": 3,
|
||||
"IconPhraseDay": "Partly sunny",
|
||||
"HasPrecipitationDay": false,
|
||||
"ShortPhraseDay": "Cooler with partial sunshine",
|
||||
"LongPhraseDay": "Cooler with partial sunshine",
|
||||
"PrecipitationProbabilityDay": 9,
|
||||
"ThunderstormProbabilityDay": 0,
|
||||
"RainProbabilityDay": 9,
|
||||
"SnowProbabilityDay": 0,
|
||||
"IceProbabilityDay": 0,
|
||||
"WindDay": {
|
||||
"Speed": {
|
||||
"Value": 13.0,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 293,
|
||||
"Localized": "WNW",
|
||||
"English": "WNW"
|
||||
}
|
||||
},
|
||||
"WindGustDay": {
|
||||
"Speed": {
|
||||
"Value": 24.1,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 271,
|
||||
"Localized": "W",
|
||||
"English": "W"
|
||||
}
|
||||
},
|
||||
"TotalLiquidDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"RainDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"SnowDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "cm",
|
||||
"UnitType": 4
|
||||
},
|
||||
"IceDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"HoursOfPrecipitationDay": 0.0,
|
||||
"HoursOfRainDay": 0.0,
|
||||
"HoursOfSnowDay": 0.0,
|
||||
"HoursOfIceDay": 0.0,
|
||||
"CloudCoverDay": 45,
|
||||
"IconNight": 34,
|
||||
"IconPhraseNight": "Mostly clear",
|
||||
"HasPrecipitationNight": false,
|
||||
"ShortPhraseNight": "Mainly clear",
|
||||
"LongPhraseNight": "Mainly clear",
|
||||
"PrecipitationProbabilityNight": 1,
|
||||
"ThunderstormProbabilityNight": 0,
|
||||
"RainProbabilityNight": 1,
|
||||
"SnowProbabilityNight": 0,
|
||||
"IceProbabilityNight": 0,
|
||||
"WindNight": {
|
||||
"Speed": {
|
||||
"Value": 11.1,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 264,
|
||||
"Localized": "W",
|
||||
"English": "W"
|
||||
}
|
||||
},
|
||||
"WindGustNight": {
|
||||
"Speed": {
|
||||
"Value": 18.5,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 266,
|
||||
"Localized": "W",
|
||||
"English": "W"
|
||||
}
|
||||
},
|
||||
"TotalLiquidNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"RainNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"SnowNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "cm",
|
||||
"UnitType": 4
|
||||
},
|
||||
"IceNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"HoursOfPrecipitationNight": 0.0,
|
||||
"HoursOfRainNight": 0.0,
|
||||
"HoursOfSnowNight": 0.0,
|
||||
"HoursOfIceNight": 0.0,
|
||||
"CloudCoverNight": 27
|
||||
},
|
||||
{
|
||||
"Date": "2020-07-30T07:00:00+02:00",
|
||||
"EpochDate": 1596085200,
|
||||
"HoursOfSun": 9.2,
|
||||
"DegreeDaySummary": {
|
||||
"Heating": {
|
||||
"Value": 1.0,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"Cooling": {
|
||||
"Value": 0.0,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
}
|
||||
},
|
||||
"Ozone": {
|
||||
"Value": 14,
|
||||
"Category": "Good",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Grass": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Mold": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Ragweed": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"Tree": {
|
||||
"Value": 0,
|
||||
"Category": "Low",
|
||||
"CategoryValue": 1
|
||||
},
|
||||
"UVIndex": {
|
||||
"Value": 7,
|
||||
"Category": "High",
|
||||
"CategoryValue": 3
|
||||
},
|
||||
"TemperatureMin": {
|
||||
"Value": 12.2,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"TemperatureMax": {
|
||||
"Value": 21.4,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureMin": {
|
||||
"Value": 11.3,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureMax": {
|
||||
"Value": 22.2,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureShadeMin": {
|
||||
"Value": 11.3,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"RealFeelTemperatureShadeMax": {
|
||||
"Value": 19.5,
|
||||
"Unit": "C",
|
||||
"UnitType": 17
|
||||
},
|
||||
"IconDay": 4,
|
||||
"IconPhraseDay": "Intermittent clouds",
|
||||
"HasPrecipitationDay": false,
|
||||
"ShortPhraseDay": "Clouds and sun",
|
||||
"LongPhraseDay": "Intervals of clouds and sunshine",
|
||||
"PrecipitationProbabilityDay": 1,
|
||||
"ThunderstormProbabilityDay": 0,
|
||||
"RainProbabilityDay": 1,
|
||||
"SnowProbabilityDay": 0,
|
||||
"IceProbabilityDay": 0,
|
||||
"WindDay": {
|
||||
"Speed": {
|
||||
"Value": 18.5,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 280,
|
||||
"Localized": "W",
|
||||
"English": "W"
|
||||
}
|
||||
},
|
||||
"WindGustDay": {
|
||||
"Speed": {
|
||||
"Value": 27.8,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 273,
|
||||
"Localized": "W",
|
||||
"English": "W"
|
||||
}
|
||||
},
|
||||
"TotalLiquidDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"RainDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"SnowDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "cm",
|
||||
"UnitType": 4
|
||||
},
|
||||
"IceDay": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"HoursOfPrecipitationDay": 0.0,
|
||||
"HoursOfRainDay": 0.0,
|
||||
"HoursOfSnowDay": 0.0,
|
||||
"HoursOfIceDay": 0.0,
|
||||
"CloudCoverDay": 50,
|
||||
"IconNight": 34,
|
||||
"IconPhraseNight": "Mostly clear",
|
||||
"HasPrecipitationNight": false,
|
||||
"ShortPhraseNight": "Mostly clear",
|
||||
"LongPhraseNight": "Mostly clear",
|
||||
"PrecipitationProbabilityNight": 3,
|
||||
"ThunderstormProbabilityNight": 0,
|
||||
"RainProbabilityNight": 3,
|
||||
"SnowProbabilityNight": 0,
|
||||
"IceProbabilityNight": 0,
|
||||
"WindNight": {
|
||||
"Speed": {
|
||||
"Value": 9.3,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 272,
|
||||
"Localized": "W",
|
||||
"English": "W"
|
||||
}
|
||||
},
|
||||
"WindGustNight": {
|
||||
"Speed": {
|
||||
"Value": 18.5,
|
||||
"Unit": "km/h",
|
||||
"UnitType": 7
|
||||
},
|
||||
"Direction": {
|
||||
"Degrees": 274,
|
||||
"Localized": "W",
|
||||
"English": "W"
|
||||
}
|
||||
},
|
||||
"TotalLiquidNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"RainNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"SnowNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "cm",
|
||||
"UnitType": 4
|
||||
},
|
||||
"IceNight": {
|
||||
"Value": 0.0,
|
||||
"Unit": "mm",
|
||||
"UnitType": 3
|
||||
},
|
||||
"HoursOfPrecipitationNight": 0.0,
|
||||
"HoursOfRainNight": 0.0,
|
||||
"HoursOfSnowNight": 0.0,
|
||||
"HoursOfIceNight": 0.0,
|
||||
"CloudCoverNight": 13
|
||||
}
|
||||
]
|
Loading…
Add table
Add a link
Reference in a new issue