Merge pull request #13 from schizza/Bearing

New sensor fo Azimut now supported.

A new constant WIND_AZIMUT is added to allow creating a wind direction sensor that returns a text value from UnitOfDir instead of just a numeric degree value.

The wind direction sensor entity now optionally creates both a numeric wind direction sensor using WIND_DIR and a text-based azimuth sensor using WIND_AZIMUT. If the numeric one is enabled, the text one will also be added.

So in summary, these changes improve the usability of wind data by adding a more human-readable text version alongside the existing numeric version.
pull/14/head v1.3.1
schizza 2024-04-18 21:14:53 +02:00 committed by GitHub
commit 80e5f5a4ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 137 additions and 4 deletions

View File

@ -1,5 +1,6 @@
"""Constants.""" """Constants."""
from enum import StrEnum
from typing import Final from typing import Final
DOMAIN = "sws12500" DOMAIN = "sws12500"
@ -59,6 +60,7 @@ OUTSIDE_HUMIDITY: Final = "outside_humidity"
WIND_SPEED: Final = "wind_speed" WIND_SPEED: Final = "wind_speed"
WIND_GUST: Final = "wind_gust" WIND_GUST: Final = "wind_gust"
WIND_DIR: Final = "wind_dir" WIND_DIR: Final = "wind_dir"
WIND_AZIMUT: Final = "wind_azimut"
RAIN: Final = "rain" RAIN: Final = "rain"
DAILY_RAIN: Final = "daily_rain" DAILY_RAIN: Final = "daily_rain"
SOLAR_RADIATION: Final = "solar_radiation" SOLAR_RADIATION: Final = "solar_radiation"
@ -89,3 +91,41 @@ REMAP_ITEMS: dict = {
DISABLED_BY_DEFAULT: Final = [CH2_TEMP, CH2_HUMIDITY] DISABLED_BY_DEFAULT: Final = [CH2_TEMP, CH2_HUMIDITY]
class UnitOfDir(StrEnum):
"""Wind direrction azimut."""
NNE = "NNE"
NE = "NE"
ENE = "ENE"
E = "E"
ESE = "ESE"
SE = "SE"
SSE = "SSE"
S = "S"
SSW = "SSW"
SW = "SW"
WSW = "WSW"
W = "W"
WNW = "WNW"
NW = "NW"
NNW = "NNW"
N = "N"
AZIMUT: list[UnitOfDir] = [
UnitOfDir.NNE,
UnitOfDir.NE,
UnitOfDir.ENE,
UnitOfDir.E,
UnitOfDir.ESE,
UnitOfDir.SE,
UnitOfDir.SSE,
UnitOfDir.S,
UnitOfDir.SSW,
UnitOfDir.SW,
UnitOfDir.WSW,
UnitOfDir.W,
UnitOfDir.WNW,
UnitOfDir.NW,
UnitOfDir.NNW,
UnitOfDir.N,
]

View File

@ -45,10 +45,13 @@ from .const import (
SENSORS_TO_LOAD, SENSORS_TO_LOAD,
SOLAR_RADIATION, SOLAR_RADIATION,
UV, UV,
WIND_AZIMUT,
WIND_DIR, WIND_DIR,
WIND_GUST, WIND_GUST,
WIND_SPEED, WIND_SPEED,
UnitOfDir,
) )
from .utils import wind_dir_to_text
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -145,6 +148,14 @@ SENSOR_TYPES: tuple[WeatherSensorEntityDescription, ...] = (
translation_key=WIND_DIR, translation_key=WIND_DIR,
value_fn=lambda data: cast(int, data), 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( WeatherSensorEntityDescription(
key=RAIN, key=RAIN,
native_unit_of_measurement=UnitOfPrecipitationDepth.INCHES, native_unit_of_measurement=UnitOfPrecipitationDepth.INCHES,
@ -221,6 +232,8 @@ async def async_setup_entry(
# 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):
if WIND_DIR in sensors_to_load:
sensors_to_load.append(WIND_AZIMUT)
sensors = [ sensors = [
WeatherSensor(hass, description, coordinator) WeatherSensor(hass, description, coordinator)
for description in SENSOR_TYPES for description in SENSOR_TYPES
@ -276,6 +289,10 @@ class WeatherSensor(
@property @property
def native_value(self) -> str | int | float | None: def native_value(self) -> str | int | float | None:
"""Return value of entity.""" """Return value of entity."""
if self.coordinator.data and (WIND_AZIMUT in self.entity_description.key):
return self.entity_description.value_fn(self.coordinator.data.get(WIND_DIR))
return self.entity_description.value_fn(self._data) return self.entity_description.value_fn(self._data)
@property @property

View File

@ -76,7 +76,28 @@
"daily_rain": { "name": "Daily precipitation" }, "daily_rain": { "name": "Daily precipitation" },
"solar_radiation": { "name": "Solar irradiance" }, "solar_radiation": { "name": "Solar irradiance" },
"ch2_temp": { "name": "Channel 2 temperature" }, "ch2_temp": { "name": "Channel 2 temperature" },
"ch2_humidity": { "name": "Channel 2 humidity" } "ch2_humidity": { "name": "Channel 2 humidity" },
"wind_azimut": {
"name": "Bearing",
"state": {
"N": "N",
"NNE": "NNE",
"NE": "NE",
"ENE": "ENE",
"E": "E",
"ESE": "ESE",
"SE": "SE",
"SSE": "SSE",
"S": "S",
"SSW": "SSW",
"SW": "SW",
"WSW": "WSW",
"W": "W",
"WNW": "WNW",
"NW": "NW",
"NNW": "NNW"
}
}
} }
}, },
"notify": { "notify": {

View File

@ -75,7 +75,28 @@
"daily_rain": { "name": "Denní úhrn srážek" }, "daily_rain": { "name": "Denní úhrn srážek" },
"solar_radiation": { "name": "Sluneční osvit" }, "solar_radiation": { "name": "Sluneční osvit" },
"ch2_temp": { "name": "Teplota senzoru 2" }, "ch2_temp": { "name": "Teplota senzoru 2" },
"ch2_humidity": { "name": "Vlhkost sensoru 2" } "ch2_humidity": { "name": "Vlhkost sensoru 2" },
"wind_azimut": {
"name": "Azimut",
"state": {
"N": "S",
"NNE": "SSV",
"NE": "SV",
"ENE": "VVS",
"E": "V",
"ESE": "VVJ",
"SE": "JV",
"SSE": "JJV",
"S": "J",
"SSW": "JJZ",
"SW": "JZ",
"WSW": "JZZ",
"W": "Z",
"WNW": "ZZS",
"NW": "SZ",
"NNW": "SSZ"
}
}
} }
}, },
"notify": { "notify": {

View File

@ -76,7 +76,28 @@
"daily_rain": { "name": "Daily precipitation" }, "daily_rain": { "name": "Daily precipitation" },
"solar_radiation": { "name": "Solar irradiance" }, "solar_radiation": { "name": "Solar irradiance" },
"ch2_temp": { "name": "Channel 2 temperature" }, "ch2_temp": { "name": "Channel 2 temperature" },
"ch2_humidity": { "name": "Channel 2 humidity" } "ch2_humidity": { "name": "Channel 2 humidity" },
"wind_azimut": {
"name": "Bearing",
"state": {
"N": "N",
"NNE": "NNE",
"NE": "NE",
"ENE": "ENE",
"E": "E",
"ESE": "ESE",
"SE": "SE",
"SSE": "SSE",
"S": "S",
"SSW": "SSW",
"SW": "SW",
"WSW": "WSW",
"W": "W",
"WNW": "WNW",
"NW": "NW",
"NNW": "NNW"
}
}
} }
}, },
"notify": { "notify": {

View File

@ -7,7 +7,7 @@ from homeassistant.config_entries import ConfigEntry
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 .const import DEV_DBG, REMAP_ITEMS, SENSORS_TO_LOAD from .const import AZIMUT, DEV_DBG, REMAP_ITEMS, SENSORS_TO_LOAD, UnitOfDir
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -128,3 +128,16 @@ def check_disabled(
_LOGGER.info("Add sensor (%s) to loading queue", item) _LOGGER.info("Add sensor (%s) to loading queue", item)
return missing_sensors if entityFound else None return missing_sensors if entityFound else None
def wind_dir_to_text(deg: float) -> UnitOfDir | None:
"""Return wind direction in text representation.
Returns UnitOfDir or None
"""
if deg:
return AZIMUT[int(abs((float(deg) - 11.25) % 360) / 22.5)]
return None