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:
Simone Chemelli 2022-08-01 09:52:51 +02:00 committed by GitHub
parent 5bb5920697
commit 0738f08215
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 7 deletions

View file

@ -190,9 +190,9 @@ def async_setup_entry_rpc(
] and not description.supported(wrapper.device.status[key]):
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(
wrapper.device.config, key
wrapper.device.config, wrapper.device.status, key
):
domain = sensor_class.__module__.split(".")[-1]
unique_id = f"{wrapper.mac}-{key}-{sensor_id}"
@ -268,7 +268,7 @@ class RpcEntityDescription(EntityDescription, RpcEntityRequiredKeysMixin):
value: Callable[[Any, Any], Any] | 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
use_polling_wrapper: bool = False
supported: Callable = lambda _: False

View file

@ -46,7 +46,12 @@ from .entity import (
async_setup_entry_rest,
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
@ -352,6 +357,15 @@ RPC_SENSORS: Final = {
entity_category=EntityCategory.DIAGNOSTIC,
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(
key="wifi",
sub_key="rssi",
@ -373,6 +387,27 @@ RPC_SENSORS: Final = {
entity_category=EntityCategory.DIAGNOSTIC,
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,
),
}

View file

@ -271,7 +271,9 @@ def get_rpc_channel_name(device: RpcDevice, key: str) -> str:
entity_name = device.config[key].get("name", device_name)
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
@ -325,7 +327,9 @@ def get_rpc_key_ids(keys_dict: dict[str, Any], key: str) -> list[int]:
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 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")
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]]:
"""Return list of input triggers for RPC device."""
triggers = []
@ -350,7 +361,7 @@ def get_rpc_input_triggers(device: RpcDevice) -> list[tuple[str, str]]:
for id_ in key_ids:
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
for trigger_type in RPC_INPUTS_EVENTS_TYPES: