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
commit
80e5f5a4ed
|
|
@ -1,5 +1,6 @@
|
|||
"""Constants."""
|
||||
|
||||
from enum import StrEnum
|
||||
from typing import Final
|
||||
|
||||
DOMAIN = "sws12500"
|
||||
|
|
@ -59,6 +60,7 @@ OUTSIDE_HUMIDITY: Final = "outside_humidity"
|
|||
WIND_SPEED: Final = "wind_speed"
|
||||
WIND_GUST: Final = "wind_gust"
|
||||
WIND_DIR: Final = "wind_dir"
|
||||
WIND_AZIMUT: Final = "wind_azimut"
|
||||
RAIN: Final = "rain"
|
||||
DAILY_RAIN: Final = "daily_rain"
|
||||
SOLAR_RADIATION: Final = "solar_radiation"
|
||||
|
|
@ -89,3 +91,41 @@ REMAP_ITEMS: dict = {
|
|||
|
||||
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,
|
||||
]
|
||||
|
|
|
|||
|
|
@ -45,10 +45,13 @@ from .const import (
|
|||
SENSORS_TO_LOAD,
|
||||
SOLAR_RADIATION,
|
||||
UV,
|
||||
WIND_AZIMUT,
|
||||
WIND_DIR,
|
||||
WIND_GUST,
|
||||
WIND_SPEED,
|
||||
UnitOfDir,
|
||||
)
|
||||
from .utils import wind_dir_to_text
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -145,6 +148,14 @@ SENSOR_TYPES: tuple[WeatherSensorEntityDescription, ...] = (
|
|||
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,
|
||||
|
|
@ -221,6 +232,8 @@ async def async_setup_entry(
|
|||
|
||||
# Check if we have some 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 = [
|
||||
WeatherSensor(hass, description, coordinator)
|
||||
for description in SENSOR_TYPES
|
||||
|
|
@ -276,6 +289,10 @@ class WeatherSensor(
|
|||
@property
|
||||
def native_value(self) -> str | int | float | None:
|
||||
"""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)
|
||||
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -76,7 +76,28 @@
|
|||
"daily_rain": { "name": "Daily precipitation" },
|
||||
"solar_radiation": { "name": "Solar irradiance" },
|
||||
"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": {
|
||||
|
|
|
|||
|
|
@ -75,7 +75,28 @@
|
|||
"daily_rain": { "name": "Denní úhrn srážek" },
|
||||
"solar_radiation": { "name": "Sluneční osvit" },
|
||||
"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": {
|
||||
|
|
|
|||
|
|
@ -76,7 +76,28 @@
|
|||
"daily_rain": { "name": "Daily precipitation" },
|
||||
"solar_radiation": { "name": "Solar irradiance" },
|
||||
"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": {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from homeassistant.config_entries import ConfigEntry
|
|||
from homeassistant.core import HomeAssistant
|
||||
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__)
|
||||
|
||||
|
|
@ -128,3 +128,16 @@ def check_disabled(
|
|||
_LOGGER.info("Add sensor (%s) to loading queue", item)
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue