Add energy meter sensors for Shelly Pro EM (#99747)
* Add support for Pro EM * Improve get_rpc_channel_name() * Revert an unintended change * Add tests
This commit is contained in:
parent
0c7e0f5cd9
commit
e1f4a3fa9f
4 changed files with 125 additions and 0 deletions
|
@ -363,6 +363,14 @@ RPC_SENSORS: Final = {
|
|||
device_class=SensorDeviceClass.POWER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
"power_em1": RpcSensorDescription(
|
||||
key="em1",
|
||||
sub_key="act_power",
|
||||
name="Power",
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
device_class=SensorDeviceClass.POWER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
"power_pm1": RpcSensorDescription(
|
||||
key="pm1",
|
||||
sub_key="apower",
|
||||
|
@ -427,6 +435,14 @@ RPC_SENSORS: Final = {
|
|||
device_class=SensorDeviceClass.APPARENT_POWER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
"aprt_power_em1": RpcSensorDescription(
|
||||
key="em1",
|
||||
sub_key="aprt_power",
|
||||
name="Apparent power",
|
||||
native_unit_of_measurement=UnitOfApparentPower.VOLT_AMPERE,
|
||||
device_class=SensorDeviceClass.APPARENT_POWER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
"total_aprt_power": RpcSensorDescription(
|
||||
key="em",
|
||||
sub_key="total_aprt_power",
|
||||
|
@ -435,6 +451,13 @@ RPC_SENSORS: Final = {
|
|||
device_class=SensorDeviceClass.APPARENT_POWER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
"pf_em1": RpcSensorDescription(
|
||||
key="em1",
|
||||
sub_key="pf",
|
||||
name="Power factor",
|
||||
device_class=SensorDeviceClass.POWER_FACTOR,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
"a_pf": RpcSensorDescription(
|
||||
key="em",
|
||||
sub_key="a_pf",
|
||||
|
@ -467,6 +490,17 @@ RPC_SENSORS: Final = {
|
|||
state_class=SensorStateClass.MEASUREMENT,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
"voltage_em1": RpcSensorDescription(
|
||||
key="em1",
|
||||
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_pm1": RpcSensorDescription(
|
||||
key="pm1",
|
||||
sub_key="voltage",
|
||||
|
@ -515,6 +549,16 @@ RPC_SENSORS: Final = {
|
|||
state_class=SensorStateClass.MEASUREMENT,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
"current_em1": RpcSensorDescription(
|
||||
key="em1",
|
||||
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_pm1": RpcSensorDescription(
|
||||
key="pm1",
|
||||
sub_key="current",
|
||||
|
@ -605,6 +649,18 @@ RPC_SENSORS: Final = {
|
|||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
),
|
||||
"total_act_energy": RpcSensorDescription(
|
||||
key="em1data",
|
||||
sub_key="total_act_energy",
|
||||
name="Total active energy",
|
||||
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
|
||||
suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
value=lambda status, _: float(status),
|
||||
suggested_display_precision=2,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
"a_total_act_energy": RpcSensorDescription(
|
||||
key="emdata",
|
||||
sub_key="a_total_act_energy",
|
||||
|
@ -652,6 +708,18 @@ RPC_SENSORS: Final = {
|
|||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
),
|
||||
"total_act_ret_energy": RpcSensorDescription(
|
||||
key="em1data",
|
||||
sub_key="total_act_ret_energy",
|
||||
name="Total active returned energy",
|
||||
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
|
||||
suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
value=lambda status, _: float(status),
|
||||
suggested_display_precision=2,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
"a_total_act_ret_energy": RpcSensorDescription(
|
||||
key="emdata",
|
||||
sub_key="a_total_act_ret_energy",
|
||||
|
@ -698,6 +766,16 @@ RPC_SENSORS: Final = {
|
|||
state_class=SensorStateClass.MEASUREMENT,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
"freq_em1": RpcSensorDescription(
|
||||
key="em1",
|
||||
sub_key="freq",
|
||||
name="Frequency",
|
||||
native_unit_of_measurement=UnitOfFrequency.HERTZ,
|
||||
suggested_display_precision=0,
|
||||
device_class=SensorDeviceClass.FREQUENCY,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
"freq_pm1": RpcSensorDescription(
|
||||
key="pm1",
|
||||
sub_key="freq",
|
||||
|
|
|
@ -288,6 +288,7 @@ def get_model_name(info: dict[str, Any]) -> str:
|
|||
def get_rpc_channel_name(device: RpcDevice, key: str) -> str:
|
||||
"""Get name based on device and channel name."""
|
||||
key = key.replace("emdata", "em")
|
||||
key = key.replace("em1data", "em1")
|
||||
if device.config.get("switch:0"):
|
||||
key = key.replace("input", "switch")
|
||||
device_name = device.name
|
||||
|
@ -298,6 +299,8 @@ def get_rpc_channel_name(device: RpcDevice, key: str) -> str:
|
|||
if entity_name is None:
|
||||
if key.startswith(("input:", "light:", "switch:")):
|
||||
return f"{device_name} {key.replace(':', '_')}"
|
||||
if key.startswith("em1"):
|
||||
return f"{device_name} EM{key.split(':')[-1]}"
|
||||
return device_name
|
||||
|
||||
return entity_name
|
||||
|
|
|
@ -202,6 +202,10 @@ MOCK_STATUS_RPC = {
|
|||
"devicepower:0": {"external": {"present": True}},
|
||||
"temperature:0": {"tC": 22.9},
|
||||
"illuminance:0": {"lux": 345},
|
||||
"em1:0": {"act_power": 85.3},
|
||||
"em1:1": {"act_power": 123.3},
|
||||
"em1data:0": {"total_act_energy": 123456.4},
|
||||
"em1data:1": {"total_act_energy": 987654.3},
|
||||
"sys": {
|
||||
"available_updates": {
|
||||
"beta": {"version": "some_beta_version"},
|
||||
|
|
|
@ -408,3 +408,43 @@ async def test_rpc_restored_sleeping_sensor_no_last_state(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get(entity_id).state == "22.9"
|
||||
|
||||
|
||||
async def test_rpc_em1_sensors(
|
||||
hass: HomeAssistant, mock_rpc_device, entity_registry_enabled_by_default: None
|
||||
) -> None:
|
||||
"""Test RPC sensors for EM1 component."""
|
||||
registry = async_get(hass)
|
||||
await init_integration(hass, 2)
|
||||
|
||||
state = hass.states.get("sensor.test_name_em0_power")
|
||||
assert state
|
||||
assert state.state == "85.3"
|
||||
|
||||
entry = registry.async_get("sensor.test_name_em0_power")
|
||||
assert entry
|
||||
assert entry.unique_id == "123456789ABC-em1:0-power_em1"
|
||||
|
||||
state = hass.states.get("sensor.test_name_em1_power")
|
||||
assert state
|
||||
assert state.state == "123.3"
|
||||
|
||||
entry = registry.async_get("sensor.test_name_em1_power")
|
||||
assert entry
|
||||
assert entry.unique_id == "123456789ABC-em1:1-power_em1"
|
||||
|
||||
state = hass.states.get("sensor.test_name_em0_total_active_energy")
|
||||
assert state
|
||||
assert state.state == "123.4564"
|
||||
|
||||
entry = registry.async_get("sensor.test_name_em0_total_active_energy")
|
||||
assert entry
|
||||
assert entry.unique_id == "123456789ABC-em1data:0-total_act_energy"
|
||||
|
||||
state = hass.states.get("sensor.test_name_em1_total_active_energy")
|
||||
assert state
|
||||
assert state.state == "987.6543"
|
||||
|
||||
entry = registry.async_get("sensor.test_name_em1_total_active_energy")
|
||||
assert entry
|
||||
assert entry.unique_id == "123456789ABC-em1data:1-total_act_energy"
|
||||
|
|
Loading…
Add table
Reference in a new issue