Netatmo, use nameclass (#53247)

This commit is contained in:
Daniel Hjelseth Høyer 2021-07-21 08:46:01 +02:00 committed by GitHub
parent 7306503756
commit 2cf930f3bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,5 +1,8 @@
"""Support for the Netatmo Weather Service."""
from __future__ import annotations
import logging
from typing import NamedTuple
from homeassistant.components.sensor import SensorEntity
from homeassistant.const import (
@ -51,136 +54,172 @@ SUPPORTED_PUBLIC_SENSOR_TYPES = [
"sum_rain_24",
]
# sensor type: [name, netatmo name, unit of measurement, icon, device class, enable default]
SENSOR_TYPES = {
"temperature": [
class SensorMetadata(NamedTuple):
"""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",
TEMP_CELSIUS,
None,
DEVICE_CLASS_TEMPERATURE,
True,
],
"temp_trend": [
netatmo_name="Temperature",
enable_default=True,
unit=TEMP_CELSIUS,
device_class=DEVICE_CLASS_TEMPERATURE,
),
"temp_trend": SensorMetadata(
"Temperature trend",
"temp_trend",
None,
"mdi:trending-up",
None,
False,
],
"co2": [
netatmo_name="temp_trend",
enable_default=False,
icon="mdi:trending-up",
),
"co2": SensorMetadata(
"CO2",
"CO2",
CONCENTRATION_PARTS_PER_MILLION,
None,
DEVICE_CLASS_CO2,
True,
],
"pressure": [
netatmo_name="CO2",
unit=CONCENTRATION_PARTS_PER_MILLION,
enable_default=True,
device_class=DEVICE_CLASS_CO2,
),
"pressure": SensorMetadata(
"Pressure",
"Pressure",
PRESSURE_MBAR,
None,
DEVICE_CLASS_PRESSURE,
True,
],
"pressure_trend": [
netatmo_name="Pressure",
enable_default=True,
unit=PRESSURE_MBAR,
device_class=DEVICE_CLASS_PRESSURE,
),
"pressure_trend": SensorMetadata(
"Pressure trend",
"pressure_trend",
None,
"mdi:trending-up",
None,
False,
],
"noise": ["Noise", "Noise", SOUND_PRESSURE_DB, "mdi:volume-high", None, True],
"humidity": ["Humidity", "Humidity", PERCENTAGE, None, DEVICE_CLASS_HUMIDITY, True],
"rain": ["Rain", "Rain", LENGTH_MILLIMETERS, "mdi:weather-rainy", None, True],
"sum_rain_1": [
netatmo_name="pressure_trend",
enable_default=False,
icon="mdi:trending-up",
),
"noise": SensorMetadata(
"Noise",
netatmo_name="Noise",
enable_default=True,
unit=SOUND_PRESSURE_DB,
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",
"sum_rain_1",
LENGTH_MILLIMETERS,
"mdi:weather-rainy",
None,
False,
],
"sum_rain_24": [
enable_default=False,
netatmo_name="sum_rain_1",
unit=LENGTH_MILLIMETERS,
icon="mdi:weather-rainy",
),
"sum_rain_24": SensorMetadata(
"Rain today",
"sum_rain_24",
LENGTH_MILLIMETERS,
"mdi:weather-rainy",
None,
True,
],
"battery_percent": [
enable_default=True,
netatmo_name="sum_rain_24",
unit=LENGTH_MILLIMETERS,
icon="mdi:weather-rainy",
),
"battery_percent": SensorMetadata(
"Battery Percent",
"battery_percent",
PERCENTAGE,
None,
DEVICE_CLASS_BATTERY,
True,
],
"windangle": ["Direction", "WindAngle", None, "mdi:compass-outline", None, True],
"windangle_value": [
netatmo_name="battery_percent",
enable_default=True,
unit=PERCENTAGE,
device_class=DEVICE_CLASS_BATTERY,
),
"windangle": SensorMetadata(
"Direction",
netatmo_name="WindAngle",
enable_default=True,
icon="mdi:compass-outline",
),
"windangle_value": SensorMetadata(
"Angle",
"WindAngle",
DEGREE,
"mdi:compass-outline",
None,
False,
],
"windstrength": [
netatmo_name="WindAngle",
enable_default=False,
unit=DEGREE,
icon="mdi:compass-outline",
),
"windstrength": SensorMetadata(
"Wind Strength",
"WindStrength",
SPEED_KILOMETERS_PER_HOUR,
"mdi:weather-windy",
None,
True,
],
"gustangle": [
netatmo_name="WindStrength",
enable_default=True,
unit=SPEED_KILOMETERS_PER_HOUR,
icon="mdi:weather-windy",
),
"gustangle": SensorMetadata(
"Gust Direction",
"GustAngle",
None,
"mdi:compass-outline",
None,
False,
],
"gustangle_value": [
netatmo_name="GustAngle",
enable_default=False,
icon="mdi:compass-outline",
),
"gustangle_value": SensorMetadata(
"Gust Angle",
"GustAngle",
DEGREE,
"mdi:compass-outline",
None,
False,
],
"guststrength": [
netatmo_name="GustAngle",
enable_default=False,
unit=DEGREE,
icon="mdi:compass-outline",
),
"guststrength": SensorMetadata(
"Gust Strength",
"GustStrength",
SPEED_KILOMETERS_PER_HOUR,
"mdi:weather-windy",
None,
False,
],
"reachable": ["Reachability", "reachable", None, "mdi:signal", None, False],
"rf_status": ["Radio", "rf_status", None, "mdi:signal", None, False],
"rf_status_lvl": [
netatmo_name="GustStrength",
enable_default=False,
unit=SPEED_KILOMETERS_PER_HOUR,
icon="mdi:weather-windy",
),
"reachable": SensorMetadata(
"Reachability",
netatmo_name="reachable",
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",
"rf_status",
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
None,
DEVICE_CLASS_SIGNAL_STRENGTH,
False,
],
"wifi_status": ["Wifi", "wifi_status", None, "mdi:wifi", None, False],
"wifi_status_lvl": [
netatmo_name="rf_status",
enable_default=False,
unit=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
),
"wifi_status": SensorMetadata(
"Wifi",
netatmo_name="wifi_status",
enable_default=False,
icon="mdi:wifi",
),
"wifi_status_lvl": SensorMetadata(
"Wifi Level",
"wifi_status",
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
None,
DEVICE_CLASS_SIGNAL_STRENGTH,
False,
],
"health_idx": ["Health", "health_idx", None, "mdi:cloud", None, True],
netatmo_name="wifi_status",
enable_default=False,
unit=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
),
"health_idx": SensorMetadata(
"Health",
enable_default=True,
netatmo_name="health_idx",
icon="mdi:cloud",
),
}
MODULE_TYPE_OUTDOOR = "NAModule1"
@ -188,11 +227,41 @@ MODULE_TYPE_WIND = "NAModule2"
MODULE_TYPE_RAIN = "NAModule3"
MODULE_TYPE_INDOOR = "NAModule4"
class BatteryData(NamedTuple):
"""Metadata for a batter."""
full: int
high: int
medium: int
low: int
BATTERY_VALUES = {
MODULE_TYPE_WIND: {"Full": 5590, "High": 5180, "Medium": 4770, "Low": 4360},
MODULE_TYPE_RAIN: {"Full": 5500, "High": 5000, "Medium": 4500, "Low": 4000},
MODULE_TYPE_INDOOR: {"Full": 5500, "High": 5280, "Medium": 4920, "Low": 4560},
MODULE_TYPE_OUTDOOR: {"Full": 5500, "High": 5000, "Medium": 4500, "Low": 4000},
MODULE_TYPE_WIND: BatteryData(
full=5590,
high=5180,
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"
@ -331,6 +400,8 @@ class NetatmoSensor(NetatmoBase, SensorEntity):
"""Initialize the sensor."""
super().__init__(data_handler)
metadata: SensorMetadata = SENSOR_TYPES[sensor_type]
self._data_classes.append(
{"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'])}"
)
self._attr_name = (
f"{MANUFACTURER} {self._device_name} {SENSOR_TYPES[sensor_type][0]}"
)
self._attr_name = f"{MANUFACTURER} {self._device_name} {metadata.name}"
self.type = sensor_type
self._attr_device_class = SENSOR_TYPES[self.type][4]
self._attr_icon = SENSOR_TYPES[self.type][3]
self._attr_unit_of_measurement = SENSOR_TYPES[self.type][2]
self._attr_device_class = metadata.device_class
self._attr_icon = metadata.icon
self._attr_unit_of_measurement = metadata.unit
self._model = device["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
def available(self):
@ -395,7 +464,7 @@ class NetatmoSensor(NetatmoBase, SensorEntity):
return
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"}:
self._attr_state = round(state, 1)
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:
"""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"
if data >= values["High"]:
if data >= battery_data.high:
return "High"
if data >= values["Medium"]:
if data >= battery_data.medium:
return "Medium"
if data >= values["Low"]:
if data >= battery_data.low:
return "Low"
return "Very Low"
@ -518,6 +587,7 @@ class NetatmoPublicSensor(NetatmoBase, SensorEntity):
SIGNAL_NAME: self._signal_name,
}
)
metadata: SensorMetadata = SENSOR_TYPES[sensor_type]
self.type = sensor_type
self.area = area
@ -525,12 +595,10 @@ class NetatmoPublicSensor(NetatmoBase, SensorEntity):
self._area_name = area.area_name
self._id = self._area_name
self._device_name = f"{self._area_name}"
self._attr_name = (
f"{MANUFACTURER} {self._device_name} {SENSOR_TYPES[self.type][0]}"
)
self._attr_device_class = SENSOR_TYPES[self.type][4]
self._attr_icon = SENSOR_TYPES[self.type][3]
self._attr_unit_of_measurement = SENSOR_TYPES[self.type][2]
self._attr_name = f"{MANUFACTURER} {self._device_name} {metadata.name}"
self._attr_device_class = metadata.device_class
self._attr_icon = metadata.icon
self._attr_unit_of_measurement = metadata.unit
self._show_on_map = area.show_on_map
self._attr_unique_id = f"{self._device_name.replace(' ', '-')}-{self.type}"
self._model = PUBLIC