diff --git a/CHANGELOG.md b/CHANGELOG.md index e4ede5b..9ebca0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,18 @@ Date: `2023-11-18` +This release is now V1.0, as all the relevant entities from the previous release are now implemented. Unfortunately my PR for getting this in to Default HACS is not merged yet, but I hope that this will happen soon, and when this does the previous integration will be removed. + ### Changes -- Added new sensor `Power Save Mode` that shows the Power Mode of a Tempest device. Attributes of the sensor gives a textual explanation. For more information [read here](https://help.weatherflow.com/hc/en-us/articles/360048877194-Solar-Power-Rechargeable-Battery) - Bump pyweatherflow-forecast to 1.0.0 -- Added new sensor `UV Description`, detailing the current UV value (For translated values please update the language file in the *translations* directory) -- Added new sensor `Staton Information`, detailing data about the Tempest Station (For translated values please update the language file in the *translations* directory) +- Added new sensor `Power Save Mode` that shows the Power Mode of a Tempest device. Attributes of the sensor gives a textual explanation. For more information [read here](https://help.weatherflow.com/hc/en-us/articles/360048877194-Solar-Power-Rechargeable-Battery) Closes (#27) +- Added new sensor `Beaufort Description`, detailing the current Beaufort value with a descriptive text (For translated values please update the language file in the *translations* directory) Closes (#27) +- Added new sensor `UV Description`, detailing the current UV value (For translated values please update the language file in the *translations* directory) Closes (#27) +- Added new sensor `Staton Name`, detailing data about the Tempest Station (For translated values please update the language file in the *translations* directory) Closes (#27) +- Added new Binary Sensor `Is Freezing`. On when the Celcius temperature is below 0. (Closes #26) +- Added new Binary Sensor `Is Lightning`. On when Lightning strikes are detected. (Closes #26) +- Added new Binary Sensor `Is Raining`. On when the rain rate is above 0mm. (Closes #26) ### TODO - If sensors have been installed, and the user selectes to remove them again, ensure they are deleted from Home Assistant. Currently they must be manually removed. diff --git a/README.md b/README.md index fd613ab..41192f9 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,16 @@ You can configure more than 1 instance of the Integration by using a different S Here is the list of sensors that the program generates. Calculated means, if No, then data comes directly from the Weather Station, if yes, it is a sensor that is derived from some of the other sensors. Not all sensors show up on all installations. It depends on where in the world your station is located. +### Binary Sensors +All entities are prefixed with `[STATION NAME]_binary_sensors_` + +| Sensor Name | Description | Calculated | +| --- | --- | --- | +| Is Freezing | On when the Celcius temperature is below 0 | Yes | +| Is Lightning | On when Lightning strikes are detected | Yes | +| Is Raining | On when the rain rate is above 0mm | Yes | + +### Sensors All entities are prefixed with `[STATION NAME]_sensors_` | Sensor Name | Description | Calculated | @@ -85,6 +95,7 @@ All entities are prefixed with `[STATION NAME]_sensors_` | Barometric Pressure | The Barometric pressure | No | | Battery | The % of charge on the Battery (Tempest device only) | Yes | | Beaufort | Beaufort scale is an empirical measure that relates wind speed to observed conditions at sea or on land | Yes | +| Beaufort Description | A descriptive text of the Beaufort value | Yes | | Cloud Base| The cloud height altitude above sea level | Yes | | Data Updated | The time of the last data update. Disabled by default. | No | | Delta T | Difference between Air Temperature and Wet Bulb Temperature | No | @@ -111,9 +122,11 @@ All entities are prefixed with `[STATION NAME]_sensors_` | Pressure Trend | Returns Steady, Falling or Rising determined by the rate of change over the past 3 hours| No | | Sea Level Pressure | Preasure measurement at Sea Level | No | | Solar Radiation | Electromagnetic radiation emitted by the sun | No | +| Staton Name | Station Name as state and more information about the station in the Attributes | Yes | | Station Pressure | Pressure measurement where the station is located | No | | Temperature | Outside Temperature | No | | Time of last lightning strike | When the last lightning strike occurred | No | +| UV Description | A descriptive text of the UV Index | Yes | | UV Index | The UV index | No | | Voltage | The Voltage of the Tempest device | No | | Visibility | Distance to the horizon | Yes | diff --git a/custom_components/weatherflow_forecast/__init__.py b/custom_components/weatherflow_forecast/__init__.py index 0f80d0b..59887d9 100644 --- a/custom_components/weatherflow_forecast/__init__.py +++ b/custom_components/weatherflow_forecast/__init__.py @@ -17,6 +17,7 @@ WeatherFlowForecastInternalServerError, WeatherFlowForecastWongStationId, WeatherFlowSensorData, + WeatherFlowStationData, ) from homeassistant.config_entries import ConfigEntry @@ -34,7 +35,7 @@ CONF_STATION_ID, ) -PLATFORMS = [Platform.WEATHER, Platform.SENSOR] +PLATFORMS = [Platform.WEATHER, Platform.SENSOR, Platform.BINARY_SENSOR] _LOGGER = logging.getLogger(__name__) @@ -121,6 +122,7 @@ def __init__(self, hass: HomeAssistant, config: MappingProxyType[str, Any], add_ self.daily_forecast: WeatherFlowForecastDaily = [] self.hourly_forecast: WeatherFlowForecastHourly = [] self.sensor_data: WeatherFlowSensorData = {} + self.station_data: WeatherFlowStationData = {} def initialize_data(self) -> bool: """Establish connection to API.""" @@ -157,6 +159,7 @@ async def fetch_data(self) -> Self: if self._add_sensors: try: resp: WeatherFlowForecastData = await self._weather_data.async_fetch_sensor_data() + station_info: WeatherFlowStationData = await self._weather_data.async_get_station() except WeatherFlowForecastWongStationId as unauthorized: _LOGGER.debug(unauthorized) raise Unauthorized from unauthorized @@ -170,9 +173,10 @@ async def fetch_data(self) -> Self: _LOGGER.debug(notreadyerror) raise ConfigEntryNotReady from notreadyerror - if not resp: + if not resp or not station_info: raise CannotConnect() self.sensor_data = resp + self.station_data = station_info # _LOGGER.debug(vars(self.sensor_data)) return self diff --git a/custom_components/weatherflow_forecast/binary_sensor.py b/custom_components/weatherflow_forecast/binary_sensor.py new file mode 100644 index 0000000..3332697 --- /dev/null +++ b/custom_components/weatherflow_forecast/binary_sensor.py @@ -0,0 +1,123 @@ +"""Support for WeatherFlow binary sensor data.""" +from __future__ import annotations + +import logging + +from dataclasses import dataclass +from types import MappingProxyType +from typing import Any + +from homeassistant.components.binary_sensor import ( + BinarySensorDeviceClass, + BinarySensorEntity, + BinarySensorEntityDescription, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import ( + CONF_NAME, +) +from homeassistant.core import HomeAssistant +from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo +from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.typing import StateType +from homeassistant.helpers.update_coordinator import ( + CoordinatorEntity, + DataUpdateCoordinator, +) + +from . import WeatherFlowForecastDataUpdateCoordinator +from .const import ( + ATTR_ATTRIBUTION, + CONF_STATION_ID, + DOMAIN, + MANUFACTURER, + MODEL, +) + +@dataclass +class WeatherFlowBinarySensorEntityDescription(BinarySensorEntityDescription): + """Describes WeatherFlow binary sensor entity.""" + + +BINARY_SENSOR_TYPES: tuple[WeatherFlowBinarySensorEntityDescription, ...] = ( + WeatherFlowBinarySensorEntityDescription( + key="is_freezing", + name="Is Freezing", + icon="mdi:snowflake-alert", + device_class=BinarySensorDeviceClass.COLD + ), + WeatherFlowBinarySensorEntityDescription( + key="is_lightning", + name="Is Lightning", + icon="mdi:flash-alert", + device_class=BinarySensorDeviceClass.SAFETY + ), + WeatherFlowBinarySensorEntityDescription( + key="is_raining", + name="Is Raining", + icon="mdi:water-percent-alert", + device_class=BinarySensorDeviceClass.MOISTURE + ), +) + +_LOGGER = logging.getLogger(__name__) + +async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback) -> None: + """WeatherFlow binary sensor platform.""" + coordinator: WeatherFlowForecastDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] + + if coordinator.data.sensor_data == {}: + return + + entities: list[WeatherFlowBinarySensor[Any]] = [ + WeatherFlowBinarySensor(coordinator, description, config_entry) + for description in BINARY_SENSOR_TYPES if getattr(coordinator.data.sensor_data, description.key) is not None + ] + + async_add_entities(entities, False) + +class WeatherFlowBinarySensor(CoordinatorEntity[DataUpdateCoordinator], BinarySensorEntity): + """A WeatherFlow binary sensor.""" + + entity_description: WeatherFlowBinarySensorEntityDescription + _attr_has_entity_name = True + + def __init__( + self, + coordinator: WeatherFlowForecastDataUpdateCoordinator, + description: WeatherFlowBinarySensorEntityDescription, + config: MappingProxyType[str, Any] + ) -> None: + """Initialize a WeatherFlow binary sensor.""" + super().__init__(coordinator) + self.entity_description = description + self._config = config + self._coordinator = coordinator + self._hw_version = " - Not Available" if self._coordinator.data.station_data.firmware_revision is None else self._coordinator.data.station_data.firmware_revision + + self._attr_device_info = DeviceInfo( + identifiers={(DOMAIN, f"{self._config.data[CONF_STATION_ID]}_binary")}, + entry_type=DeviceEntryType.SERVICE, + manufacturer=MANUFACTURER, + model=MODEL, + name=f"{self._config.data[CONF_NAME]} Binary Sensors", + configuration_url=f"https://tempestwx.com/station/{self._config.data[CONF_STATION_ID]}/grid", + hw_version=f"FW V{self._hw_version}", + ) + self._attr_attribution = ATTR_ATTRIBUTION + self._attr_unique_id = f"{config.data[CONF_STATION_ID]} {description.key}" + + @property + def is_on(self) -> StateType: + """Return state of the sensor.""" + + return ( + getattr(self.coordinator.data.sensor_data, self.entity_description.key) + if self.coordinator.data.sensor_data else None + ) + + async def async_added_to_hass(self): + """When entity is added to hass.""" + self.async_on_remove( + self.coordinator.async_add_listener(self.async_write_ha_state) + ) diff --git a/custom_components/weatherflow_forecast/const.py b/custom_components/weatherflow_forecast/const.py index fe0a80e..a3efb21 100644 --- a/custom_components/weatherflow_forecast/const.py +++ b/custom_components/weatherflow_forecast/const.py @@ -2,6 +2,9 @@ ATTR_ATTRIBUTION = "Weather data delivered by WeatherFlow" ATTR_DESCRIPTION = "description" +ATTR_HW_FIRMWARE_REVISION = "Firmware Revision" +ATTR_HW_SERIAL_NUMBER = "Serial Number" +ATTR_HW_STATION_ID = "Station ID" BATTERY_MODE_DESCRIPTION = [ "All sensors enabled and operating at full performance. Wind sampling interval every 3 seconds", diff --git a/custom_components/weatherflow_forecast/manifest.json b/custom_components/weatherflow_forecast/manifest.json index a2d35d9..3a4d722 100644 --- a/custom_components/weatherflow_forecast/manifest.json +++ b/custom_components/weatherflow_forecast/manifest.json @@ -10,7 +10,7 @@ "iot_class": "cloud_polling", "issue_tracker": "https://github.com/briis/weatherflow_forecast/issues", "requirements": [ - "pyweatherflow-forecast==0.6.4" + "pyweatherflow-forecast==1.0.0" ], - "version": "0.3.3" + "version": "1.0.0" } \ No newline at end of file diff --git a/custom_components/weatherflow_forecast/sensor.py b/custom_components/weatherflow_forecast/sensor.py index f65769d..7135acb 100644 --- a/custom_components/weatherflow_forecast/sensor.py +++ b/custom_components/weatherflow_forecast/sensor.py @@ -46,9 +46,11 @@ from .const import ( ATTR_ATTRIBUTION, ATTR_DESCRIPTION, + ATTR_HW_FIRMWARE_REVISION, + ATTR_HW_SERIAL_NUMBER, + ATTR_HW_STATION_ID, BATTERY_MODE_DESCRIPTION, CONCENTRATION_GRAMS_PER_CUBIC_METER, - CONF_FIRMWARE_REVISION, CONF_STATION_ID, DOMAIN, MANUFACTURER, @@ -106,6 +108,12 @@ class WeatherFlowSensorEntityDescription(SensorEntityDescription): icon="mdi:windsock", state_class=SensorStateClass.MEASUREMENT, ), + WeatherFlowSensorEntityDescription( + key="beaufort_description", + name="Beaufort Description", + icon="mdi:windsock", + translation_key="beaufort", + ), WeatherFlowSensorEntityDescription( key="brightness", name="Illuminance", @@ -300,6 +308,11 @@ class WeatherFlowSensorEntityDescription(SensorEntityDescription): device_class=SensorDeviceClass.IRRADIANCE, state_class=SensorStateClass.MEASUREMENT, ), + WeatherFlowSensorEntityDescription( + key="station_name", + name="Station Name", + icon="mdi:hubspot", + ), WeatherFlowSensorEntityDescription( key="station_pressure", name="Station Pressure", @@ -323,6 +336,12 @@ class WeatherFlowSensorEntityDescription(SensorEntityDescription): icon="mdi:sun-wireless", suggested_display_precision=1, ), + WeatherFlowSensorEntityDescription( + key="uv_description", + name="UV Description", + icon="mdi:sun-wireless", + translation_key="uv_description", + ), WeatherFlowSensorEntityDescription( key="visibility", name="Visibility", @@ -428,6 +447,8 @@ def __init__( super().__init__(coordinator) self.entity_description = description self._config = config + self._coordinator = coordinator + self._hw_version = " - Not Available" if self._coordinator.data.station_data.firmware_revision is None else self._coordinator.data.station_data.firmware_revision self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, self._config.data[CONF_STATION_ID])}, @@ -436,7 +457,7 @@ def __init__( model=MODEL, name=f"{self._config.data[CONF_NAME]} Sensors", configuration_url=f"https://tempestwx.com/station/{self._config.data[CONF_STATION_ID]}/grid", - hw_version=f"FW V{self._config.data.get(CONF_FIRMWARE_REVISION, ' - Not Available')}", + hw_version=f"FW V{self._hw_version}", ) self._attr_attribution = ATTR_ATTRIBUTION self._attr_unique_id = f"{config.data[CONF_STATION_ID]} {description.key}" @@ -466,6 +487,15 @@ def extra_state_attributes(self) -> None: return { ATTR_DESCRIPTION: BATTERY_MODE_DESCRIPTION[sensor_value], } + if self.entity_description.key == "station_name": + sensor_value = getattr(self.coordinator.data.sensor_data, + self.entity_description.key) if self.coordinator.data.sensor_data else None + if sensor_value is not None: + return { + ATTR_HW_FIRMWARE_REVISION: self._coordinator.data.station_data.firmware_revision, + ATTR_HW_SERIAL_NUMBER: self._coordinator.data.station_data.serial_number, + ATTR_HW_STATION_ID: str(self._config.data[CONF_STATION_ID]), + } async def async_added_to_hass(self): """When entity is added to hass.""" diff --git a/custom_components/weatherflow_forecast/translations/cs.json b/custom_components/weatherflow_forecast/translations/cs.json index ba62936..ca8d427 100644 --- a/custom_components/weatherflow_forecast/translations/cs.json +++ b/custom_components/weatherflow_forecast/translations/cs.json @@ -59,6 +59,33 @@ "nw": "SZ", "nnw": "SSZ" } + }, + "beaufort": { + "state": { + "calm": "Bezvětří", + "light_air": "Klidný vánek", + "light_breeze": "Lehký vánek", + "gentle_breeze": "Mírný vánek", + "moderate_breeze": "Střední vítr", + "fresh_breeze": "Střední vítr", + "strong_breeze": "Silný vítr", + "moderate_gale": "Mírnější vichr", + "fresh_gale": "Střední vichr", + "strong_gale": "Silný vichr", + "storm": "Bouřka", + "violent_storm": "Silná bouřka", + "hurricane": "Vichřice" + } + }, + "uv_description": { + "state": { + "extreme": "Extrémní", + "very-high": "Velmi vysoké", + "high": "Vysoké", + "moderate": "Střední", + "low": "Nízké", + "none": "Žádné" + } } } } diff --git a/custom_components/weatherflow_forecast/translations/da.json b/custom_components/weatherflow_forecast/translations/da.json index 08bb7af..2d40450 100644 --- a/custom_components/weatherflow_forecast/translations/da.json +++ b/custom_components/weatherflow_forecast/translations/da.json @@ -59,6 +59,33 @@ "rising": "Stiger", "steady": "Stabil" } + }, + "beaufort": { + "state": { + "calm": "Stille", + "light_air": "Næsten stille", + "light_breeze": "Svag vind", + "gentle_breeze": "Let vind", + "moderate_breeze": "Jævn vind", + "fresh_breeze": "Frisk vind", + "strong_breeze": "Hård vind", + "moderate_gale": "Stiv kuling", + "fresh_gale": "Hård kuling", + "strong_gale": "Stormende kuling", + "storm": "Storm", + "violent_storm": "Stærk storm", + "hurricane": "Orkan" + } + }, + "uv_description": { + "state": { + "extreme": "Ekstrem høj", + "very-high": "Meget høj", + "high": "Høj", + "moderate": "Moderat", + "low": "Lav", + "none": "Ingen data" + } } } } diff --git a/custom_components/weatherflow_forecast/translations/de.json b/custom_components/weatherflow_forecast/translations/de.json index e36b32d..219db88 100644 --- a/custom_components/weatherflow_forecast/translations/de.json +++ b/custom_components/weatherflow_forecast/translations/de.json @@ -59,6 +59,33 @@ "nw": "NW", "nnw": "NNW" } + }, + "beaufort": { + "state": { + "calm": "Windstille", + "light_air": "leiser Zug", + "light_breeze": "leichte Brise", + "gentle_breeze": "schwache Brise", + "moderate_breeze": "mäßige Brise", + "fresh_breeze": "frischer Wind", + "strong_breeze": "starker Wind", + "moderate_gale": "steifer Wind", + "fresh_gale": "stürmischer Wind", + "strong_gale": "Sturm", + "storm": "schwerer Sturm", + "violent_storm": "orkanartiger Sturm", + "hurricane": "Orkan" + } + }, + "uv_description": { + "state": { + "extreme": "extrem", + "very-high": "sehr hoch", + "high": "hoch", + "moderate": "mäßig", + "low": "niedrig", + "none": "kein" + } } } } diff --git a/custom_components/weatherflow_forecast/translations/en.json b/custom_components/weatherflow_forecast/translations/en.json index 1df3a09..06c993e 100644 --- a/custom_components/weatherflow_forecast/translations/en.json +++ b/custom_components/weatherflow_forecast/translations/en.json @@ -59,6 +59,33 @@ "rising": "Rising", "steady": "Steady" } + }, + "beaufort": { + "state": { + "calm": "Calm", + "light_air": "Light air", + "light_breeze": "Light breeze", + "gentle_breeze": "Gentle breeze", + "moderate_breeze": "Moderate breeze", + "fresh_breeze": "Fresh breeze", + "strong_breeze": "Strong breeze", + "moderate_gale": "Moderate Gale", + "fresh_gale": "Fresh Gale", + "strong_gale": "Strong Gale", + "storm": "Storm", + "violent_storm": "Violent Storm", + "hurricane": "Hurricane" + } + }, + "uv_description": { + "state": { + "extreme": "Extreme", + "very-high": "Very High", + "high": "High", + "moderate": "Moderate", + "low": "Low", + "none": "None" + } } } } diff --git a/custom_components/weatherflow_forecast/translations/fr.json b/custom_components/weatherflow_forecast/translations/fr.json index 95ade75..0c8ad5f 100644 --- a/custom_components/weatherflow_forecast/translations/fr.json +++ b/custom_components/weatherflow_forecast/translations/fr.json @@ -59,7 +59,34 @@ "rising": "À la hausse", "steady": "Constante" } + }, + "beaufort": { + "state": { + "calm": "Calm", + "light_air": "Light air", + "light_breeze": "Light breeze", + "gentle_breeze": "Gentle breeze", + "moderate_breeze": "Moderate breeze", + "fresh_breeze": "Fresh breeze", + "strong_breeze": "Strong breeze", + "moderate_gale": "Moderate Gale", + "fresh_gale": "Fresh Gale", + "strong_gale": "Strong Gale", + "storm": "Storm", + "violent_storm": "Violent Storm", + "hurricane": "Hurricane" + } + }, + "uv_description": { + "state": { + "extreme": "Extreme", + "very-high": "Very High", + "high": "High", + "moderate": "Moderate", + "low": "Low", + "none": "None" + } } } } -} +} \ No newline at end of file diff --git a/custom_components/weatherflow_forecast/translations/it.json b/custom_components/weatherflow_forecast/translations/it.json index 39acaf0..5ce07da 100644 --- a/custom_components/weatherflow_forecast/translations/it.json +++ b/custom_components/weatherflow_forecast/translations/it.json @@ -59,6 +59,33 @@ "nw": "NO", "nnw": "NNO" } + }, + "beaufort": { + "state": { + "calm": "Calma", + "light_air": "Bava di vento", + "light_breeze": "Brezza leggera", + "gentle_breeze": "Brezza leggera", + "moderate_breeze": "Brezza moderata", + "fresh_breeze": "Brezza moderata", + "strong_breeze": "Brezza forte", + "moderate_gale": "Burrasca moderata", + "fresh_gale": "Burrasca moderata", + "strong_gale": "Burrasca intensa", + "storm": "Bufera", + "violent_storm": "Bufera violenta", + "hurricane": "Uragano" + } + }, + "uv_description": { + "state": { + "extreme": "Estremo", + "very-high": "Molto Elevato", + "high": "Elevato", + "moderate": "Moderato", + "low": "Basso", + "none": "Nessuno" + } } } } diff --git a/custom_components/weatherflow_forecast/translations/nl.json b/custom_components/weatherflow_forecast/translations/nl.json index 244893a..31feff8 100644 --- a/custom_components/weatherflow_forecast/translations/nl.json +++ b/custom_components/weatherflow_forecast/translations/nl.json @@ -59,6 +59,33 @@ "nw": "NW", "nnw": "NNW" } + }, + "beaufort": { + "state": { + "calm": "Windstil", + "light_air": "Zwakke wind", + "light_breeze": "Zwakke wind", + "gentle_breeze": "Matige wind", + "moderate_breeze": "Matige wind", + "fresh_breeze": "Vrij krachtige wind", + "strong_breeze": "Krachtige wind", + "moderate_gale": "Harde wind", + "fresh_gale": "Stormachtige wind", + "strong_gale": "Storm", + "storm": "Zware storm", + "violent_storm": "Zeer ware storm", + "hurricane": "Orkaan" + } + }, + "uv_description": { + "state": { + "extreme": "Extreem", + "very-high": "Zeer sterk", + "high": "Sterk", + "moderate": "Matig", + "low": "Zwak", + "none": "Geen" + } } } } diff --git a/custom_components/weatherflow_forecast/translations/sv.json b/custom_components/weatherflow_forecast/translations/sv.json index 23297f5..0bf4983 100644 --- a/custom_components/weatherflow_forecast/translations/sv.json +++ b/custom_components/weatherflow_forecast/translations/sv.json @@ -59,6 +59,33 @@ "nw": "NV", "nnw": "NNV" } + }, + "beaufort": { + "state": { + "calm": "Lugnt", + "light_air": "Svag vind", + "light_breeze": "Svag vind", + "gentle_breeze": "Måttlig vind", + "moderate_breeze": "Måttlig vind", + "fresh_breeze": "Frisk vind", + "strong_breeze": "Frisk vind", + "moderate_gale": "Hård vind", + "fresh_gale": "Hård vind", + "strong_gale": "Hård vind", + "storm": "Storm", + "violent_storm": "Storm", + "hurricane": "Orkan" + } + }, + "uv_description": { + "state": { + "extreme": "Extrem", + "very-high": "Mycket hög", + "high": "Hög", + "moderate": "Måttlig", + "low": "Låg", + "none": "Ingen" + } } } }