Add zwave_js ZWavePropertyBinarySensory (#45504)

This commit is contained in:
Ian Tewksbury 2021-01-25 09:50:21 -05:00 committed by GitHub
parent d174c8265e
commit 666a94a8e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 609 additions and 0 deletions

View file

@ -252,6 +252,28 @@ NOTIFICATION_SENSOR_MAPPINGS: List[NotificationSensorMapping] = [
},
]
PROPERTY_DOOR_STATUS = "doorStatus"
class PropertySensorMapping(TypedDict, total=False):
"""Represent a property sensor mapping dict type."""
property_name: str # required
on_states: List[str] # required
device_class: str
enabled: bool
# Mappings for property sensors
PROPERTY_SENSOR_MAPPINGS: List[PropertySensorMapping] = [
{
"property_name": PROPERTY_DOOR_STATUS,
"on_states": ["open"],
"device_class": DEVICE_CLASS_DOOR,
"enabled": True,
},
]
async def async_setup_entry(
hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: Callable
@ -266,6 +288,8 @@ async def async_setup_entry(
if info.platform_hint == "notification":
entities.append(ZWaveNotificationBinarySensor(config_entry, client, info))
elif info.platform_hint == "property":
entities.append(ZWavePropertyBinarySensor(config_entry, client, info))
else:
# boolean sensor
entities.append(ZWaveBooleanBinarySensor(config_entry, client, info))
@ -356,3 +380,43 @@ class ZWaveNotificationBinarySensor(ZWaveBaseEntity, BinarySensorEntity):
mapping_info = mapping.copy()
return mapping_info
return {}
class ZWavePropertyBinarySensor(ZWaveBaseEntity, BinarySensorEntity):
"""Representation of a Z-Wave binary_sensor from a property."""
def __init__(
self, config_entry: ConfigEntry, client: ZwaveClient, info: ZwaveDiscoveryInfo
) -> None:
"""Initialize a ZWavePropertyBinarySensor entity."""
super().__init__(config_entry, client, info)
# check if we have a custom mapping for this value
self._mapping_info = self._get_sensor_mapping()
@property
def is_on(self) -> bool:
"""Return if the sensor is on or off."""
return self.info.primary_value.value in self._mapping_info["on_states"]
@property
def device_class(self) -> Optional[str]:
"""Return device class."""
return self._mapping_info.get("device_class")
@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
# We hide some more advanced sensors by default to not overwhelm users
# unless explicitly stated in a mapping, assume deisabled by default
return self._mapping_info.get("enabled", False)
@callback
def _get_sensor_mapping(self) -> PropertySensorMapping:
"""Try to get a device specific mapping for this sensor."""
mapping_info = PropertySensorMapping()
for mapping in PROPERTY_SENSOR_MAPPINGS:
if mapping["property_name"] == self.info.primary_value.property_name:
mapping_info = mapping.copy()
break
return mapping_info

View file

@ -74,6 +74,24 @@ DISCOVERY_SCHEMAS = [
property={"currentMode", "locked"},
type={"number", "boolean"},
),
# door lock door status
ZWaveDiscoverySchema(
platform="binary_sensor",
hint="property",
device_class_generic={"Entry Control"},
device_class_specific={
"Door Lock",
"Advanced Door Lock",
"Secure Keypad Door Lock",
"Secure Lockbox",
},
command_class={
CommandClass.LOCK,
CommandClass.DOOR_LOCK,
},
property={"doorStatus"},
type={"any"},
),
# climate
ZWaveDiscoverySchema(
platform="climate",

View file

@ -7,3 +7,6 @@ LOW_BATTERY_BINARY_SENSOR = "binary_sensor.multisensor_6_low_battery_level"
ENABLED_LEGACY_BINARY_SENSOR = "binary_sensor.z_wave_door_window_sensor_any"
DISABLED_LEGACY_BINARY_SENSOR = "binary_sensor.multisensor_6_any"
NOTIFICATION_MOTION_BINARY_SENSOR = "binary_sensor.multisensor_6_motion_sensor_status"
PROPERTY_DOOR_STATUS_BINARY_SENSOR = (
"binary_sensor.august_smart_lock_pro_3rd_gen_the_current_status_of_the_door"
)

View file

@ -68,6 +68,12 @@ def lock_schlage_be469_state_fixture():
return json.loads(load_fixture("zwave_js/lock_schlage_be469_state.json"))
@pytest.fixture(name="lock_august_asl03_state", scope="session")
def lock_august_asl03_state_fixture():
"""Load the August Pro lock node state fixture data."""
return json.loads(load_fixture("zwave_js/lock_august_asl03_state.json"))
@pytest.fixture(name="climate_radio_thermostat_ct100_plus_state", scope="session")
def climate_radio_thermostat_ct100_plus_state_fixture():
"""Load the climate radio thermostat ct100 plus node state fixture data."""
@ -170,6 +176,14 @@ def lock_schlage_be469_fixture(client, lock_schlage_be469_state):
return node
@pytest.fixture(name="lock_august_pro")
def lock_august_asl03_fixture(client, lock_august_asl03_state):
"""Mock a August Pro lock node."""
node = Node(client, lock_august_asl03_state)
client.driver.controller.nodes[node.node_id] = node
return node
@pytest.fixture(name="climate_radio_thermostat_ct100_plus")
def climate_radio_thermostat_ct100_plus_fixture(
client, climate_radio_thermostat_ct100_plus_state

View file

@ -9,6 +9,7 @@ from .common import (
ENABLED_LEGACY_BINARY_SENSOR,
LOW_BATTERY_BINARY_SENSOR,
NOTIFICATION_MOTION_BINARY_SENSOR,
PROPERTY_DOOR_STATUS_BINARY_SENSOR,
)
@ -84,3 +85,56 @@ async def test_notification_sensor(hass, multisensor_6, integration):
assert state
assert state.state == STATE_ON
assert state.attributes["device_class"] == DEVICE_CLASS_MOTION
async def test_property_sensor_door_status(hass, lock_august_pro, integration):
"""Test property binary sensor with sensor mapping (doorStatus)."""
node = lock_august_pro
state = hass.states.get(PROPERTY_DOOR_STATUS_BINARY_SENSOR)
assert state is not None
assert state.state == STATE_OFF
# open door
event = Event(
type="value updated",
data={
"source": "node",
"event": "value updated",
"nodeId": 6,
"args": {
"commandClassName": "Door Lock",
"commandClass": 98,
"endpoint": 0,
"property": "doorStatus",
"newValue": "open",
"prevValue": "closed",
"propertyName": "doorStatus",
},
},
)
node.receive_event(event)
state = hass.states.get(PROPERTY_DOOR_STATUS_BINARY_SENSOR)
assert state.state == STATE_ON
# close door
event = Event(
type="value updated",
data={
"source": "node",
"event": "value updated",
"nodeId": 6,
"args": {
"commandClassName": "Door Lock",
"commandClass": 98,
"endpoint": 0,
"property": "doorStatus",
"newValue": "closed",
"prevValue": "open",
"propertyName": "doorStatus",
},
},
)
node.receive_event(event)
state = hass.states.get(PROPERTY_DOOR_STATUS_BINARY_SENSOR)
assert state.state == STATE_OFF

View file

@ -0,0 +1,456 @@
{
"nodeId": 6,
"index": 0,
"installerIcon": 768,
"userIcon": 768,
"status": 4,
"ready": true,
"deviceClass": {
"basic": "Routing Slave",
"generic": "Entry Control",
"specific": "Secure Keypad Door Lock",
"mandatorySupportedCCs": [
"Basic",
"Door Lock",
"User Code",
"Manufacturer Specific",
"Security",
"Version"
],
"mandatoryControlCCs": []
},
"isListening": false,
"isFrequentListening": true,
"isRouting": true,
"maxBaudRate": 40000,
"isSecure": true,
"version": 4,
"isBeaming": true,
"manufacturerId": 831,
"productId": 1,
"productType": 1,
"firmwareVersion": "1.59",
"zwavePlusVersion": 1,
"nodeType": 0,
"roleType": 7,
"deviceConfig": {
"manufacturerId": 831,
"manufacturer": "August Smart Locks",
"label": "ASL-03",
"description": "August Smart Lock Pro 3rd Gen",
"devices": [
{
"productType": "0x0000",
"productId": "0x0594"
},
{
"productType": "0x0000",
"productId": "0xdf29"
},
{
"productType": "0x0001",
"productId": "0x0001"
}
],
"firmwareVersion": {
"min": "0.0",
"max": "255.255"
}
},
"label": "ASL-03",
"neighbors": [
1,
7,
8,
9
],
"interviewAttempts": 1,
"endpoints": [
{
"nodeId": 6,
"index": 0,
"installerIcon": 768,
"userIcon": 768
}
],
"values": [
{
"commandClassName": "Door Lock",
"commandClass": 98,
"endpoint": 0,
"property": "currentMode",
"propertyName": "currentMode",
"metadata": {
"type": "number",
"readable": true,
"writeable": false,
"min": 0,
"max": 255,
"label": "Current lock mode",
"states": {
"0": "Unsecured",
"1": "UnsecuredWithTimeout",
"16": "InsideUnsecured",
"17": "InsideUnsecuredWithTimeout",
"32": "OutsideUnsecured",
"33": "OutsideUnsecuredWithTimeout",
"254": "Unknown",
"255": "Secured"
}
},
"value": 255
},
{
"commandClassName": "Door Lock",
"commandClass": 98,
"endpoint": 0,
"property": "targetMode",
"propertyName": "targetMode",
"metadata": {
"type": "number",
"readable": true,
"writeable": true,
"min": 0,
"max": 255,
"label": "Target lock mode",
"states": {
"0": "Unsecured",
"1": "UnsecuredWithTimeout",
"16": "InsideUnsecured",
"17": "InsideUnsecuredWithTimeout",
"32": "OutsideUnsecured",
"33": "OutsideUnsecuredWithTimeout",
"254": "Unknown",
"255": "Secured"
}
}
},
{
"commandClassName": "Door Lock",
"commandClass": 98,
"endpoint": 0,
"property": "outsideHandlesCanOpenDoor",
"propertyName": "outsideHandlesCanOpenDoor",
"metadata": {
"type": "any",
"readable": true,
"writeable": false,
"label": "Which outside handles can open the door (actual status)"
},
"value": [
false,
false,
false,
false
]
},
{
"commandClassName": "Door Lock",
"commandClass": 98,
"endpoint": 0,
"property": "insideHandlesCanOpenDoor",
"propertyName": "insideHandlesCanOpenDoor",
"metadata": {
"type": "any",
"readable": true,
"writeable": false,
"label": "Which inside handles can open the door (actual status)"
},
"value": [
true,
false,
false,
false
]
},
{
"commandClassName": "Door Lock",
"commandClass": 98,
"endpoint": 0,
"property": "latchStatus",
"propertyName": "latchStatus",
"metadata": {
"type": "any",
"readable": true,
"writeable": false,
"label": "The current status of the latch"
},
"value": "open"
},
{
"commandClassName": "Door Lock",
"commandClass": 98,
"endpoint": 0,
"property": "boltStatus",
"propertyName": "boltStatus",
"metadata": {
"type": "any",
"readable": true,
"writeable": false,
"label": "The current status of the bolt"
},
"value": "locked"
},
{
"commandClassName": "Door Lock",
"commandClass": 98,
"endpoint": 0,
"property": "doorStatus",
"propertyName": "doorStatus",
"metadata": {
"type": "any",
"readable": true,
"writeable": false,
"label": "The current status of the door"
},
"value": "closed"
},
{
"commandClassName": "Door Lock",
"commandClass": 98,
"endpoint": 0,
"property": "lockTimeout",
"propertyName": "lockTimeout",
"metadata": {
"type": "number",
"readable": true,
"writeable": false,
"label": "Seconds until lock mode times out"
}
},
{
"commandClassName": "Door Lock",
"commandClass": 98,
"endpoint": 0,
"property": "operationType",
"propertyName": "operationType",
"metadata": {
"type": "number",
"readable": true,
"writeable": true,
"min": 0,
"max": 255,
"label": "Lock operation type",
"states": {
"1": "Constant",
"2": "Timed"
}
},
"value": 1
},
{
"commandClassName": "Door Lock",
"commandClass": 98,
"endpoint": 0,
"property": "outsideHandlesCanOpenDoorConfiguration",
"propertyName": "outsideHandlesCanOpenDoorConfiguration",
"metadata": {
"type": "any",
"readable": true,
"writeable": true,
"label": "Which outside handles can open the door (configuration)"
},
"value": [
false,
false,
false,
false
]
},
{
"commandClassName": "Door Lock",
"commandClass": 98,
"endpoint": 0,
"property": "insideHandlesCanOpenDoorConfiguration",
"propertyName": "insideHandlesCanOpenDoorConfiguration",
"metadata": {
"type": "any",
"readable": true,
"writeable": true,
"label": "Which inside handles can open the door (configuration)"
},
"value": [
true,
false,
false,
false
]
},
{
"commandClassName": "Door Lock",
"commandClass": 98,
"endpoint": 0,
"property": "lockTimeoutConfiguration",
"propertyName": "lockTimeoutConfiguration",
"metadata": {
"type": "number",
"readable": true,
"writeable": true,
"min": 0,
"max": 65535,
"label": "Duration of timed mode in seconds"
}
},
{
"commandClassName": "Notification",
"commandClass": 113,
"endpoint": 0,
"property": "Access Control",
"propertyKey": "Lock state",
"propertyName": "Access Control",
"propertyKeyName": "Lock state",
"metadata": {
"type": "number",
"readable": true,
"writeable": false,
"min": 0,
"max": 255,
"label": "Lock state",
"states": {
"0": "idle",
"11": "Lock jammed"
},
"ccSpecific": {
"notificationType": 6
}
},
"value": 0
},
{
"commandClassName": "Manufacturer Specific",
"commandClass": 114,
"endpoint": 0,
"property": "manufacturerId",
"propertyName": "manufacturerId",
"metadata": {
"type": "number",
"readable": true,
"writeable": false,
"min": 0,
"max": 65535,
"label": "Manufacturer ID"
},
"value": 831
},
{
"commandClassName": "Manufacturer Specific",
"commandClass": 114,
"endpoint": 0,
"property": "productType",
"propertyName": "productType",
"metadata": {
"type": "number",
"readable": true,
"writeable": false,
"min": 0,
"max": 65535,
"label": "Product type"
},
"value": 1
},
{
"commandClassName": "Manufacturer Specific",
"commandClass": 114,
"endpoint": 0,
"property": "productId",
"propertyName": "productId",
"metadata": {
"type": "number",
"readable": true,
"writeable": false,
"min": 0,
"max": 65535,
"label": "Product ID"
},
"value": 1
},
{
"commandClassName": "Battery",
"commandClass": 128,
"endpoint": 0,
"property": "level",
"propertyName": "level",
"metadata": {
"type": "number",
"readable": true,
"writeable": false,
"min": 0,
"max": 100,
"unit": "%",
"label": "Battery level"
},
"value": 100
},
{
"commandClassName": "Battery",
"commandClass": 128,
"endpoint": 0,
"property": "isLow",
"propertyName": "isLow",
"metadata": {
"type": "boolean",
"readable": true,
"writeable": false,
"label": "Low battery level"
},
"value": false
},
{
"commandClassName": "Version",
"commandClass": 134,
"endpoint": 0,
"property": "libraryType",
"propertyName": "libraryType",
"metadata": {
"type": "any",
"readable": true,
"writeable": false,
"label": "Library type"
},
"value": 3
},
{
"commandClassName": "Version",
"commandClass": 134,
"endpoint": 0,
"property": "protocolVersion",
"propertyName": "protocolVersion",
"metadata": {
"type": "any",
"readable": true,
"writeable": false,
"label": "Z-Wave protocol version"
},
"value": "4.61"
},
{
"commandClassName": "Version",
"commandClass": 134,
"endpoint": 0,
"property": "firmwareVersions",
"propertyName": "firmwareVersions",
"metadata": {
"type": "any",
"readable": true,
"writeable": false,
"label": "Z-Wave chip firmware versions"
},
"value": [
"1.59"
]
},
{
"commandClassName": "Version",
"commandClass": 134,
"endpoint": 0,
"property": "hardwareVersion",
"propertyName": "hardwareVersion",
"metadata": {
"type": "any",
"readable": true,
"writeable": false,
"label": "Z-Wave chip hardware version"
}
}
]
}