mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Netatmo, use nameclass (#53247)
This commit is contained in:
parent
7306503756
commit
2cf930f3bd
@ -1,5 +1,8 @@
|
|||||||
"""Support for the Netatmo Weather Service."""
|
"""Support for the Netatmo Weather Service."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
from typing import NamedTuple
|
||||||
|
|
||||||
from homeassistant.components.sensor import SensorEntity
|
from homeassistant.components.sensor import SensorEntity
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
@ -51,136 +54,172 @@ SUPPORTED_PUBLIC_SENSOR_TYPES = [
|
|||||||
"sum_rain_24",
|
"sum_rain_24",
|
||||||
]
|
]
|
||||||
|
|
||||||
# sensor type: [name, netatmo name, unit of measurement, icon, device class, enable default]
|
|
||||||
SENSOR_TYPES = {
|
class SensorMetadata(NamedTuple):
|
||||||
"temperature": [
|
"""Metadata for an individual sensor."""
|
||||||
|
|
||||||
|
name: str
|
||||||
|
netatmo_name: str
|
||||||
|
enable_default: bool
|
||||||
|
unit: str | None = None
|
||||||
|
icon: str | None = None
|
||||||
|
device_class: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
SENSOR_TYPES: dict[str, SensorMetadata] = {
|
||||||
|
"temperature": SensorMetadata(
|
||||||
"Temperature",
|
"Temperature",
|
||||||
"Temperature",
|
netatmo_name="Temperature",
|
||||||
TEMP_CELSIUS,
|
enable_default=True,
|
||||||
None,
|
unit=TEMP_CELSIUS,
|
||||||
DEVICE_CLASS_TEMPERATURE,
|
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||||
True,
|
),
|
||||||
],
|
"temp_trend": SensorMetadata(
|
||||||
"temp_trend": [
|
|
||||||
"Temperature trend",
|
"Temperature trend",
|
||||||
"temp_trend",
|
netatmo_name="temp_trend",
|
||||||
None,
|
enable_default=False,
|
||||||
"mdi:trending-up",
|
icon="mdi:trending-up",
|
||||||
None,
|
),
|
||||||
False,
|
"co2": SensorMetadata(
|
||||||
],
|
|
||||||
"co2": [
|
|
||||||
"CO2",
|
"CO2",
|
||||||
"CO2",
|
netatmo_name="CO2",
|
||||||
CONCENTRATION_PARTS_PER_MILLION,
|
unit=CONCENTRATION_PARTS_PER_MILLION,
|
||||||
None,
|
enable_default=True,
|
||||||
DEVICE_CLASS_CO2,
|
device_class=DEVICE_CLASS_CO2,
|
||||||
True,
|
),
|
||||||
],
|
"pressure": SensorMetadata(
|
||||||
"pressure": [
|
|
||||||
"Pressure",
|
"Pressure",
|
||||||
"Pressure",
|
netatmo_name="Pressure",
|
||||||
PRESSURE_MBAR,
|
enable_default=True,
|
||||||
None,
|
unit=PRESSURE_MBAR,
|
||||||
DEVICE_CLASS_PRESSURE,
|
device_class=DEVICE_CLASS_PRESSURE,
|
||||||
True,
|
),
|
||||||
],
|
"pressure_trend": SensorMetadata(
|
||||||
"pressure_trend": [
|
|
||||||
"Pressure trend",
|
"Pressure trend",
|
||||||
"pressure_trend",
|
netatmo_name="pressure_trend",
|
||||||
None,
|
enable_default=False,
|
||||||
"mdi:trending-up",
|
icon="mdi:trending-up",
|
||||||
None,
|
),
|
||||||
False,
|
"noise": SensorMetadata(
|
||||||
],
|
"Noise",
|
||||||
"noise": ["Noise", "Noise", SOUND_PRESSURE_DB, "mdi:volume-high", None, True],
|
netatmo_name="Noise",
|
||||||
"humidity": ["Humidity", "Humidity", PERCENTAGE, None, DEVICE_CLASS_HUMIDITY, True],
|
enable_default=True,
|
||||||
"rain": ["Rain", "Rain", LENGTH_MILLIMETERS, "mdi:weather-rainy", None, True],
|
unit=SOUND_PRESSURE_DB,
|
||||||
"sum_rain_1": [
|
icon="mdi:volume-high",
|
||||||
|
),
|
||||||
|
"humidity": SensorMetadata(
|
||||||
|
"Humidity",
|
||||||
|
netatmo_name="Humidity",
|
||||||
|
enable_default=True,
|
||||||
|
unit=PERCENTAGE,
|
||||||
|
device_class=DEVICE_CLASS_HUMIDITY,
|
||||||
|
),
|
||||||
|
"rain": SensorMetadata(
|
||||||
|
"Rain",
|
||||||
|
netatmo_name="Rain",
|
||||||
|
enable_default=True,
|
||||||
|
unit=LENGTH_MILLIMETERS,
|
||||||
|
icon="mdi:weather-rainy",
|
||||||
|
),
|
||||||
|
"sum_rain_1": SensorMetadata(
|
||||||
"Rain last hour",
|
"Rain last hour",
|
||||||
"sum_rain_1",
|
enable_default=False,
|
||||||
LENGTH_MILLIMETERS,
|
netatmo_name="sum_rain_1",
|
||||||
"mdi:weather-rainy",
|
unit=LENGTH_MILLIMETERS,
|
||||||
None,
|
icon="mdi:weather-rainy",
|
||||||
False,
|
),
|
||||||
],
|
"sum_rain_24": SensorMetadata(
|
||||||
"sum_rain_24": [
|
|
||||||
"Rain today",
|
"Rain today",
|
||||||
"sum_rain_24",
|
enable_default=True,
|
||||||
LENGTH_MILLIMETERS,
|
netatmo_name="sum_rain_24",
|
||||||
"mdi:weather-rainy",
|
unit=LENGTH_MILLIMETERS,
|
||||||
None,
|
icon="mdi:weather-rainy",
|
||||||
True,
|
),
|
||||||
],
|
"battery_percent": SensorMetadata(
|
||||||
"battery_percent": [
|
|
||||||
"Battery Percent",
|
"Battery Percent",
|
||||||
"battery_percent",
|
netatmo_name="battery_percent",
|
||||||
PERCENTAGE,
|
enable_default=True,
|
||||||
None,
|
unit=PERCENTAGE,
|
||||||
DEVICE_CLASS_BATTERY,
|
device_class=DEVICE_CLASS_BATTERY,
|
||||||
True,
|
),
|
||||||
],
|
"windangle": SensorMetadata(
|
||||||
"windangle": ["Direction", "WindAngle", None, "mdi:compass-outline", None, True],
|
"Direction",
|
||||||
"windangle_value": [
|
netatmo_name="WindAngle",
|
||||||
|
enable_default=True,
|
||||||
|
icon="mdi:compass-outline",
|
||||||
|
),
|
||||||
|
"windangle_value": SensorMetadata(
|
||||||
"Angle",
|
"Angle",
|
||||||
"WindAngle",
|
netatmo_name="WindAngle",
|
||||||
DEGREE,
|
enable_default=False,
|
||||||
"mdi:compass-outline",
|
unit=DEGREE,
|
||||||
None,
|
icon="mdi:compass-outline",
|
||||||
False,
|
),
|
||||||
],
|
"windstrength": SensorMetadata(
|
||||||
"windstrength": [
|
|
||||||
"Wind Strength",
|
"Wind Strength",
|
||||||
"WindStrength",
|
netatmo_name="WindStrength",
|
||||||
SPEED_KILOMETERS_PER_HOUR,
|
enable_default=True,
|
||||||
"mdi:weather-windy",
|
unit=SPEED_KILOMETERS_PER_HOUR,
|
||||||
None,
|
icon="mdi:weather-windy",
|
||||||
True,
|
),
|
||||||
],
|
"gustangle": SensorMetadata(
|
||||||
"gustangle": [
|
|
||||||
"Gust Direction",
|
"Gust Direction",
|
||||||
"GustAngle",
|
netatmo_name="GustAngle",
|
||||||
None,
|
enable_default=False,
|
||||||
"mdi:compass-outline",
|
icon="mdi:compass-outline",
|
||||||
None,
|
),
|
||||||
False,
|
"gustangle_value": SensorMetadata(
|
||||||
],
|
|
||||||
"gustangle_value": [
|
|
||||||
"Gust Angle",
|
"Gust Angle",
|
||||||
"GustAngle",
|
netatmo_name="GustAngle",
|
||||||
DEGREE,
|
enable_default=False,
|
||||||
"mdi:compass-outline",
|
unit=DEGREE,
|
||||||
None,
|
icon="mdi:compass-outline",
|
||||||
False,
|
),
|
||||||
],
|
"guststrength": SensorMetadata(
|
||||||
"guststrength": [
|
|
||||||
"Gust Strength",
|
"Gust Strength",
|
||||||
"GustStrength",
|
netatmo_name="GustStrength",
|
||||||
SPEED_KILOMETERS_PER_HOUR,
|
enable_default=False,
|
||||||
"mdi:weather-windy",
|
unit=SPEED_KILOMETERS_PER_HOUR,
|
||||||
None,
|
icon="mdi:weather-windy",
|
||||||
False,
|
),
|
||||||
],
|
"reachable": SensorMetadata(
|
||||||
"reachable": ["Reachability", "reachable", None, "mdi:signal", None, False],
|
"Reachability",
|
||||||
"rf_status": ["Radio", "rf_status", None, "mdi:signal", None, False],
|
netatmo_name="reachable",
|
||||||
"rf_status_lvl": [
|
enable_default=False,
|
||||||
|
icon="mdi:signal",
|
||||||
|
),
|
||||||
|
"rf_status": SensorMetadata(
|
||||||
|
"Radio",
|
||||||
|
netatmo_name="rf_status",
|
||||||
|
enable_default=False,
|
||||||
|
icon="mdi:signal",
|
||||||
|
),
|
||||||
|
"rf_status_lvl": SensorMetadata(
|
||||||
"Radio Level",
|
"Radio Level",
|
||||||
"rf_status",
|
netatmo_name="rf_status",
|
||||||
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
|
enable_default=False,
|
||||||
None,
|
unit=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
|
||||||
DEVICE_CLASS_SIGNAL_STRENGTH,
|
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
False,
|
),
|
||||||
],
|
"wifi_status": SensorMetadata(
|
||||||
"wifi_status": ["Wifi", "wifi_status", None, "mdi:wifi", None, False],
|
"Wifi",
|
||||||
"wifi_status_lvl": [
|
netatmo_name="wifi_status",
|
||||||
|
enable_default=False,
|
||||||
|
icon="mdi:wifi",
|
||||||
|
),
|
||||||
|
"wifi_status_lvl": SensorMetadata(
|
||||||
"Wifi Level",
|
"Wifi Level",
|
||||||
"wifi_status",
|
netatmo_name="wifi_status",
|
||||||
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
|
enable_default=False,
|
||||||
None,
|
unit=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
|
||||||
DEVICE_CLASS_SIGNAL_STRENGTH,
|
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
False,
|
),
|
||||||
],
|
"health_idx": SensorMetadata(
|
||||||
"health_idx": ["Health", "health_idx", None, "mdi:cloud", None, True],
|
"Health",
|
||||||
|
enable_default=True,
|
||||||
|
netatmo_name="health_idx",
|
||||||
|
icon="mdi:cloud",
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_TYPE_OUTDOOR = "NAModule1"
|
MODULE_TYPE_OUTDOOR = "NAModule1"
|
||||||
@ -188,11 +227,41 @@ MODULE_TYPE_WIND = "NAModule2"
|
|||||||
MODULE_TYPE_RAIN = "NAModule3"
|
MODULE_TYPE_RAIN = "NAModule3"
|
||||||
MODULE_TYPE_INDOOR = "NAModule4"
|
MODULE_TYPE_INDOOR = "NAModule4"
|
||||||
|
|
||||||
|
|
||||||
|
class BatteryData(NamedTuple):
|
||||||
|
"""Metadata for a batter."""
|
||||||
|
|
||||||
|
full: int
|
||||||
|
high: int
|
||||||
|
medium: int
|
||||||
|
low: int
|
||||||
|
|
||||||
|
|
||||||
BATTERY_VALUES = {
|
BATTERY_VALUES = {
|
||||||
MODULE_TYPE_WIND: {"Full": 5590, "High": 5180, "Medium": 4770, "Low": 4360},
|
MODULE_TYPE_WIND: BatteryData(
|
||||||
MODULE_TYPE_RAIN: {"Full": 5500, "High": 5000, "Medium": 4500, "Low": 4000},
|
full=5590,
|
||||||
MODULE_TYPE_INDOOR: {"Full": 5500, "High": 5280, "Medium": 4920, "Low": 4560},
|
high=5180,
|
||||||
MODULE_TYPE_OUTDOOR: {"Full": 5500, "High": 5000, "Medium": 4500, "Low": 4000},
|
medium=4770,
|
||||||
|
low=4360,
|
||||||
|
),
|
||||||
|
MODULE_TYPE_RAIN: BatteryData(
|
||||||
|
full=5500,
|
||||||
|
high=5000,
|
||||||
|
medium=4500,
|
||||||
|
low=4000,
|
||||||
|
),
|
||||||
|
MODULE_TYPE_INDOOR: BatteryData(
|
||||||
|
full=5500,
|
||||||
|
high=5280,
|
||||||
|
medium=4920,
|
||||||
|
low=4560,
|
||||||
|
),
|
||||||
|
MODULE_TYPE_OUTDOOR: BatteryData(
|
||||||
|
full=5500,
|
||||||
|
high=5000,
|
||||||
|
medium=4500,
|
||||||
|
low=4000,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
PUBLIC = "public"
|
PUBLIC = "public"
|
||||||
@ -331,6 +400,8 @@ class NetatmoSensor(NetatmoBase, SensorEntity):
|
|||||||
"""Initialize the sensor."""
|
"""Initialize the sensor."""
|
||||||
super().__init__(data_handler)
|
super().__init__(data_handler)
|
||||||
|
|
||||||
|
metadata: SensorMetadata = SENSOR_TYPES[sensor_type]
|
||||||
|
|
||||||
self._data_classes.append(
|
self._data_classes.append(
|
||||||
{"name": data_class_name, SIGNAL_NAME: data_class_name}
|
{"name": data_class_name, SIGNAL_NAME: data_class_name}
|
||||||
)
|
)
|
||||||
@ -353,16 +424,14 @@ class NetatmoSensor(NetatmoBase, SensorEntity):
|
|||||||
f"{module_info.get('module_name', device['type'])}"
|
f"{module_info.get('module_name', device['type'])}"
|
||||||
)
|
)
|
||||||
|
|
||||||
self._attr_name = (
|
self._attr_name = f"{MANUFACTURER} {self._device_name} {metadata.name}"
|
||||||
f"{MANUFACTURER} {self._device_name} {SENSOR_TYPES[sensor_type][0]}"
|
|
||||||
)
|
|
||||||
self.type = sensor_type
|
self.type = sensor_type
|
||||||
self._attr_device_class = SENSOR_TYPES[self.type][4]
|
self._attr_device_class = metadata.device_class
|
||||||
self._attr_icon = SENSOR_TYPES[self.type][3]
|
self._attr_icon = metadata.icon
|
||||||
self._attr_unit_of_measurement = SENSOR_TYPES[self.type][2]
|
self._attr_unit_of_measurement = metadata.unit
|
||||||
self._model = device["type"]
|
self._model = device["type"]
|
||||||
self._attr_unique_id = f"{self._id}-{self.type}"
|
self._attr_unique_id = f"{self._id}-{self.type}"
|
||||||
self._attr_entity_registry_enabled_default = SENSOR_TYPES[self.type][5]
|
self._attr_entity_registry_enabled_default = metadata.enable_default
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self):
|
def available(self):
|
||||||
@ -395,7 +464,7 @@ class NetatmoSensor(NetatmoBase, SensorEntity):
|
|||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
state = data[SENSOR_TYPES[self.type][1]]
|
state = data[SENSOR_TYPES[self.type].netatmo_name]
|
||||||
if self.type in {"temperature", "pressure", "sum_rain_1"}:
|
if self.type in {"temperature", "pressure", "sum_rain_1"}:
|
||||||
self._attr_state = round(state, 1)
|
self._attr_state = round(state, 1)
|
||||||
elif self.type in {"windangle_value", "gustangle_value"}:
|
elif self.type in {"windangle_value", "gustangle_value"}:
|
||||||
@ -449,15 +518,15 @@ def process_angle(angle: int) -> str:
|
|||||||
|
|
||||||
def process_battery(data: int, model: str) -> str:
|
def process_battery(data: int, model: str) -> str:
|
||||||
"""Process battery data and return string for display."""
|
"""Process battery data and return string for display."""
|
||||||
values = BATTERY_VALUES[model]
|
battery_data = BATTERY_VALUES[model]
|
||||||
|
|
||||||
if data >= values["Full"]:
|
if data >= battery_data.full:
|
||||||
return "Full"
|
return "Full"
|
||||||
if data >= values["High"]:
|
if data >= battery_data.high:
|
||||||
return "High"
|
return "High"
|
||||||
if data >= values["Medium"]:
|
if data >= battery_data.medium:
|
||||||
return "Medium"
|
return "Medium"
|
||||||
if data >= values["Low"]:
|
if data >= battery_data.low:
|
||||||
return "Low"
|
return "Low"
|
||||||
return "Very Low"
|
return "Very Low"
|
||||||
|
|
||||||
@ -518,6 +587,7 @@ class NetatmoPublicSensor(NetatmoBase, SensorEntity):
|
|||||||
SIGNAL_NAME: self._signal_name,
|
SIGNAL_NAME: self._signal_name,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
metadata: SensorMetadata = SENSOR_TYPES[sensor_type]
|
||||||
|
|
||||||
self.type = sensor_type
|
self.type = sensor_type
|
||||||
self.area = area
|
self.area = area
|
||||||
@ -525,12 +595,10 @@ class NetatmoPublicSensor(NetatmoBase, SensorEntity):
|
|||||||
self._area_name = area.area_name
|
self._area_name = area.area_name
|
||||||
self._id = self._area_name
|
self._id = self._area_name
|
||||||
self._device_name = f"{self._area_name}"
|
self._device_name = f"{self._area_name}"
|
||||||
self._attr_name = (
|
self._attr_name = f"{MANUFACTURER} {self._device_name} {metadata.name}"
|
||||||
f"{MANUFACTURER} {self._device_name} {SENSOR_TYPES[self.type][0]}"
|
self._attr_device_class = metadata.device_class
|
||||||
)
|
self._attr_icon = metadata.icon
|
||||||
self._attr_device_class = SENSOR_TYPES[self.type][4]
|
self._attr_unit_of_measurement = metadata.unit
|
||||||
self._attr_icon = SENSOR_TYPES[self.type][3]
|
|
||||||
self._attr_unit_of_measurement = SENSOR_TYPES[self.type][2]
|
|
||||||
self._show_on_map = area.show_on_map
|
self._show_on_map = area.show_on_map
|
||||||
self._attr_unique_id = f"{self._device_name.replace(' ', '-')}-{self.type}"
|
self._attr_unique_id = f"{self._device_name.replace(' ', '-')}-{self.type}"
|
||||||
self._model = PUBLIC
|
self._model = PUBLIC
|
||||||
|
Loading…
x
Reference in New Issue
Block a user