Add missing sensors for Shelly Plus H&T (#76001)
* Add missing sensors for Shelly Plus H&T * Cleanup * Fix * Add voltage to battery sensor * Apply review comments
This commit is contained in:
parent
5bb5920697
commit
0738f08215
3 changed files with 53 additions and 7 deletions
|
@ -190,9 +190,9 @@ def async_setup_entry_rpc(
|
||||||
] and not description.supported(wrapper.device.status[key]):
|
] and not description.supported(wrapper.device.status[key]):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Filter and remove entities that according to settings should not create an entity
|
# Filter and remove entities that according to settings/status should not create an entity
|
||||||
if description.removal_condition and description.removal_condition(
|
if description.removal_condition and description.removal_condition(
|
||||||
wrapper.device.config, key
|
wrapper.device.config, wrapper.device.status, key
|
||||||
):
|
):
|
||||||
domain = sensor_class.__module__.split(".")[-1]
|
domain = sensor_class.__module__.split(".")[-1]
|
||||||
unique_id = f"{wrapper.mac}-{key}-{sensor_id}"
|
unique_id = f"{wrapper.mac}-{key}-{sensor_id}"
|
||||||
|
@ -268,7 +268,7 @@ class RpcEntityDescription(EntityDescription, RpcEntityRequiredKeysMixin):
|
||||||
|
|
||||||
value: Callable[[Any, Any], Any] | None = None
|
value: Callable[[Any, Any], Any] | None = None
|
||||||
available: Callable[[dict], bool] | None = None
|
available: Callable[[dict], bool] | None = None
|
||||||
removal_condition: Callable[[dict, str], bool] | None = None
|
removal_condition: Callable[[dict, dict, str], bool] | None = None
|
||||||
extra_state_attributes: Callable[[dict, dict], dict | None] | None = None
|
extra_state_attributes: Callable[[dict, dict], dict | None] | None = None
|
||||||
use_polling_wrapper: bool = False
|
use_polling_wrapper: bool = False
|
||||||
supported: Callable = lambda _: False
|
supported: Callable = lambda _: False
|
||||||
|
|
|
@ -46,7 +46,12 @@ from .entity import (
|
||||||
async_setup_entry_rest,
|
async_setup_entry_rest,
|
||||||
async_setup_entry_rpc,
|
async_setup_entry_rpc,
|
||||||
)
|
)
|
||||||
from .utils import get_device_entry_gen, get_device_uptime, temperature_unit
|
from .utils import (
|
||||||
|
get_device_entry_gen,
|
||||||
|
get_device_uptime,
|
||||||
|
is_rpc_device_externally_powered,
|
||||||
|
temperature_unit,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
@ -352,6 +357,15 @@ RPC_SENSORS: Final = {
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
use_polling_wrapper=True,
|
use_polling_wrapper=True,
|
||||||
),
|
),
|
||||||
|
"temperature_0": RpcSensorDescription(
|
||||||
|
key="temperature:0",
|
||||||
|
sub_key="tC",
|
||||||
|
name="Temperature",
|
||||||
|
native_unit_of_measurement=TEMP_CELSIUS,
|
||||||
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
entity_registry_enabled_default=True,
|
||||||
|
),
|
||||||
"rssi": RpcSensorDescription(
|
"rssi": RpcSensorDescription(
|
||||||
key="wifi",
|
key="wifi",
|
||||||
sub_key="rssi",
|
sub_key="rssi",
|
||||||
|
@ -373,6 +387,27 @@ RPC_SENSORS: Final = {
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
use_polling_wrapper=True,
|
use_polling_wrapper=True,
|
||||||
),
|
),
|
||||||
|
"humidity_0": RpcSensorDescription(
|
||||||
|
key="humidity:0",
|
||||||
|
sub_key="rh",
|
||||||
|
name="Humidity",
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
device_class=SensorDeviceClass.HUMIDITY,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
entity_registry_enabled_default=True,
|
||||||
|
),
|
||||||
|
"battery": RpcSensorDescription(
|
||||||
|
key="devicepower:0",
|
||||||
|
sub_key="battery",
|
||||||
|
name="Battery",
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
value=lambda status, _: status["percent"],
|
||||||
|
device_class=SensorDeviceClass.BATTERY,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
removal_condition=is_rpc_device_externally_powered,
|
||||||
|
entity_registry_enabled_default=True,
|
||||||
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,9 @@ def get_rpc_channel_name(device: RpcDevice, key: str) -> str:
|
||||||
entity_name = device.config[key].get("name", device_name)
|
entity_name = device.config[key].get("name", device_name)
|
||||||
|
|
||||||
if entity_name is None:
|
if entity_name is None:
|
||||||
return f"{device_name} {key.replace(':', '_')}"
|
if [k for k in key if k.startswith(("input", "switch"))]:
|
||||||
|
return f"{device_name} {key.replace(':', '_')}"
|
||||||
|
return device_name
|
||||||
|
|
||||||
return entity_name
|
return entity_name
|
||||||
|
|
||||||
|
@ -325,7 +327,9 @@ def get_rpc_key_ids(keys_dict: dict[str, Any], key: str) -> list[int]:
|
||||||
return key_ids
|
return key_ids
|
||||||
|
|
||||||
|
|
||||||
def is_rpc_momentary_input(config: dict[str, Any], key: str) -> bool:
|
def is_rpc_momentary_input(
|
||||||
|
config: dict[str, Any], status: dict[str, Any], key: str
|
||||||
|
) -> bool:
|
||||||
"""Return true if rpc input button settings is set to a momentary type."""
|
"""Return true if rpc input button settings is set to a momentary type."""
|
||||||
return cast(bool, config[key]["type"] == "button")
|
return cast(bool, config[key]["type"] == "button")
|
||||||
|
|
||||||
|
@ -342,6 +346,13 @@ def is_rpc_channel_type_light(config: dict[str, Any], channel: int) -> bool:
|
||||||
return con_types is not None and con_types[channel].lower().startswith("light")
|
return con_types is not None and con_types[channel].lower().startswith("light")
|
||||||
|
|
||||||
|
|
||||||
|
def is_rpc_device_externally_powered(
|
||||||
|
config: dict[str, Any], status: dict[str, Any], key: str
|
||||||
|
) -> bool:
|
||||||
|
"""Return true if device has external power instead of battery."""
|
||||||
|
return cast(bool, status[key]["external"]["present"])
|
||||||
|
|
||||||
|
|
||||||
def get_rpc_input_triggers(device: RpcDevice) -> list[tuple[str, str]]:
|
def get_rpc_input_triggers(device: RpcDevice) -> list[tuple[str, str]]:
|
||||||
"""Return list of input triggers for RPC device."""
|
"""Return list of input triggers for RPC device."""
|
||||||
triggers = []
|
triggers = []
|
||||||
|
@ -350,7 +361,7 @@ def get_rpc_input_triggers(device: RpcDevice) -> list[tuple[str, str]]:
|
||||||
|
|
||||||
for id_ in key_ids:
|
for id_ in key_ids:
|
||||||
key = f"input:{id_}"
|
key = f"input:{id_}"
|
||||||
if not is_rpc_momentary_input(device.config, key):
|
if not is_rpc_momentary_input(device.config, device.status, key):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for trigger_type in RPC_INPUTS_EVENTS_TYPES:
|
for trigger_type in RPC_INPUTS_EVENTS_TYPES:
|
||||||
|
|
Loading…
Add table
Reference in a new issue