Use entity class attributes for buienradar (#53166)

This commit is contained in:
Robert Hillis 2021-07-19 15:22:20 -04:00 committed by GitHub
parent 8527179c0e
commit f5b3118d3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 122 deletions

View File

@ -356,32 +356,29 @@ async def async_setup_entry(
class BrSensor(SensorEntity): class BrSensor(SensorEntity):
"""Representation of an Buienradar sensor.""" """Representation of an Buienradar sensor."""
_attr_entity_registry_enabled_default = False
_attr_should_poll = False
def __init__(self, sensor_type, client_name, coordinates): def __init__(self, sensor_type, client_name, coordinates):
"""Initialize the sensor.""" """Initialize the sensor."""
self.client_name = client_name self._attr_name = f"{client_name} {SENSOR_TYPES[sensor_type][0]}"
self._name = SENSOR_TYPES[sensor_type][0] self._attr_icon = SENSOR_TYPES[sensor_type][2]
self.type = sensor_type self.type = sensor_type
self._state = None self._attr_unit_of_measurement = SENSOR_TYPES[sensor_type][1]
self._unit_of_measurement = SENSOR_TYPES[self.type][1]
self._entity_picture = None
self._attribution = None
self._measured = None self._measured = None
self._stationname = None self._attr_unique_id = "{:2.6f}{:2.6f}{}".format(
self._unique_id = self.uid(coordinates) coordinates[CONF_LATITUDE], coordinates[CONF_LONGITUDE], sensor_type
)
self._attr_device_class = SENSOR_TYPES[sensor_type][3]
# All continuous sensors should be forced to be updated # All continuous sensors should be forced to be updated
self._force_update = self.type != SYMBOL and not self.type.startswith(CONDITION) self._attr_force_update = sensor_type != SYMBOL and not sensor_type.startswith(
CONDITION
if self.type.startswith(PRECIPITATION_FORECAST):
self._timeframe = None
def uid(self, coordinates):
"""Generate a unique id using coordinates and sensor type."""
# The combination of the location, name and sensor type is unique
return "{:2.6f}{:2.6f}{}".format(
coordinates[CONF_LATITUDE], coordinates[CONF_LONGITUDE], self.type
) )
if sensor_type.startswith(PRECIPITATION_FORECAST):
self._timeframe = None
@callback @callback
def data_updated(self, data): def data_updated(self, data):
"""Update data.""" """Update data."""
@ -398,8 +395,6 @@ class BrSensor(SensorEntity):
if self._measured == data.get(MEASURED): if self._measured == data.get(MEASURED):
return False return False
self._attribution = data.get(ATTRIBUTION)
self._stationname = data.get(STATIONNAME)
self._measured = data.get(MEASURED) self._measured = data.get(MEASURED)
if ( if (
@ -442,18 +437,18 @@ class BrSensor(SensorEntity):
img = condition.get(IMAGE) img = condition.get(IMAGE)
if new_state != self._state or img != self._entity_picture: if new_state != self.state or img != self.entity_picture:
self._state = new_state self._attr_state = new_state
self._entity_picture = img self._attr_entity_picture = img
return True return True
return False return False
if self.type.startswith(WINDSPEED): if self.type.startswith(WINDSPEED):
# hass wants windspeeds in km/h not m/s, so convert: # hass wants windspeeds in km/h not m/s, so convert:
try: try:
self._state = data.get(FORECAST)[fcday].get(self.type[:-3]) self._attr_state = data.get(FORECAST)[fcday].get(self.type[:-3])
if self._state is not None: if self.state is not None:
self._state = round(self._state * 3.6, 1) self._attr_state = round(self.state * 3.6, 1)
return True return True
except IndexError: except IndexError:
_LOGGER.warning("No forecast for fcday=%s", fcday) _LOGGER.warning("No forecast for fcday=%s", fcday)
@ -461,7 +456,7 @@ class BrSensor(SensorEntity):
# update all other sensors # update all other sensors
try: try:
self._state = data.get(FORECAST)[fcday].get(self.type[:-3]) self._attr_state = data.get(FORECAST)[fcday].get(self.type[:-3])
return True return True
except IndexError: except IndexError:
_LOGGER.warning("No forecast for fcday=%s", fcday) _LOGGER.warning("No forecast for fcday=%s", fcday)
@ -484,9 +479,9 @@ class BrSensor(SensorEntity):
img = condition.get(IMAGE) img = condition.get(IMAGE)
if new_state != self._state or img != self._entity_picture: if new_state != self.state or img != self.entity_picture:
self._state = new_state self._attr_state = new_state
self._entity_picture = img self._attr_entity_picture = img
return True return True
return False return False
@ -495,99 +490,40 @@ class BrSensor(SensorEntity):
# update nested precipitation forecast sensors # update nested precipitation forecast sensors
nested = data.get(PRECIPITATION_FORECAST) nested = data.get(PRECIPITATION_FORECAST)
self._timeframe = nested.get(TIMEFRAME) self._timeframe = nested.get(TIMEFRAME)
self._state = nested.get(self.type[len(PRECIPITATION_FORECAST) + 1 :]) self._attr_state = nested.get(self.type[len(PRECIPITATION_FORECAST) + 1 :])
return True return True
if self.type in [WINDSPEED, WINDGUST]: if self.type in [WINDSPEED, WINDGUST]:
# hass wants windspeeds in km/h not m/s, so convert: # hass wants windspeeds in km/h not m/s, so convert:
self._state = data.get(self.type) self._attr_state = data.get(self.type)
if self._state is not None: if self.state is not None:
self._state = round(data.get(self.type) * 3.6, 1) self._attr_state = round(data.get(self.type) * 3.6, 1)
return True return True
if self.type == VISIBILITY: if self.type == VISIBILITY:
# hass wants visibility in km (not m), so convert: # hass wants visibility in km (not m), so convert:
self._state = data.get(self.type) self._attr_state = data.get(self.type)
if self._state is not None: if self.state is not None:
self._state = round(self._state / 1000, 1) self._attr_state = round(self.state / 1000, 1)
return True return True
# update all other sensors # update all other sensors
self._state = data.get(self.type) self._attr_state = data.get(self.type)
return True
@property
def attribution(self):
"""Return the attribution."""
return self._attribution
@property
def unique_id(self):
"""Return the unique id."""
return self._unique_id
@property
def name(self):
"""Return the name of the sensor."""
return f"{self.client_name} {self._name}"
@property
def state(self):
"""Return the state of the device."""
return self._state
@property
def should_poll(self):
"""No polling needed."""
return False
@property
def entity_picture(self):
"""Weather symbol if type is symbol."""
return self._entity_picture
@property
def extra_state_attributes(self):
"""Return the state attributes."""
if self.type.startswith(PRECIPITATION_FORECAST): if self.type.startswith(PRECIPITATION_FORECAST):
result = {ATTR_ATTRIBUTION: self._attribution} result = {ATTR_ATTRIBUTION: data.get(ATTRIBUTION)}
if self._timeframe is not None: if self._timeframe is not None:
result[TIMEFRAME_LABEL] = "%d min" % (self._timeframe) result[TIMEFRAME_LABEL] = "%d min" % (self._timeframe)
return result self._attr_extra_state_attributes = result
result = { result = {
ATTR_ATTRIBUTION: self._attribution, ATTR_ATTRIBUTION: data.get(ATTRIBUTION),
SENSOR_TYPES["stationname"][0]: self._stationname, SENSOR_TYPES["stationname"][0]: data.get(STATIONNAME),
} }
if self._measured is not None: if self._measured is not None:
# convert datetime (Europe/Amsterdam) into local datetime # convert datetime (Europe/Amsterdam) into local datetime
local_dt = dt_util.as_local(self._measured) local_dt = dt_util.as_local(self._measured)
result[MEASURED_LABEL] = local_dt.strftime("%c") result[MEASURED_LABEL] = local_dt.strftime("%c")
return result self._attr_extra_state_attributes = result
return True
@property
def unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""
return self._unit_of_measurement
@property
def device_class(self):
"""Return the class of this device, from component DEVICE_CLASSES."""
return SENSOR_TYPES[self.type][3]
@property
def icon(self):
"""Return possible sensor specific icon."""
return SENSOR_TYPES[self.type][2]
@property
def force_update(self):
"""Return true for continuous sensors, false for discrete sensors."""
return self._force_update
@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
return False

View File

@ -111,12 +111,17 @@ async def async_setup_entry(
class BrWeather(WeatherEntity): class BrWeather(WeatherEntity):
"""Representation of a weather condition.""" """Representation of a weather condition."""
_attr_temperature_unit = TEMP_CELSIUS
def __init__(self, data, config, coordinates): def __init__(self, data, config, coordinates):
"""Initialise the platform with a data instance and station name.""" """Initialize the platform with a data instance and station name."""
self._stationname = config.get(CONF_NAME, "Buienradar") self._stationname = config.get(CONF_NAME, "Buienradar")
self._attr_name = (
self._stationname or f"BR {data.stationname or '(unknown station)'}"
)
self._data = data self._data = data
self._unique_id = "{:2.6f}{:2.6f}".format( self._attr_unique_id = "{:2.6f}{:2.6f}".format(
coordinates[CONF_LATITUDE], coordinates[CONF_LONGITUDE] coordinates[CONF_LATITUDE], coordinates[CONF_LONGITUDE]
) )
@ -125,13 +130,6 @@ class BrWeather(WeatherEntity):
"""Return the attribution.""" """Return the attribution."""
return self._data.attribution return self._data.attribution
@property
def name(self):
"""Return the name of the sensor."""
return (
self._stationname or f"BR {self._data.stationname or '(unknown station)'}"
)
@property @property
def condition(self): def condition(self):
"""Return the current condition.""" """Return the current condition."""
@ -176,11 +174,6 @@ class BrWeather(WeatherEntity):
"""Return the current wind bearing (degrees).""" """Return the current wind bearing (degrees)."""
return self._data.wind_bearing return self._data.wind_bearing
@property
def temperature_unit(self):
"""Return the unit of measurement."""
return TEMP_CELSIUS
@property @property
def forecast(self): def forecast(self):
"""Return the forecast array.""" """Return the forecast array."""
@ -207,8 +200,3 @@ class BrWeather(WeatherEntity):
fcdata_out.append(data_out) fcdata_out.append(data_out)
return fcdata_out return fcdata_out
@property
def unique_id(self):
"""Return the unique id."""
return self._unique_id