From c8dc5d15ee3a07c7a72aeb41d5de91fcfe7ecce3 Mon Sep 17 00:00:00 2001 From: Shay Levy Date: Mon, 4 Oct 2021 23:46:46 +0300 Subject: [PATCH] Fix: Shelly Gen2 - filter unsupported sensors (#57065) --- .../components/shelly/binary_sensor.py | 16 +++++----------- homeassistant/components/shelly/entity.py | 19 +++++++++++++++---- homeassistant/components/shelly/sensor.py | 17 +++++++++++------ 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/homeassistant/components/shelly/binary_sensor.py b/homeassistant/components/shelly/binary_sensor.py index 16ffe8b4ee5..46e5468c079 100644 --- a/homeassistant/components/shelly/binary_sensor.py +++ b/homeassistant/components/shelly/binary_sensor.py @@ -122,34 +122,28 @@ REST_SENSORS: Final = { RPC_SENSORS: Final = { "input": RpcAttributeDescription( key="input", + sub_key="state", name="Input", - value=lambda status, _: status["state"], device_class=DEVICE_CLASS_POWER, default_enabled=False, removal_condition=is_rpc_momentary_input, ), "cloud": RpcAttributeDescription( key="cloud", + sub_key="connected", name="Cloud", - value=lambda status, _: status["connected"], device_class=DEVICE_CLASS_CONNECTIVITY, default_enabled=False, ), "fwupdate": RpcAttributeDescription( key="sys", + sub_key="available_updates", name="Firmware Update", device_class=DEVICE_CLASS_UPDATE, - value=lambda status, _: status["available_updates"], default_enabled=False, extra_state_attributes=lambda status: { - "latest_stable_version": status["available_updates"].get( - "stable", - {"version": ""}, - )["version"], - "beta_version": status["available_updates"].get( - "beta", - {"version": ""}, - )["version"], + "latest_stable_version": status.get("stable", {"version": ""})["version"], + "beta_version": status.get("beta", {"version": ""})["version"], }, ), } diff --git a/homeassistant/components/shelly/entity.py b/homeassistant/components/shelly/entity.py index f12633bd0e3..0fe25884f00 100644 --- a/homeassistant/components/shelly/entity.py +++ b/homeassistant/components/shelly/entity.py @@ -166,6 +166,10 @@ async def async_setup_entry_rpc( key_instances = get_rpc_key_instances(wrapper.device.status, description.key) for key in key_instances: + # Filter non-existing sensors + if description.sub_key not in wrapper.device.status[key]: + continue + # Filter and remove entities that according to settings should not create an entity if description.removal_condition and description.removal_condition( wrapper.device.config, key @@ -240,10 +244,11 @@ class RpcAttributeDescription: """Class to describe a RPC sensor.""" key: str + sub_key: str name: str icon: str | None = None unit: str | None = None - value: Callable[[dict, Any], Any] | None = None + value: Callable[[Any, Any], Any] | None = None device_class: str | None = None state_class: str | None = None default_enabled: bool = True @@ -549,6 +554,7 @@ class ShellyRpcAttributeEntity(ShellyRpcEntity, entity.Entity): ) -> None: """Initialize sensor.""" super().__init__(wrapper, key) + self.sub_key = description.sub_key self.attribute = attribute self.description = description @@ -564,8 +570,11 @@ class ShellyRpcAttributeEntity(ShellyRpcEntity, entity.Entity): """Value of sensor.""" if callable(self.description.value): self._last_value = self.description.value( - self.wrapper.device.status[self.key], self._last_value + self.wrapper.device.status[self.key][self.sub_key], self._last_value ) + else: + self._last_value = self.wrapper.device.status[self.key][self.sub_key] + return self._last_value @property @@ -576,7 +585,9 @@ class ShellyRpcAttributeEntity(ShellyRpcEntity, entity.Entity): if not available or not self.description.available: return available - return self.description.available(self.wrapper.device.status[self.key]) + return self.description.available( + self.wrapper.device.status[self.key][self.sub_key] + ) @property def extra_state_attributes(self) -> dict[str, Any] | None: @@ -585,7 +596,7 @@ class ShellyRpcAttributeEntity(ShellyRpcEntity, entity.Entity): return None return self.description.extra_state_attributes( - self.wrapper.device.status[self.key] + self.wrapper.device.status[self.key][self.sub_key] ) diff --git a/homeassistant/components/shelly/sensor.py b/homeassistant/components/shelly/sensor.py index 09e91946cf3..9ee0712aaef 100644 --- a/homeassistant/components/shelly/sensor.py +++ b/homeassistant/components/shelly/sensor.py @@ -242,51 +242,56 @@ REST_SENSORS: Final = { RPC_SENSORS: Final = { "power": RpcAttributeDescription( key="switch", + sub_key="apower", name="Power", unit=POWER_WATT, - value=lambda status, _: round(float(status["apower"]), 1), + value=lambda status, _: round(float(status), 1), device_class=sensor.DEVICE_CLASS_POWER, state_class=sensor.STATE_CLASS_MEASUREMENT, ), "voltage": RpcAttributeDescription( key="switch", + sub_key="voltage", name="Voltage", unit=ELECTRIC_POTENTIAL_VOLT, - value=lambda status, _: round(float(status["voltage"]), 1), + value=lambda status, _: round(float(status), 1), device_class=sensor.DEVICE_CLASS_VOLTAGE, state_class=sensor.STATE_CLASS_MEASUREMENT, default_enabled=False, ), "energy": RpcAttributeDescription( key="switch", + sub_key="aenergy", name="Energy", unit=ENERGY_KILO_WATT_HOUR, - value=lambda status, _: round(status["aenergy"]["total"] / 1000, 2), + value=lambda status, _: round(status["total"] / 1000, 2), device_class=sensor.DEVICE_CLASS_ENERGY, state_class=sensor.STATE_CLASS_TOTAL_INCREASING, ), "temperature": RpcAttributeDescription( key="switch", + sub_key="temperature", name="Temperature", unit=TEMP_CELSIUS, - value=lambda status, _: round(status["temperature"]["tC"], 1), + value=lambda status, _: round(status["tC"], 1), device_class=sensor.DEVICE_CLASS_TEMPERATURE, state_class=sensor.STATE_CLASS_MEASUREMENT, default_enabled=False, ), "rssi": RpcAttributeDescription( key="wifi", + sub_key="rssi", name="RSSI", unit=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, - value=lambda status, _: status["rssi"], device_class=sensor.DEVICE_CLASS_SIGNAL_STRENGTH, state_class=sensor.STATE_CLASS_MEASUREMENT, default_enabled=False, ), "uptime": RpcAttributeDescription( key="sys", + sub_key="uptime", name="Uptime", - value=lambda status, last: get_device_uptime(status["uptime"], last), + value=get_device_uptime, device_class=sensor.DEVICE_CLASS_TIMESTAMP, default_enabled=False, ),