diff --git a/homeassistant/components/shelly/sensor.py b/homeassistant/components/shelly/sensor.py index 8c1333a989c..6cabee6ccba 100644 --- a/homeassistant/components/shelly/sensor.py +++ b/homeassistant/components/shelly/sensor.py @@ -392,6 +392,22 @@ RPC_SENSORS: Final = { device_class=SensorDeviceClass.POWER, state_class=SensorStateClass.MEASUREMENT, ), + "power_rgb": RpcSensorDescription( + key="rgb", + sub_key="apower", + name="Power", + native_unit_of_measurement=UnitOfPower.WATT, + device_class=SensorDeviceClass.POWER, + state_class=SensorStateClass.MEASUREMENT, + ), + "power_rgbw": RpcSensorDescription( + key="rgbw", + sub_key="apower", + name="Power", + native_unit_of_measurement=UnitOfPower.WATT, + device_class=SensorDeviceClass.POWER, + state_class=SensorStateClass.MEASUREMENT, + ), "a_act_power": RpcSensorDescription( key="em", sub_key="a_act_power", @@ -536,6 +552,28 @@ RPC_SENSORS: Final = { state_class=SensorStateClass.MEASUREMENT, entity_registry_enabled_default=False, ), + "voltage_rgb": RpcSensorDescription( + key="rgb", + sub_key="voltage", + name="Voltage", + native_unit_of_measurement=UnitOfElectricPotential.VOLT, + value=lambda status, _: None if status is None else float(status), + suggested_display_precision=1, + device_class=SensorDeviceClass.VOLTAGE, + state_class=SensorStateClass.MEASUREMENT, + entity_registry_enabled_default=False, + ), + "voltage_rgbw": RpcSensorDescription( + key="rgbw", + sub_key="voltage", + name="Voltage", + native_unit_of_measurement=UnitOfElectricPotential.VOLT, + value=lambda status, _: None if status is None else float(status), + suggested_display_precision=1, + device_class=SensorDeviceClass.VOLTAGE, + state_class=SensorStateClass.MEASUREMENT, + entity_registry_enabled_default=False, + ), "a_voltage": RpcSensorDescription( key="em", sub_key="a_voltage", @@ -603,6 +641,26 @@ RPC_SENSORS: Final = { state_class=SensorStateClass.MEASUREMENT, entity_registry_enabled_default=False, ), + "current_rgb": RpcSensorDescription( + key="rgb", + sub_key="current", + name="Current", + native_unit_of_measurement=UnitOfElectricCurrent.AMPERE, + value=lambda status, _: None if status is None else float(status), + device_class=SensorDeviceClass.CURRENT, + state_class=SensorStateClass.MEASUREMENT, + entity_registry_enabled_default=False, + ), + "current_rgbw": RpcSensorDescription( + key="rgbw", + sub_key="current", + name="Current", + native_unit_of_measurement=UnitOfElectricCurrent.AMPERE, + value=lambda status, _: None if status is None else float(status), + device_class=SensorDeviceClass.CURRENT, + state_class=SensorStateClass.MEASUREMENT, + entity_registry_enabled_default=False, + ), "a_current": RpcSensorDescription( key="em", sub_key="a_current", @@ -683,6 +741,28 @@ RPC_SENSORS: Final = { device_class=SensorDeviceClass.ENERGY, state_class=SensorStateClass.TOTAL_INCREASING, ), + "energy_rgb": RpcSensorDescription( + key="rgb", + sub_key="aenergy", + name="Energy", + native_unit_of_measurement=UnitOfEnergy.WATT_HOUR, + suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, + value=lambda status, _: status["total"], + suggested_display_precision=2, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, + ), + "energy_rgbw": RpcSensorDescription( + key="rgbw", + sub_key="aenergy", + name="Energy", + native_unit_of_measurement=UnitOfEnergy.WATT_HOUR, + suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, + value=lambda status, _: status["total"], + suggested_display_precision=2, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, + ), "total_act": RpcSensorDescription( key="emdata", sub_key="total_act", @@ -895,6 +975,32 @@ RPC_SENSORS: Final = { entity_category=EntityCategory.DIAGNOSTIC, use_polling_coordinator=True, ), + "temperature_rgb": RpcSensorDescription( + key="rgb", + sub_key="temperature", + name="Device temperature", + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + value=lambda status, _: status["tC"], + suggested_display_precision=1, + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + entity_registry_enabled_default=False, + entity_category=EntityCategory.DIAGNOSTIC, + use_polling_coordinator=True, + ), + "temperature_rgbw": RpcSensorDescription( + key="rgbw", + sub_key="temperature", + name="Device temperature", + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + value=lambda status, _: status["tC"], + suggested_display_precision=1, + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + entity_registry_enabled_default=False, + entity_category=EntityCategory.DIAGNOSTIC, + use_polling_coordinator=True, + ), "temperature_0": RpcSensorDescription( key="temperature", sub_key="tC", diff --git a/tests/components/shelly/test_sensor.py b/tests/components/shelly/test_sensor.py index a39123a6722..843270107e0 100644 --- a/tests/components/shelly/test_sensor.py +++ b/tests/components/shelly/test_sensor.py @@ -25,8 +25,12 @@ from homeassistant.const import ( PERCENTAGE, STATE_UNAVAILABLE, STATE_UNKNOWN, + UnitOfElectricCurrent, + UnitOfElectricPotential, UnitOfEnergy, UnitOfFrequency, + UnitOfPower, + UnitOfTemperature, ) from homeassistant.core import HomeAssistant, State from homeassistant.helpers.device_registry import DeviceRegistry @@ -1189,3 +1193,89 @@ async def test_rpc_remove_enum_virtual_sensor_when_orphaned( entry = entity_registry.async_get(entity_id) assert not entry + + +@pytest.mark.usefixtures("entity_registry_enabled_by_default") +@pytest.mark.parametrize("light_type", ["rgb", "rgbw"]) +async def test_rpc_rgbw_sensors( + hass: HomeAssistant, + entity_registry: EntityRegistry, + mock_rpc_device: Mock, + monkeypatch: pytest.MonkeyPatch, + light_type: str, +) -> None: + """Test sensors for RGB/RGBW light.""" + config = deepcopy(mock_rpc_device.config) + config[f"{light_type}:0"] = {"id": 0} + monkeypatch.setattr(mock_rpc_device, "config", config) + + status = deepcopy(mock_rpc_device.status) + status[f"{light_type}:0"] = { + "temperature": {"tC": 54.3, "tF": 129.7}, + "aenergy": {"total": 45.141}, + "apower": 12.2, + "current": 0.23, + "voltage": 12.4, + } + monkeypatch.setattr(mock_rpc_device, "status", status) + + await init_integration(hass, 2) + + entity_id = "sensor.test_name_power" + + state = hass.states.get(entity_id) + assert state + assert state.state == "12.2" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UnitOfPower.WATT + + entry = entity_registry.async_get(entity_id) + assert entry + assert entry.unique_id == f"123456789ABC-{light_type}:0-power_{light_type}" + + entity_id = "sensor.test_name_energy" + + state = hass.states.get(entity_id) + assert state + assert state.state == "0.045141" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UnitOfEnergy.KILO_WATT_HOUR + + entry = entity_registry.async_get(entity_id) + assert entry + assert entry.unique_id == f"123456789ABC-{light_type}:0-energy_{light_type}" + + entity_id = "sensor.test_name_current" + + state = hass.states.get(entity_id) + assert state + assert state.state == "0.23" + assert ( + state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UnitOfElectricCurrent.AMPERE + ) + + entry = entity_registry.async_get(entity_id) + assert entry + assert entry.unique_id == f"123456789ABC-{light_type}:0-current_{light_type}" + + entity_id = "sensor.test_name_voltage" + + state = hass.states.get(entity_id) + assert state + assert state.state == "12.4" + assert ( + state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UnitOfElectricPotential.VOLT + ) + + entry = entity_registry.async_get(entity_id) + assert entry + assert entry.unique_id == f"123456789ABC-{light_type}:0-voltage_{light_type}" + + entity_id = "sensor.test_name_device_temperature" + + state = hass.states.get(entity_id) + assert state + assert state.state == "54.3" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UnitOfTemperature.CELSIUS + + entry = entity_registry.async_get(entity_id) + assert entry + assert entry.unique_id == f"123456789ABC-{light_type}:0-temperature_{light_type}"