Ecowitt support
Update setiing (config_flow and translations) for Ecowitt settings. Also updated utils.py to accept None for value.ecowitt_support
parent
9288ae4a64
commit
211965dd52
|
|
@ -48,6 +48,7 @@ from .const import (
|
|||
ECOWITT_ENABLED,
|
||||
ECOWITT_URL_PREFIX,
|
||||
HEALTH_URL,
|
||||
LEGACY_ENABLED,
|
||||
POCASI_CZ_ENABLED,
|
||||
SENSORS_TO_LOAD,
|
||||
WINDY_ENABLED,
|
||||
|
|
@ -421,6 +422,7 @@ def register_path(
|
|||
|
||||
_wslink: bool = checked_or(config.options.get(WSLINK), bool, False)
|
||||
_ecowitt_enabled: bool = checked_or(config.options.get(ECOWITT_ENABLED), bool, False)
|
||||
_legacy: bool = checked_or(config.options.get(LEGACY_ENABLED), bool, True)
|
||||
|
||||
# Load registred routes
|
||||
routes: Routes | None = hass_data.get("routes", None)
|
||||
|
|
@ -450,9 +452,10 @@ def register_path(
|
|||
raise ConfigEntryNotReady from Ex
|
||||
|
||||
# Finally create internal route dispatcher with provided urls, while we have webhooks registered.
|
||||
routes.add_route(DEFAULT_URL, _default_route, coordinator.received_data, enabled=not _wslink)
|
||||
routes.add_route(WSLINK_URL, _wslink_post_route, coordinator.received_data, enabled=_wslink)
|
||||
routes.add_route(WSLINK_URL, _wslink_get_route, coordinator.received_data, enabled=_wslink)
|
||||
routes.add_route(DEFAULT_URL, _default_route, coordinator.received_data, enabled=_legacy and not _wslink)
|
||||
routes.add_route(WSLINK_URL, _wslink_post_route, coordinator.received_data, enabled=_legacy and _wslink)
|
||||
routes.add_route(WSLINK_URL, _wslink_get_route, coordinator.received_data, enabled=_legacy and _wslink)
|
||||
|
||||
# Make health route `sticky` so it will not change upon updating options.
|
||||
routes.add_route(
|
||||
HEALTH_URL,
|
||||
|
|
@ -530,6 +533,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
entry_data[ENTRY_LAST_OPTIONS] = dict(entry.options)
|
||||
|
||||
_wslink = checked_or(entry.options.get(WSLINK), bool, False)
|
||||
_legacy = checked_or(entry.options.get(LEGACY_ENABLED), bool, True)
|
||||
_ecowitt_enabled = checked_or(entry.options.get(ECOWITT_ENABLED), bool, False)
|
||||
_ecowitt_path = ECOWITT_URL_PREFIX + "/{webhook_id}"
|
||||
|
||||
|
|
@ -537,7 +541,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
|
||||
if routes:
|
||||
_LOGGER.debug("We have routes registered, will try to switch dispatcher.")
|
||||
routes.switch_route(coordinator.received_data, DEFAULT_URL if not _wslink else WSLINK_URL)
|
||||
routes.switch_route(coordinator.received_data, DEFAULT_URL if not _wslink else WSLINK_URL, enabled=_legacy)
|
||||
routes.set_ecowitt_enabled(_ecowitt_path, coordinator.recieved_ecowitt_data, _ecowitt_enabled)
|
||||
routes.set_ingress_observer(coordinator_health.record_dispatch)
|
||||
coordinator_health.update_routing(routes)
|
||||
|
|
|
|||
|
|
@ -70,15 +70,17 @@ class ConfigOptionsFlowHandler(OptionsFlow):
|
|||
self.user_data = {
|
||||
API_ID: self.config_entry.options.get(API_ID, ""),
|
||||
API_KEY: self.config_entry.options.get(API_KEY, ""),
|
||||
LEGACY_ENABLED: self.config_entry.options.get(LEGACY_ENABLED, True),
|
||||
WSLINK: self.config_entry.options.get(WSLINK, False),
|
||||
DEV_DBG: self.config_entry.options.get(DEV_DBG, False),
|
||||
}
|
||||
|
||||
self.user_data_schema = {
|
||||
vol.Required(API_ID, default=self.user_data.get(API_ID, "")): str,
|
||||
vol.Required(API_KEY, default=self.user_data.get(API_KEY, "")): str,
|
||||
vol.Optional(API_ID, default=self.user_data.get(API_ID, "")): str,
|
||||
vol.Optional(API_KEY, default=self.user_data.get(API_KEY, "")): str,
|
||||
vol.Optional(WSLINK, default=self.user_data.get(WSLINK, False)): bool,
|
||||
vol.Optional(DEV_DBG, default=self.user_data.get(DEV_DBG, False)): bool,
|
||||
vol.Optional(LEGACY_ENABLED, default=self.user_data.get(LEGACY_ENABLED, True)): bool,
|
||||
}
|
||||
|
||||
self.sensors = {
|
||||
|
|
@ -146,7 +148,12 @@ class ConfigOptionsFlowHandler(OptionsFlow):
|
|||
)
|
||||
|
||||
async def async_step_basic(self, user_input: Any = None):
|
||||
"""Manage basic options - credentials."""
|
||||
"""Manage basic options - PWS/WSLink credentials and legacy endpoint toggle.
|
||||
|
||||
API ID/KEY are required only when legacy (PWS/WSLINK) endpoint is enabled.
|
||||
For an Ecowitt-only setup, the user can turn the legacy endpoint off and leave credantials empty.
|
||||
|
||||
"""
|
||||
errors: dict[str, str] = {}
|
||||
|
||||
await self._get_entry_data()
|
||||
|
|
@ -158,15 +165,16 @@ class ConfigOptionsFlowHandler(OptionsFlow):
|
|||
errors=errors,
|
||||
)
|
||||
|
||||
if user_input[API_ID] in INVALID_CREDENTIALS:
|
||||
if user_input.get(LEGACY_ENABLED):
|
||||
if user_input[API_ID] in INVALID_CREDENTIALS or user_input.get(API_ID, "") == "":
|
||||
errors[API_ID] = "valid_credentials_api"
|
||||
elif user_input[API_KEY] in INVALID_CREDENTIALS:
|
||||
elif user_input[API_KEY] in INVALID_CREDENTIALS or user_input.get(API_KEY, "") == "":
|
||||
errors[API_KEY] = "valid_credentials_key"
|
||||
elif user_input[API_KEY] == user_input[API_ID]:
|
||||
errors["base"] = "valid_credentials_match"
|
||||
else:
|
||||
user_input = self.retain_data(user_input)
|
||||
|
||||
if not errors:
|
||||
user_input = self.retain_data(user_input)
|
||||
return self.async_create_entry(title=DOMAIN, data=user_input)
|
||||
|
||||
self.user_data = user_input
|
||||
|
|
|
|||
|
|
@ -126,17 +126,19 @@ class Routes:
|
|||
handler = info.handler if info.enabled else info.fallback
|
||||
return await handler(request)
|
||||
|
||||
def switch_route(self, handler: Handler, url_path: str) -> None:
|
||||
def switch_route(self, handler: Handler, url_path: str | None, *, enabled: bool = True) -> None:
|
||||
"""Enable routes based on URL, disable all others. Leave sticky routes enabled.
|
||||
|
||||
This is called when options change (e.g. WSLink toggle). The aiohttp router stays
|
||||
untouched; we only flip which internal handler is active.
|
||||
When `enabled` is False (or url_path is None), all non-sticky (legacy) routes are disabled.
|
||||
- used when only Ecowitt is active.
|
||||
Sticky routes (health, ecowitt) are left untouched.
|
||||
The aiohttp router stays untouched; we only flip which internal handler is active.
|
||||
"""
|
||||
for route in self.routes.values():
|
||||
if route.sticky:
|
||||
continue
|
||||
|
||||
if route.url_path == url_path:
|
||||
if enabled and route.url_path == url_path:
|
||||
_LOGGER.info(
|
||||
"New coordinator to route: (%s):%s",
|
||||
route.route.method,
|
||||
|
|
|
|||
|
|
@ -4,9 +4,8 @@ from collections.abc import Callable
|
|||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.sensor import SensorEntityDescription
|
||||
|
||||
from dev.custom_components.sws12500.const import VOCLevel
|
||||
from homeassistant.components.sensor import SensorEntityDescription
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
|
|
@ -14,7 +13,7 @@ class WeatherSensorEntityDescription(SensorEntityDescription):
|
|||
"""Describe Weather Sensor entities."""
|
||||
|
||||
value_fn: Callable[[Any], int | float | str | VOCLevel | None] | None = None
|
||||
value_from_data_fn: Callable[[dict[str, Any]], int | float | str | None] | None = None
|
||||
value_from_data_fn: Callable[[dict[str, Any]], int | float | str | VOCLevel | None] | None = None
|
||||
|
||||
deprecated: bool = False
|
||||
replacement_entity_domain: str | None = None
|
||||
|
|
|
|||
|
|
@ -573,7 +573,7 @@ SENSOR_TYPES_WSLINK: tuple[WeatherSensorEntityDescription, ...] = (
|
|||
device_class=SensorDeviceClass.ENUM,
|
||||
options=list(VOCLevel),
|
||||
icon="mdi:air-filter",
|
||||
value_from_data_fn=voc_level_to_text(data),
|
||||
value_from_data_fn=lambda data: voc_level_to_text(data.get(VOC, None)),
|
||||
),
|
||||
WeatherSensorEntityDescription(
|
||||
key=T9_BATTERY,
|
||||
|
|
|
|||
|
|
@ -7,19 +7,39 @@
|
|||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"description": "Provide API ID and API KEY so the Weather Station can access HomeAssistant",
|
||||
"title": "Configure access for Weather Station",
|
||||
"title": "Choose your station type",
|
||||
"description": "Choose the type of your station. If you don't have Eccowit station, choose PWS/WSLink",
|
||||
"menu_options": {
|
||||
"pws": "PWS/WSLink (Sencor, Garni, Bresser, other - Weather Underground compatible)",
|
||||
"ecowitt": "Ecowitt"
|
||||
}
|
||||
},
|
||||
"pws": {
|
||||
"title": "PWS/WSLink credentials.",
|
||||
"description": "Provide API ID and API KEY so the Weather Station can access HomeAssistant.",
|
||||
"data": {
|
||||
"API_ID": "API ID / Station ID",
|
||||
"API_KEY": "API KEY / Password",
|
||||
"WSLINK": "WSLink API",
|
||||
"wslink": "WSLink Protocol",
|
||||
"dev_debug_checkbox": "Developer log"
|
||||
},
|
||||
"data_description": {
|
||||
"dev_debug_checkbox": " Enable only if you want to send debuging data to the developer.",
|
||||
"API_ID": "API ID is the Station ID you set in the Weather Station.",
|
||||
"API_KEY": "API KEY is the password you set in the Weather Station.",
|
||||
"WSLINK": "Enable WSLink API if the station is set to send data via WSLink."
|
||||
"wslink": "Enable WSLink Protocol if the station is set to send data via WSLink. If you are unsure, use https://test-station.schizza.cz/",
|
||||
"dev_debug_checkbox": " Enable only if you want to send debuging data to the developer."
|
||||
}
|
||||
},
|
||||
"ecowitt": {
|
||||
"title": "Ecowitt configuration.",
|
||||
"description": "No API ID/KEY needed. Set your Ecowitt station to send data to the enndpoint below.",
|
||||
"data": {
|
||||
"ecowitt_webhook_id": "Unique webhook ID",
|
||||
"ecowitt_enabled": "Enable Ecowitt station data"
|
||||
},
|
||||
"data_description": {
|
||||
"ecowitt_webhook_id": "Set your Ecowitt station to send data to the endpoint: {url}:{port}/weatherhub/{webhook_id}",
|
||||
"ecowitt_enabled": "Enable receiving data from Ecowitt stations"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -41,19 +61,19 @@
|
|||
}
|
||||
},
|
||||
"basic": {
|
||||
"description": "Provide API ID and API KEY so the Weather Station can access HomeAssistant",
|
||||
"title": "Configure credentials",
|
||||
"data": {
|
||||
"description": "Configure the PWS/WSLink endpoint. Turn off 'Enable PWS/WSLink' for an Ecowitt-only setup - API ID/KEY are not required."""title": "Configure PWS/WSLink","data": {
|
||||
"API_ID": "API ID / Station ID",
|
||||
"API_KEY": "API KEY / Password",
|
||||
"WSLINK": "WSLink API",
|
||||
"wslink": "WSLink protocol",
|
||||
"legacy_enbaled": "Enable PWS/WSLink endpoint (disable for Ecowitt-only setup)",
|
||||
"dev_debug_checkbox": "Developer log"
|
||||
},
|
||||
"data_description": {
|
||||
"dev_debug_checkbox": " Enable only if you want to send debuging data to the developer.",
|
||||
"API_ID": "API ID is the Station ID you set in the Weather Station.",
|
||||
"API_KEY": "API KEY is the password you set in the Weather Station.",
|
||||
"WSLINK": "Enable WSLink API if the station is set to send data via WSLink."
|
||||
"wslink": "Enable WSLink API if the station is set to send data via WSLink. (If you are unsure, use https://test-station.schizza.cz/)",
|
||||
"legacy_enbaled": "Turn off if your station uses Ecowitt only."
|
||||
}
|
||||
},
|
||||
"windy": {
|
||||
|
|
|
|||
|
|
@ -7,19 +7,39 @@
|
|||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"description": "Zadejte API ID a API KEY, aby meteostanice mohla komunikovat s HomeAssistantem",
|
||||
"title": "Nastavení přihlášení",
|
||||
"title": "Vyberte typ stanice",
|
||||
"description": "Zadejte typ stanice, kterou používáte. Pokude nepoužíváte Ecowitt, vyberte PWS/WSLink",
|
||||
"menu_options": {
|
||||
"pws": "PWS/WSLink (Sencor, Garni, Bresser, jiné - Weather Underground kompatibilní)",
|
||||
"ecowitt": "Ecowitt"
|
||||
}
|
||||
},
|
||||
"pws": {
|
||||
"title": "Přihlašovací údaje PWS/WSLink.",
|
||||
"description": "Zadejte API ID a API KEY, aby meteostanice mohla komunikovat s HomeAssistantem.",
|
||||
"data": {
|
||||
"API_ID": "API ID / ID Stanice",
|
||||
"API_KEY": "API KEY / Heslo",
|
||||
"wslink": "WSLink API",
|
||||
"wslink": "WSLink Protorkol",
|
||||
"dev_debug_checkbox": "Developer log"
|
||||
},
|
||||
"data_description": {
|
||||
"dev_debug_checkbox": "Zapnout pouze v případě, že chcete poslat ladící informace vývojáři.",
|
||||
"API_ID": "API ID je ID stanice, které jste nastavili v meteostanici.",
|
||||
"API_KEY": "API KEY je heslo, které jste nastavili v meteostanici.",
|
||||
"wslink": "WSLink API zapněte, pokud je stanice nastavena na zasílání dat přes WSLink."
|
||||
"wslink": "Zapněte tuto volbu, pokud stanice používá WSLink protokol. Pokud si nejstě jistí, použijte https://test-station.schizza.cz/",
|
||||
"dev_debug_checkbox": "Zapnout pouze v případě, že chcete poslat ladící informace vývojáři."
|
||||
}
|
||||
},
|
||||
"ecowitt": {
|
||||
"title": "Nastavení pro Ecowitt stanice",
|
||||
"description": "Zadejte unikátní webhook ID pro příjem dat ze stanic Ecowitt. Pokud nepoužíváte stanice Ecowitt, tento krok přeskočte.",
|
||||
"data": {
|
||||
"ecowitt_webhook_id": "Unikátní webhook ID pro Ecowitt stanice",
|
||||
"ecowitt_enabled": "Povolit data ze stanic Ecowitt"
|
||||
},
|
||||
"data_description": {
|
||||
"ecowitt_webhook_id": "Nastavení pro stanici: {url}:{port}/weatherhub/{webhook_id}",
|
||||
"ecowitt_enabled": "Povolit přijímání dat ze stanic Ecowitt"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -49,19 +69,21 @@
|
|||
}
|
||||
},
|
||||
"basic": {
|
||||
"description": "Zadejte API ID a API KEY, aby meteostanice mohla komunikovat s HomeAssistantem",
|
||||
"title": "Nastavení přihlášení",
|
||||
"description": "Nastavení endpointu PWS/WSLink. Pro stanici jen s Ecowwittem vypněte 'Povolit endpoint PWS/WSLink'. API ID/KEY nejsou potřeba",
|
||||
"title": "Nastavení PWS/WSLink",
|
||||
"data": {
|
||||
"API_ID": "API ID / ID Stanice",
|
||||
"API_KEY": "API KEY / Heslo",
|
||||
"wslink": "WSLink API",
|
||||
"dev_debug_checkbox": "Developer log"
|
||||
"wslink": "WSLink protokol",
|
||||
"dev_debug_checkbox": "Developer log",
|
||||
"legacy_enabled": "Povolit endpoint PWS/WSLink"
|
||||
},
|
||||
"data_description": {
|
||||
"dev_debug_checkbox": "Zapnout pouze v případě, že chcete poslat ladící informace vývojáři.",
|
||||
"API_ID": "API ID je ID stanice, které jste nastavili v meteostanici.",
|
||||
"API_KEY": "API KEY je heslo, které jste nastavili v meteostanici.",
|
||||
"wslink": "WSLink API zapněte, pokud je stanice nastavena na zasílání dat přes WSLink."
|
||||
"wslink": "WSLink API zapněte, pokud je stanice nastavena na zasílání dat přes WSLink.",
|
||||
"legacy_enabled": "Vyplněte, pokud vaše stanice používá pouze Ecowitt."
|
||||
}
|
||||
},
|
||||
"windy": {
|
||||
|
|
|
|||
|
|
@ -7,19 +7,39 @@
|
|||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"description": "Provide API ID and API KEY so the Weather Station can access HomeAssistant",
|
||||
"title": "Configure access for Weather Station",
|
||||
"title": "Choose your station type",
|
||||
"description": "Choose the type of your station. If you don't have Eccowit station, choose PWS/WSLink",
|
||||
"menu_options": {
|
||||
"pws": "PWS/WSLink (Sencor, Garni, Bresser, other - Weather Underground compatible)",
|
||||
"ecowitt": "Ecowitt"
|
||||
}
|
||||
},
|
||||
"pws": {
|
||||
"title": "PWS/WSLink credentials.",
|
||||
"description": "Provide API ID and API KEY so the Weather Station can access HomeAssistant.",
|
||||
"data": {
|
||||
"API_ID": "API ID / Station ID",
|
||||
"API_KEY": "API KEY / Password",
|
||||
"WSLINK": "WSLink API",
|
||||
"wslink": "WSLink Protocol",
|
||||
"dev_debug_checkbox": "Developer log"
|
||||
},
|
||||
"data_description": {
|
||||
"dev_debug_checkbox": " Enable only if you want to send debuging data to the developer.",
|
||||
"API_ID": "API ID is the Station ID you set in the Weather Station.",
|
||||
"API_KEY": "API KEY is the password you set in the Weather Station.",
|
||||
"WSLINK": "Enable WSLink API if the station is set to send data via WSLink."
|
||||
"wslink": "Enable WSLink Protocol if the station is set to send data via WSLink. If you are unsure, use https://test-station.schizza.cz/",
|
||||
"dev_debug_checkbox": " Enable only if you want to send debuging data to the developer."
|
||||
}
|
||||
},
|
||||
"ecowitt": {
|
||||
"title": "Ecowitt configuration.",
|
||||
"description": "No API ID/KEY needed. Set your Ecowitt station to send data to the enndpoint below.",
|
||||
"data": {
|
||||
"ecowitt_webhook_id": "Unique webhook ID",
|
||||
"ecowitt_enabled": "Enable Ecowitt station data"
|
||||
},
|
||||
"data_description": {
|
||||
"ecowitt_webhook_id": "Set your Ecowitt station to send data to the endpoint: {url}:{port}/weatherhub/{webhook_id}",
|
||||
"ecowitt_enabled": "Enable receiving data from Ecowitt stations"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ def chill_index(data: dict[str, str | float | int], convert: bool = False) -> fl
|
|||
)
|
||||
|
||||
|
||||
def voc_level_to_text(value: str) -> VOCLevel | None:
|
||||
def voc_level_to_text(value: str | None) -> VOCLevel | None:
|
||||
"""Map 1-5 VOC level to text state."""
|
||||
if value in (None, ""):
|
||||
return None
|
||||
|
|
|
|||
Loading…
Reference in New Issue