Compare commits

...

3 Commits

Author SHA1 Message Date
Lukas Svoboda bbb6a23b6c
Merge pull request #45 from schizza/config_flow_depr_fix
Fix config flow
2025-02-13 17:33:16 +01:00
schizza d9cb2179d5 Fix config deprecation
Updated config flow to comply with new changes in HA
2025-02-13 17:32:07 +01:00
schizza 25bb26bb4d WSLink support in beta
Support for firmware 3.0 and WSLink connections.
As for now the 3.0 firmware sending data only on SSL connections.
2025-02-12 13:13:46 +01:00
11 changed files with 679 additions and 307 deletions

View File

@ -19,12 +19,15 @@ from .const import (
DOMAIN, DOMAIN,
SENSORS_TO_LOAD, SENSORS_TO_LOAD,
WINDY_ENABLED, WINDY_ENABLED,
WSLINK,
WSLINK_URL,
) )
from .utils import ( from .utils import (
anonymize, anonymize,
check_disabled, check_disabled,
loaded_sensors, loaded_sensors,
remap_items, remap_items,
remap_wslink_items,
translated_notification, translated_notification,
translations, translations,
update_options, update_options,
@ -51,15 +54,25 @@ class WeatherDataUpdateCoordinator(DataUpdateCoordinator):
async def recieved_data(self, webdata): async def recieved_data(self, webdata):
"""Handle incoming data query.""" """Handle incoming data query."""
_wslink = self.config_entry.data.get(WSLINK)
data = webdata.query data = webdata.query
response = None response = None
if "ID" not in data or "PASSWORD" not in data: if not _wslink and ("ID" not in data or "PASSWORD" not in data):
_LOGGER.error("Invalid request. No security data provided!") _LOGGER.error("Invalid request. No security data provided!")
raise HTTPUnauthorized raise HTTPUnauthorized
id_data = data["ID"] if _wslink and ("wsid" not in data or "wspw" not in data):
key_data = data["PASSWORD"] _LOGGER.error("Invalid request. No security data provided!")
raise HTTPUnauthorized
if _wslink:
id_data = data["wsid"]
key_data = data["wspw"]
else:
id_data = data["ID"]
key_data = data["PASSWORD"]
_id = self.config_entry.options.get(API_ID) _id = self.config_entry.options.get(API_ID)
_key = self.config_entry.options.get(API_KEY) _key = self.config_entry.options.get(API_KEY)
@ -71,7 +84,11 @@ class WeatherDataUpdateCoordinator(DataUpdateCoordinator):
if self.config_entry.options.get(WINDY_ENABLED): if self.config_entry.options.get(WINDY_ENABLED):
response = await self.windy.push_data_to_windy(data) response = await self.windy.push_data_to_windy(data)
remaped_items = remap_items(data) remaped_items = (
remap_wslink_items(data)
if self.config_entry.options.get(WSLINK)
else remap_items(data)
)
if sensors := check_disabled(self.hass, remaped_items, self.config): if sensors := check_disabled(self.hass, remaped_items, self.config):
translate_sensors = [ translate_sensors = [
@ -98,18 +115,22 @@ class WeatherDataUpdateCoordinator(DataUpdateCoordinator):
if self.config_entry.options.get(DEV_DBG): if self.config_entry.options.get(DEV_DBG):
_LOGGER.info("Dev log: %s", anonymize(data)) _LOGGER.info("Dev log: %s", anonymize(data))
response = response if response else "OK" response = response or "OK"
return aiohttp.web.Response(body=f"{response}", status=200) return aiohttp.web.Response(body=f"{response or 'OK'}", status=200)
def register_path( def register_path(
hass: HomeAssistant, url_path: str, coordinator: WeatherDataUpdateCoordinator hass: HomeAssistant, url_path: str, coordinator: WeatherDataUpdateCoordinator
): ):
"""Register path to handle incoming data.""" """Register path to handle incoming data."""
_wslink = hass.config_entries.async_get_entry(WSLINK)
try: try:
route = hass.http.app.router.add_route( route = hass.http.app.router.add_route(
"GET", url_path, coordinator.recieved_data "GET", url_path, coordinator.recieved_data
) )
except RuntimeError as Ex: # pylint: disable=(broad-except) except RuntimeError as Ex: # pylint: disable=(broad-except)
if ( if (
"Added route will never be executed, method GET is already registered" "Added route will never be executed, method GET is already registered"
@ -144,7 +165,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
if not register_path(hass, DEFAULT_URL, coordinator): _wslink = entry.data.get(WSLINK)
_LOGGER.info("WS Link is %s", "enbled" if _wslink else "disabled")
if not register_path(hass, DEFAULT_URL if not _wslink else WSLINK_URL, coordinator):
_LOGGER.error("Fatal: path not registered!") _LOGGER.error("Fatal: path not registered!")
raise PlatformNotReady raise PlatformNotReady

View File

@ -1,9 +1,10 @@
"""Config flow for Sencor SWS 12500 Weather Station integration.""" """Config flow for Sencor SWS 12500 Weather Station integration."""
from typing import Any from typing import Any
import voluptuous as vol import voluptuous as vol
from homeassistant import config_entries from homeassistant.config_entries import ConfigFlow, OptionsFlow
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
@ -17,6 +18,7 @@ from .const import (
WINDY_API_KEY, WINDY_API_KEY,
WINDY_ENABLED, WINDY_ENABLED,
WINDY_LOGGER_ENABLED, WINDY_LOGGER_ENABLED,
WSLINK,
) )
@ -28,35 +30,56 @@ class InvalidAuth(HomeAssistantError):
"""Invalid auth exception.""" """Invalid auth exception."""
class ConfigOptionsFlowHandler(config_entries.OptionsFlow): class ConfigOptionsFlowHandler(OptionsFlow):
"""Handle WeatherStation ConfigFlow.""" """Handle WeatherStation ConfigFlow."""
def __init__(self, config_entry: config_entries.ConfigEntry) -> None: def __init__(self) -> None:
"""Initialize flow.""" """Initialize flow."""
self.config_entry = config_entry super().__init__()
self.windy_data: dict[str, Any] = {}
self.windy_data_schema = {}
self.user_data: dict[str, str] = {}
self.user_data_schema = {}
self.sensors: dict[str, Any] = {}
@property
def config_entry(self):
return self.hass.config_entries.async_get_entry(self.handler)
def _get_entry_data(self):
"""Get entry data."""
self.user_data: dict[str, str] = { self.user_data: dict[str, str] = {
API_ID: self.config_entry.options.get(API_ID), API_ID: self.config_entry.options.get(API_ID),
API_KEY: self.config_entry.options.get(API_KEY), API_KEY: self.config_entry.options.get(API_KEY),
WSLINK: self.config_entry.options.get(WSLINK),
DEV_DBG: self.config_entry.options.get(DEV_DBG), DEV_DBG: self.config_entry.options.get(DEV_DBG),
} }
self.windy_data: dict[str, Any] = {
WINDY_API_KEY: self.config_entry.options.get(WINDY_API_KEY),
WINDY_ENABLED: self.config_entry.options.get(WINDY_ENABLED) if isinstance(self.config_entry.options.get(WINDY_ENABLED), bool) else False,
WINDY_LOGGER_ENABLED: self.config_entry.options.get(WINDY_LOGGER_ENABLED) if isinstance(self.config_entry.options.get(WINDY_LOGGER_ENABLED), bool) else False,
}
self.sensors: dict[str, Any] = {
SENSORS_TO_LOAD: self.config_entry.options.get(SENSORS_TO_LOAD) if isinstance(self.config_entry.options.get(SENSORS_TO_LOAD), list) else []
}
self.user_data_schema = { self.user_data_schema = {
vol.Required(API_ID, default=self.user_data[API_ID] or ""): str, vol.Required(API_ID, default=self.user_data[API_ID] or ""): str,
vol.Required(API_KEY, default=self.user_data[API_KEY] or ""): str, vol.Required(API_KEY, default=self.user_data[API_KEY] or ""): str,
vol.Optional(WSLINK, default=self.user_data[WSLINK]): bool,
vol.Optional(DEV_DBG, default=self.user_data[DEV_DBG]): bool, vol.Optional(DEV_DBG, default=self.user_data[DEV_DBG]): bool,
} }
self.sensors: dict[str, Any] = {
SENSORS_TO_LOAD: self.config_entry.options.get(SENSORS_TO_LOAD)
if isinstance(self.config_entry.options.get(SENSORS_TO_LOAD), list)
else []
}
self.windy_data: dict[str, Any] = {
WINDY_API_KEY: self.config_entry.options.get(WINDY_API_KEY),
WINDY_ENABLED: self.config_entry.options.get(WINDY_ENABLED)
if isinstance(self.config_entry.options.get(WINDY_ENABLED), bool)
else False,
WINDY_LOGGER_ENABLED: self.config_entry.options.get(WINDY_LOGGER_ENABLED)
if isinstance(self.config_entry.options.get(WINDY_LOGGER_ENABLED), bool)
else False,
}
self.windy_data_schema = { self.windy_data_schema = {
vol.Optional( vol.Optional(
WINDY_API_KEY, default=self.windy_data[WINDY_API_KEY] or "" WINDY_API_KEY, default=self.windy_data[WINDY_API_KEY] or ""
@ -76,6 +99,8 @@ class ConfigOptionsFlowHandler(config_entries.OptionsFlow):
"""Manage basic options - credentials.""" """Manage basic options - credentials."""
errors = {} errors = {}
self._get_entry_data()
if user_input is None: if user_input is None:
return self.async_show_form( return self.async_show_form(
step_id="basic", step_id="basic",
@ -93,7 +118,7 @@ class ConfigOptionsFlowHandler(config_entries.OptionsFlow):
# retain windy data # retain windy data
user_input.update(self.windy_data) user_input.update(self.windy_data)
#retain sensors # retain sensors
user_input.update(self.sensors) user_input.update(self.sensors)
return self.async_create_entry(title=DOMAIN, data=user_input) return self.async_create_entry(title=DOMAIN, data=user_input)
@ -111,6 +136,8 @@ class ConfigOptionsFlowHandler(config_entries.OptionsFlow):
"""Manage windy options.""" """Manage windy options."""
errors = {} errors = {}
self._get_entry_data()
if user_input is None: if user_input is None:
return self.async_show_form( return self.async_show_form(
step_id="windy", step_id="windy",
@ -133,18 +160,19 @@ class ConfigOptionsFlowHandler(config_entries.OptionsFlow):
# retain user_data # retain user_data
user_input.update(self.user_data) user_input.update(self.user_data)
#retain senors # retain senors
user_input.update(self.sensors) user_input.update(self.sensors)
return self.async_create_entry(title=DOMAIN, data=user_input) return self.async_create_entry(title=DOMAIN, data=user_input)
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): class ConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Sencor SWS 12500 Weather Station.""" """Handle a config flow for Sencor SWS 12500 Weather Station."""
data_schema = { data_schema = {
vol.Required(API_ID): str, vol.Required(API_ID): str,
vol.Required(API_KEY): str, vol.Required(API_KEY): str,
vol.Optional(WSLINK): bool,
vol.Optional(DEV_DBG): bool, vol.Optional(DEV_DBG): bool,
} }
@ -170,7 +198,9 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
elif user_input[API_KEY] == user_input[API_ID]: elif user_input[API_KEY] == user_input[API_ID]:
errors["base"] = "valid_credentials_match" errors["base"] = "valid_credentials_match"
else: else:
return self.async_create_entry(title=DOMAIN, data=user_input, options=user_input) return self.async_create_entry(
title=DOMAIN, data=user_input, options=user_input
)
return self.async_show_form( return self.async_show_form(
step_id="user", step_id="user",
@ -178,10 +208,9 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
errors=errors, errors=errors,
) )
@staticmethod @staticmethod
@callback @callback
def async_get_options_flow( def async_get_options_flow(config_entry) -> ConfigOptionsFlowHandler:
config_entry: config_entries.ConfigEntry,
) -> ConfigOptionsFlowHandler:
"""Get the options flow for this handler.""" """Get the options flow for this handler."""
return ConfigOptionsFlowHandler(config_entry) return ConfigOptionsFlowHandler()

View File

@ -5,6 +5,7 @@ from typing import Final
DOMAIN = "sws12500" DOMAIN = "sws12500"
DEFAULT_URL = "/weatherstation/updateweatherstation.php" DEFAULT_URL = "/weatherstation/updateweatherstation.php"
WSLINK_URL = "/data/upload.php"
WINDY_URL = "https://stations.windy.com/pws/update/" WINDY_URL = "https://stations.windy.com/pws/update/"
ICON = "mdi:weather" ICON = "mdi:weather"
@ -15,6 +16,7 @@ API_ID = "API_ID"
SENSORS_TO_LOAD: Final = "sensors_to_load" SENSORS_TO_LOAD: Final = "sensors_to_load"
DEV_DBG: Final = "dev_debug_checkbox" DEV_DBG: Final = "dev_debug_checkbox"
WSLINK: Final = "wslink"
WINDY_API_KEY = "WINDY_API_KEY" WINDY_API_KEY = "WINDY_API_KEY"
WINDY_ENABLED: Final = "windy_enabled_checkbox" WINDY_ENABLED: Final = "windy_enabled_checkbox"
@ -53,6 +55,7 @@ PURGE_DATA: Final = [
"dailyrainin", "dailyrainin",
] ]
BARO_PRESSURE: Final = "baro_pressure" BARO_PRESSURE: Final = "baro_pressure"
OUTSIDE_TEMP: Final = "outside_temp" OUTSIDE_TEMP: Final = "outside_temp"
DEW_POINT: Final = "dew_point" DEW_POINT: Final = "dew_point"
@ -99,6 +102,22 @@ REMAP_ITEMS: dict = {
"soilmoisture3": CH4_HUMIDITY, "soilmoisture3": CH4_HUMIDITY,
} }
REMAP_WSLINK_ITEMS: dict = {
"intem": INDOOR_TEMP,
"inhum": INDOOR_HUMIDITY,
"t1temp": OUTSIDE_TEMP,
"t1hum": OUTSIDE_HUMIDITY,
"t1dew": DEW_POINT,
"t1wdir": WIND_DIR,
"t1ws": WIND_SPEED,
"t1wg": WIND_GUST,
"t1rainra": RAIN,
"t1raindy": DAILY_RAIN,
"t1solrad": SOLAR_RADIATION,
"rbar": BARO_PRESSURE,
"uvi": UV
}
DISABLED_BY_DEFAULT: Final = [ DISABLED_BY_DEFAULT: Final = [
CH2_TEMP, CH2_TEMP,
CH2_HUMIDITY, CH2_HUMIDITY,
@ -148,3 +167,4 @@ AZIMUT: list[UnitOfDir] = [
UnitOfDir.NNW, UnitOfDir.NNW,
UnitOfDir.N, UnitOfDir.N,
] ]

View File

@ -10,6 +10,6 @@
"issue_tracker": "https://github.com/schizza/SWS-12500-custom-component/issues", "issue_tracker": "https://github.com/schizza/SWS-12500-custom-component/issues",
"requirements": [], "requirements": [],
"ssdp": [], "ssdp": [],
"version": "0.1.3.5", "version": "0.1.4.0",
"zeroconf": [] "zeroconf": []
} }

View File

@ -1,29 +1,9 @@
"""Sensors definition for SWS12500.""" """Sensors definition for SWS12500."""
from collections.abc import Callable
from dataclasses import dataclass
import logging import logging
from typing import Any, cast
from homeassistant.components.sensor import ( from homeassistant.components.sensor import RestoreSensor, SensorEntity
RestoreSensor,
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
DEGREE,
PERCENTAGE,
UV_INDEX,
UnitOfIrradiance,
UnitOfPrecipitationDepth,
UnitOfPressure,
UnitOfSpeed,
UnitOfTemperature,
UnitOfVolumetricFlux,
)
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.device_registry import DeviceEntryType from homeassistant.helpers.device_registry import DeviceEntryType
from homeassistant.helpers.entity import DeviceInfo, generate_entity_id from homeassistant.helpers.entity import DeviceInfo, generate_entity_id
@ -32,258 +12,25 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import WeatherDataUpdateCoordinator from . import WeatherDataUpdateCoordinator
from .const import ( from .const import (
BARO_PRESSURE,
CH2_HUMIDITY,
CH2_TEMP,
CH3_TEMP,
CH3_HUMIDITY,
CH4_TEMP,
CH4_HUMIDITY,
CHILL_INDEX, CHILL_INDEX,
DAILY_RAIN,
DEW_POINT,
DOMAIN, DOMAIN,
HEAT_INDEX, HEAT_INDEX,
INDOOR_HUMIDITY,
INDOOR_TEMP,
OUTSIDE_HUMIDITY, OUTSIDE_HUMIDITY,
OUTSIDE_TEMP, OUTSIDE_TEMP,
RAIN,
SENSORS_TO_LOAD, SENSORS_TO_LOAD,
SOLAR_RADIATION,
UV,
WIND_AZIMUT, WIND_AZIMUT,
WIND_DIR, WIND_DIR,
WIND_GUST,
WIND_SPEED, WIND_SPEED,
UnitOfDir, WSLINK,
) )
from .utils import heat_index, wind_dir_to_text, chill_index from .sensors_common import WeatherSensorEntityDescription
from .sensors_weather import SENSOR_TYPES_WEATHER_API
from .sensors_wslink import SENSOR_TYPES_WSLINK
from .utils import chill_index, heat_index
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@dataclass(frozen=True, kw_only=True)
class WeatherSensorEntityDescription(SensorEntityDescription):
"""Describe Weather Sensor entities."""
value_fn: Callable[[Any], int | float | str | None]
SENSOR_TYPES: tuple[WeatherSensorEntityDescription, ...] = (
WeatherSensorEntityDescription(
key=INDOOR_TEMP,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer",
device_class=SensorDeviceClass.TEMPERATURE,
translation_key=INDOOR_TEMP,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=INDOOR_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer",
device_class=SensorDeviceClass.HUMIDITY,
translation_key=INDOOR_HUMIDITY,
value_fn=lambda data: cast(int, data),
),
WeatherSensorEntityDescription(
key=OUTSIDE_TEMP,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer",
device_class=SensorDeviceClass.TEMPERATURE,
translation_key=OUTSIDE_TEMP,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=OUTSIDE_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer",
device_class=SensorDeviceClass.HUMIDITY,
translation_key=OUTSIDE_HUMIDITY,
value_fn=lambda data: cast(int, data),
),
WeatherSensorEntityDescription(
key=DEW_POINT,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer-lines",
device_class=SensorDeviceClass.TEMPERATURE,
translation_key=DEW_POINT,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=BARO_PRESSURE,
native_unit_of_measurement=UnitOfPressure.INHG,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer-lines",
device_class=SensorDeviceClass.ATMOSPHERIC_PRESSURE,
suggested_unit_of_measurement=UnitOfPressure.HPA,
translation_key=BARO_PRESSURE,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=WIND_SPEED,
native_unit_of_measurement=UnitOfSpeed.MILES_PER_HOUR,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.WIND_SPEED,
suggested_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
icon="mdi:weather-windy",
translation_key=WIND_SPEED,
value_fn=lambda data: cast(int, data),
),
WeatherSensorEntityDescription(
key=WIND_GUST,
native_unit_of_measurement=UnitOfSpeed.MILES_PER_HOUR,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.WIND_SPEED,
suggested_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
icon="mdi:windsock",
translation_key=WIND_GUST,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=WIND_DIR,
native_unit_of_measurement=DEGREE,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=None,
icon="mdi:sign-direction",
translation_key=WIND_DIR,
value_fn=lambda data: cast(int, data),
),
WeatherSensorEntityDescription(
key=WIND_AZIMUT,
icon="mdi:sign-direction",
value_fn=lambda data: cast(str, wind_dir_to_text(data)),
device_class=SensorDeviceClass.ENUM,
options=list(UnitOfDir),
translation_key=WIND_AZIMUT,
),
WeatherSensorEntityDescription(
key=RAIN,
native_unit_of_measurement=UnitOfPrecipitationDepth.INCHES,
device_class=SensorDeviceClass.PRECIPITATION,
state_class=SensorStateClass.TOTAL,
suggested_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
suggested_display_precision=2,
icon="mdi:weather-pouring",
translation_key=RAIN,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=DAILY_RAIN,
native_unit_of_measurement=UnitOfVolumetricFlux.INCHES_PER_DAY,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.PRECIPITATION_INTENSITY,
suggested_unit_of_measurement=UnitOfVolumetricFlux.MILLIMETERS_PER_DAY,
suggested_display_precision=2,
icon="mdi:weather-pouring",
translation_key=DAILY_RAIN,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=SOLAR_RADIATION,
native_unit_of_measurement=UnitOfIrradiance.WATTS_PER_SQUARE_METER,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.IRRADIANCE,
icon="mdi:weather-sunny",
translation_key=SOLAR_RADIATION,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=UV,
name=UV,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UV_INDEX,
icon="mdi:sunglasses",
translation_key=UV,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=CH2_TEMP,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=CH2_TEMP,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=CH2_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.HUMIDITY,
icon="mdi:weather-sunny",
translation_key=CH2_HUMIDITY,
value_fn=lambda data: cast(int, data),
),
WeatherSensorEntityDescription(
key=CH3_TEMP,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=CH3_TEMP,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=CH3_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.HUMIDITY,
icon="mdi:weather-sunny",
translation_key=CH3_HUMIDITY,
value_fn=lambda data: cast(int, data),
),
WeatherSensorEntityDescription(
key=CH4_TEMP,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=CH4_TEMP,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=CH4_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.HUMIDITY,
icon="mdi:weather-sunny",
translation_key=CH4_HUMIDITY,
value_fn=lambda data: cast(int, data),
),
WeatherSensorEntityDescription(
key=HEAT_INDEX,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=HEAT_INDEX,
value_fn=lambda data: cast(int, data),
),
WeatherSensorEntityDescription(
key=CHILL_INDEX,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
suggested_display_precision=2,
icon="mdi:weather-sunny",
translation_key=CHILL_INDEX,
value_fn=lambda data: cast(int, data),
),
)
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: ConfigEntry, config_entry: ConfigEntry,
@ -295,6 +42,9 @@ async def async_setup_entry(
sensors_to_load: list = [] sensors_to_load: list = []
sensors: list = [] sensors: list = []
_wslink = config_entry.data.get(WSLINK)
SENSOR_TYPES = SENSOR_TYPES_WSLINK if _wslink else SENSOR_TYPES_WEATHER_API
# Check if we have some sensors to load. # Check if we have some sensors to load.
if sensors_to_load := config_entry.options.get(SENSORS_TO_LOAD): if sensors_to_load := config_entry.options.get(SENSORS_TO_LOAD):

View File

@ -0,0 +1,14 @@
"""Common classes for sensors."""
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any
from homeassistant.components.sensor import SensorEntityDescription
@dataclass(frozen=True, kw_only=True)
class WeatherSensorEntityDescription(SensorEntityDescription):
"""Describe Weather Sensor entities."""
value_fn: Callable[[Any], int | float | str | None]

View File

@ -0,0 +1,257 @@
"""Sensor entities for the SWS12500 integration for old endpoint."""
from typing import cast
from homeassistant.components.sensor import SensorDeviceClass, SensorStateClass
from homeassistant.const import (
DEGREE,
PERCENTAGE,
UV_INDEX,
UnitOfIrradiance,
UnitOfPrecipitationDepth,
UnitOfPressure,
UnitOfSpeed,
UnitOfTemperature,
UnitOfVolumetricFlux,
)
from .const import (
BARO_PRESSURE,
CH2_HUMIDITY,
CH2_TEMP,
CH3_HUMIDITY,
CH3_TEMP,
CH4_HUMIDITY,
CH4_TEMP,
CHILL_INDEX,
DAILY_RAIN,
DEW_POINT,
HEAT_INDEX,
INDOOR_HUMIDITY,
INDOOR_TEMP,
OUTSIDE_HUMIDITY,
OUTSIDE_TEMP,
RAIN,
SOLAR_RADIATION,
UV,
WIND_AZIMUT,
WIND_DIR,
WIND_GUST,
WIND_SPEED,
UnitOfDir,
)
from .sensors_common import WeatherSensorEntityDescription
from .utils import wind_dir_to_text
SENSOR_TYPES_WEATHER_API: tuple[WeatherSensorEntityDescription, ...] = (
WeatherSensorEntityDescription(
key=INDOOR_TEMP,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer",
device_class=SensorDeviceClass.TEMPERATURE,
translation_key=INDOOR_TEMP,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=INDOOR_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer",
device_class=SensorDeviceClass.HUMIDITY,
translation_key=INDOOR_HUMIDITY,
value_fn=lambda data: cast("int", data),
),
WeatherSensorEntityDescription(
key=OUTSIDE_TEMP,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer",
device_class=SensorDeviceClass.TEMPERATURE,
translation_key=OUTSIDE_TEMP,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=OUTSIDE_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer",
device_class=SensorDeviceClass.HUMIDITY,
translation_key=OUTSIDE_HUMIDITY,
value_fn=lambda data: cast(int, data),
),
WeatherSensorEntityDescription(
key=DEW_POINT,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer-lines",
device_class=SensorDeviceClass.TEMPERATURE,
translation_key=DEW_POINT,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=BARO_PRESSURE,
native_unit_of_measurement=UnitOfPressure.INHG,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer-lines",
device_class=SensorDeviceClass.ATMOSPHERIC_PRESSURE,
suggested_unit_of_measurement=UnitOfPressure.HPA,
translation_key=BARO_PRESSURE,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=WIND_SPEED,
native_unit_of_measurement=UnitOfSpeed.MILES_PER_HOUR,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.WIND_SPEED,
suggested_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
icon="mdi:weather-windy",
translation_key=WIND_SPEED,
value_fn=lambda data: cast(int, data),
),
WeatherSensorEntityDescription(
key=WIND_GUST,
native_unit_of_measurement=UnitOfSpeed.MILES_PER_HOUR,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.WIND_SPEED,
suggested_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
icon="mdi:windsock",
translation_key=WIND_GUST,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=WIND_DIR,
native_unit_of_measurement=DEGREE,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=None,
icon="mdi:sign-direction",
translation_key=WIND_DIR,
value_fn=lambda data: cast(int, data),
),
WeatherSensorEntityDescription(
key=WIND_AZIMUT,
icon="mdi:sign-direction",
value_fn=lambda data: cast(str, wind_dir_to_text(data)),
device_class=SensorDeviceClass.ENUM,
options=list(UnitOfDir),
translation_key=WIND_AZIMUT,
),
WeatherSensorEntityDescription(
key=RAIN,
native_unit_of_measurement=UnitOfPrecipitationDepth.INCHES,
device_class=SensorDeviceClass.PRECIPITATION,
state_class=SensorStateClass.TOTAL,
suggested_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
suggested_display_precision=2,
icon="mdi:weather-pouring",
translation_key=RAIN,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=DAILY_RAIN,
native_unit_of_measurement=UnitOfVolumetricFlux.INCHES_PER_DAY,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.PRECIPITATION_INTENSITY,
suggested_unit_of_measurement=UnitOfVolumetricFlux.MILLIMETERS_PER_DAY,
suggested_display_precision=2,
icon="mdi:weather-pouring",
translation_key=DAILY_RAIN,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=SOLAR_RADIATION,
native_unit_of_measurement=UnitOfIrradiance.WATTS_PER_SQUARE_METER,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.IRRADIANCE,
icon="mdi:weather-sunny",
translation_key=SOLAR_RADIATION,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=UV,
name=UV,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UV_INDEX,
icon="mdi:sunglasses",
translation_key=UV,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=CH2_TEMP,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=CH2_TEMP,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=CH2_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.HUMIDITY,
icon="mdi:weather-sunny",
translation_key=CH2_HUMIDITY,
value_fn=lambda data: cast(int, data),
),
WeatherSensorEntityDescription(
key=CH3_TEMP,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=CH3_TEMP,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=CH3_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.HUMIDITY,
icon="mdi:weather-sunny",
translation_key=CH3_HUMIDITY,
value_fn=lambda data: cast(int, data),
),
WeatherSensorEntityDescription(
key=CH4_TEMP,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=CH4_TEMP,
value_fn=lambda data: cast(float, data),
),
WeatherSensorEntityDescription(
key=CH4_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.HUMIDITY,
icon="mdi:weather-sunny",
translation_key=CH4_HUMIDITY,
value_fn=lambda data: cast(int, data),
),
WeatherSensorEntityDescription(
key=HEAT_INDEX,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=HEAT_INDEX,
value_fn=lambda data: cast(int, data),
),
WeatherSensorEntityDescription(
key=CHILL_INDEX,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
suggested_display_precision=2,
icon="mdi:weather-sunny",
translation_key=CHILL_INDEX,
value_fn=lambda data: cast(int, data),
),
)

View File

@ -0,0 +1,257 @@
"""Sensor entities for the SWS12500 integration for old endpoint."""
from typing import cast
from homeassistant.components.sensor import SensorDeviceClass, SensorStateClass
from homeassistant.const import (
DEGREE,
PERCENTAGE,
UV_INDEX,
UnitOfIrradiance,
UnitOfPrecipitationDepth,
UnitOfPressure,
UnitOfSpeed,
UnitOfTemperature,
UnitOfVolumetricFlux,
)
from .const import (
BARO_PRESSURE,
CH2_HUMIDITY,
CH2_TEMP,
CH3_HUMIDITY,
CH3_TEMP,
CH4_HUMIDITY,
CH4_TEMP,
CHILL_INDEX,
DAILY_RAIN,
DEW_POINT,
HEAT_INDEX,
INDOOR_HUMIDITY,
INDOOR_TEMP,
OUTSIDE_HUMIDITY,
OUTSIDE_TEMP,
RAIN,
SOLAR_RADIATION,
UV,
WIND_AZIMUT,
WIND_DIR,
WIND_GUST,
WIND_SPEED,
UnitOfDir,
)
from .sensors_common import WeatherSensorEntityDescription
from .utils import wind_dir_to_text
SENSOR_TYPES_WSLINK: tuple[WeatherSensorEntityDescription, ...] = (
WeatherSensorEntityDescription(
key=INDOOR_TEMP,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer",
device_class=SensorDeviceClass.TEMPERATURE,
translation_key=INDOOR_TEMP,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=INDOOR_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer",
device_class=SensorDeviceClass.HUMIDITY,
translation_key=INDOOR_HUMIDITY,
value_fn=lambda data: cast("int", data),
),
WeatherSensorEntityDescription(
key=OUTSIDE_TEMP,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer",
device_class=SensorDeviceClass.TEMPERATURE,
translation_key=OUTSIDE_TEMP,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=OUTSIDE_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer",
device_class=SensorDeviceClass.HUMIDITY,
translation_key=OUTSIDE_HUMIDITY,
value_fn=lambda data: cast("int", data),
),
WeatherSensorEntityDescription(
key=DEW_POINT,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer-lines",
device_class=SensorDeviceClass.TEMPERATURE,
translation_key=DEW_POINT,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=BARO_PRESSURE,
native_unit_of_measurement=UnitOfPressure.HPA,
state_class=SensorStateClass.MEASUREMENT,
icon="mdi:thermometer-lines",
device_class=SensorDeviceClass.ATMOSPHERIC_PRESSURE,
suggested_unit_of_measurement=UnitOfPressure.HPA,
translation_key=BARO_PRESSURE,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=WIND_SPEED,
native_unit_of_measurement=UnitOfSpeed.METERS_PER_SECOND,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.WIND_SPEED,
suggested_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
icon="mdi:weather-windy",
translation_key=WIND_SPEED,
value_fn=lambda data: cast("int", data),
),
WeatherSensorEntityDescription(
key=WIND_GUST,
native_unit_of_measurement=UnitOfSpeed.METERS_PER_SECOND,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.WIND_SPEED,
suggested_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
icon="mdi:windsock",
translation_key=WIND_GUST,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=WIND_DIR,
native_unit_of_measurement=DEGREE,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=None,
icon="mdi:sign-direction",
translation_key=WIND_DIR,
value_fn=lambda data: cast("int", data),
),
WeatherSensorEntityDescription(
key=WIND_AZIMUT,
icon="mdi:sign-direction",
value_fn=lambda data: cast("str", wind_dir_to_text(data)),
device_class=SensorDeviceClass.ENUM,
options=list(UnitOfDir),
translation_key=WIND_AZIMUT,
),
WeatherSensorEntityDescription(
key=RAIN,
native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
device_class=SensorDeviceClass.PRECIPITATION,
state_class=SensorStateClass.TOTAL,
suggested_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
suggested_display_precision=2,
icon="mdi:weather-pouring",
translation_key=RAIN,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=DAILY_RAIN,
native_unit_of_measurement=UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.PRECIPITATION_INTENSITY,
suggested_unit_of_measurement=UnitOfVolumetricFlux.MILLIMETERS_PER_DAY,
suggested_display_precision=2,
icon="mdi:weather-pouring",
translation_key=DAILY_RAIN,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=SOLAR_RADIATION,
native_unit_of_measurement=UnitOfIrradiance.WATTS_PER_SQUARE_METER,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.IRRADIANCE,
icon="mdi:weather-sunny",
translation_key=SOLAR_RADIATION,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=UV,
name=UV,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UV_INDEX,
icon="mdi:sunglasses",
translation_key=UV,
value_fn=lambda data: cast("float", data),
),
# WeatherSensorEntityDescription(
# key=CH2_TEMP,
# native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
# state_class=SensorStateClass.MEASUREMENT,
# device_class=SensorDeviceClass.TEMPERATURE,
# suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
# icon="mdi:weather-sunny",
# translation_key=CH2_TEMP,
# value_fn=lambda data: cast(float, data),
# ),
# WeatherSensorEntityDescription(
# key=CH2_HUMIDITY,
# native_unit_of_measurement=PERCENTAGE,
# state_class=SensorStateClass.MEASUREMENT,
# device_class=SensorDeviceClass.HUMIDITY,
# icon="mdi:weather-sunny",
# translation_key=CH2_HUMIDITY,
# value_fn=lambda data: cast(int, data),
# ),
# WeatherSensorEntityDescription(
# key=CH3_TEMP,
# native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
# state_class=SensorStateClass.MEASUREMENT,
# device_class=SensorDeviceClass.TEMPERATURE,
# suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
# icon="mdi:weather-sunny",
# translation_key=CH3_TEMP,
# value_fn=lambda data: cast(float, data),
# ),
# WeatherSensorEntityDescription(
# key=CH3_HUMIDITY,
# native_unit_of_measurement=PERCENTAGE,
# state_class=SensorStateClass.MEASUREMENT,
# device_class=SensorDeviceClass.HUMIDITY,
# icon="mdi:weather-sunny",
# translation_key=CH3_HUMIDITY,
# value_fn=lambda data: cast(int, data),
# ),
# WeatherSensorEntityDescription(
# key=CH4_TEMP,
# native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
# state_class=SensorStateClass.MEASUREMENT,
# device_class=SensorDeviceClass.TEMPERATURE,
# suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
# icon="mdi:weather-sunny",
# translation_key=CH4_TEMP,
# value_fn=lambda data: cast(float, data),
# ),
# WeatherSensorEntityDescription(
# key=CH4_HUMIDITY,
# native_unit_of_measurement=PERCENTAGE,
# state_class=SensorStateClass.MEASUREMENT,
# device_class=SensorDeviceClass.HUMIDITY,
# icon="mdi:weather-sunny",
# translation_key=CH4_HUMIDITY,
# value_fn=lambda data: cast(int, data),
# ),
WeatherSensorEntityDescription(
key=HEAT_INDEX,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=HEAT_INDEX,
value_fn=lambda data: cast("int", data),
),
WeatherSensorEntityDescription(
key=CHILL_INDEX,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
suggested_display_precision=2,
icon="mdi:weather-sunny",
translation_key=CHILL_INDEX,
value_fn=lambda data: cast("int", data),
),
)

View File

@ -10,6 +10,7 @@
"data": { "data": {
"API_ID": "API ID / ID stanice", "API_ID": "API ID / ID stanice",
"API_KEY": "API KEY / Heslo", "API_KEY": "API KEY / Heslo",
"wslink": "WSLink API",
"dev_debug_checkbox": "Developer log" "dev_debug_checkbox": "Developer log"
}, },
"description": "Zadejte API ID a API KEY, aby meteostanice mohla komunikovat s HomeAssistantem", "description": "Zadejte API ID a API KEY, aby meteostanice mohla komunikovat s HomeAssistantem",
@ -32,6 +33,7 @@
"data": { "data": {
"API_ID": "API ID / ID Stanice", "API_ID": "API ID / ID Stanice",
"API_KEY": "API KEY / Heslo", "API_KEY": "API KEY / Heslo",
"wslink": "WSLink API",
"dev_debug_checkbox": "Developer log" "dev_debug_checkbox": "Developer log"
}, },
"description": "Zadejte API ID a API KEY, aby meteostanice mohla komunikovat s HomeAssistantem", "description": "Zadejte API ID a API KEY, aby meteostanice mohla komunikovat s HomeAssistantem",

View File

@ -10,6 +10,7 @@
"data": { "data": {
"API_ID": "API ID / Station ID", "API_ID": "API ID / Station ID",
"API_KEY": "API KEY / Password", "API_KEY": "API KEY / Password",
"WSLINK": "WSLink API",
"dev_debug_checkbox": "Developer log" "dev_debug_checkbox": "Developer log"
}, },
"description": "Provide API ID and API KEY so the Weather Station can access HomeAssistant", "description": "Provide API ID and API KEY so the Weather Station can access HomeAssistant",
@ -32,6 +33,7 @@
"data": { "data": {
"API_ID": "API ID / Station ID", "API_ID": "API ID / Station ID",
"API_KEY": "API KEY / Password", "API_KEY": "API KEY / Password",
"WSLINK": "WSLink API",
"dev_debug_checkbox": "Developer log" "dev_debug_checkbox": "Developer log"
}, },
"description": "Provide API ID and API KEY so the Weather Station can access HomeAssistant", "description": "Provide API ID and API KEY so the Weather Station can access HomeAssistant",

View File

@ -1,25 +1,27 @@
"""Utils for SWS12500.""" """Utils for SWS12500."""
import logging import logging
import math
from typing import Any
import numpy as np
from homeassistant.components import persistent_notification from homeassistant.components import persistent_notification
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import UnitOfTemperature
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.translation import async_get_translations from homeassistant.helpers.translation import async_get_translations
from homeassistant.const import UnitOfTemperature
from typing import Any
import math
import numpy as np
from .const import ( from .const import (
AZIMUT, AZIMUT,
DEV_DBG, DEV_DBG,
REMAP_ITEMS,
SENSORS_TO_LOAD,
UnitOfDir,
OUTSIDE_TEMP,
OUTSIDE_HUMIDITY, OUTSIDE_HUMIDITY,
OUTSIDE_TEMP,
REMAP_ITEMS,
REMAP_WSLINK_ITEMS,
SENSORS_TO_LOAD,
WIND_SPEED, WIND_SPEED,
UnitOfDir,
) )
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -99,7 +101,7 @@ def anonymize(data):
anonym = {} anonym = {}
for k in data: for k in data:
if k not in ("ID", "PASSWORD"): if k not in ("ID", "PASSWORD", "wsid", "wspw"):
anonym[k] = data[k] anonym[k] = data[k]
return anonym return anonym
@ -115,6 +117,16 @@ def remap_items(entities):
return items return items
def remap_wslink_items(entities):
"""Remap items in query for WSLink API."""
items = {}
for item in entities:
if item in REMAP_WSLINK_ITEMS:
items[REMAP_WSLINK_ITEMS[item]] = entities[item]
return items
def loaded_sensors(config_entry: ConfigEntry) -> list | None: def loaded_sensors(config_entry: ConfigEntry) -> list | None:
"""Get loaded sensors.""" """Get loaded sensors."""
@ -202,11 +214,15 @@ def chill_index(data: Any) -> UnitOfTemperature:
temp = float(data[OUTSIDE_TEMP]) temp = float(data[OUTSIDE_TEMP])
wind = float(data[WIND_SPEED]) wind = float(data[WIND_SPEED])
return round( return (
( round(
(35.7 + (0.6215 * temp)) (
- (35.75 * (wind**0.16)) (35.7 + (0.6215 * temp))
+ (0.4275 * (temp * (wind**0.16))) - (35.75 * (wind**0.16))
), + (0.4275 * (temp * (wind**0.16)))
2, ),
) if temp < 50 and wind > 3 else temp 2,
)
if temp < 50 and wind > 3
else temp
)