Add binary sensor platform to zwave_mqtt (#35519)
* add binary sensor platform to zwave_mqtt * add tests for binary_sensor * fix tests * device class is required value * Update homeassistant/components/zwave_mqtt/binary_sensor.py use colon as separator Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * extend tests * code optimize * add test for enabling a legacy binary sensor Co-authored-by: Martin Hjelmare <marhje52@gmail.com>pull/35551/head
parent
dd32324e01
commit
1351ddd11e
|
@ -0,0 +1,405 @@
|
||||||
|
"""Representation of Z-Wave binary_sensors."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from openzwavemqtt.const import CommandClass, ValueIndex, ValueType
|
||||||
|
|
||||||
|
from homeassistant.components.binary_sensor import (
|
||||||
|
DEVICE_CLASS_DOOR,
|
||||||
|
DEVICE_CLASS_GAS,
|
||||||
|
DEVICE_CLASS_HEAT,
|
||||||
|
DEVICE_CLASS_LOCK,
|
||||||
|
DEVICE_CLASS_MOISTURE,
|
||||||
|
DEVICE_CLASS_MOTION,
|
||||||
|
DEVICE_CLASS_POWER,
|
||||||
|
DEVICE_CLASS_PROBLEM,
|
||||||
|
DEVICE_CLASS_SAFETY,
|
||||||
|
DEVICE_CLASS_SMOKE,
|
||||||
|
DEVICE_CLASS_SOUND,
|
||||||
|
DOMAIN as BINARY_SENSOR_DOMAIN,
|
||||||
|
BinarySensorEntity,
|
||||||
|
)
|
||||||
|
from homeassistant.core import callback
|
||||||
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
|
||||||
|
from .const import DATA_UNSUBSCRIBE, DOMAIN
|
||||||
|
from .entity import ZWaveDeviceEntity
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
NOTIFICATION_TYPE = "index"
|
||||||
|
NOTIFICATION_VALUES = "values"
|
||||||
|
NOTIFICATION_DEVICE_CLASS = "device_class"
|
||||||
|
NOTIFICATION_SENSOR_ENABLED = "enabled"
|
||||||
|
NOTIFICATION_OFF_VALUE = "off_value"
|
||||||
|
|
||||||
|
NOTIFICATION_VALUE_CLEAR = 0
|
||||||
|
|
||||||
|
# Translation from values in Notification CC to binary sensors
|
||||||
|
# https://github.com/OpenZWave/open-zwave/blob/master/config/NotificationCCTypes.xml
|
||||||
|
NOTIFICATION_SENSORS = [
|
||||||
|
{
|
||||||
|
# Index 1: Smoke Alarm - Value Id's 1 and 2
|
||||||
|
# Assuming here that Value 1 and 2 are not present at the same time
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_SMOKE_ALARM,
|
||||||
|
NOTIFICATION_VALUES: [1, 2],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_SMOKE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 1: Smoke Alarm - All other Value Id's
|
||||||
|
# Create as disabled sensors
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_SMOKE_ALARM,
|
||||||
|
NOTIFICATION_VALUES: [3, 4, 5, 6, 7, 8],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_SMOKE,
|
||||||
|
NOTIFICATION_SENSOR_ENABLED: False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 2: Carbon Monoxide - Value Id's 1 and 2
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_CARBON_MONOOXIDE,
|
||||||
|
NOTIFICATION_VALUES: [1, 2],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_GAS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 2: Carbon Monoxide - All other Value Id's
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_CARBON_MONOOXIDE,
|
||||||
|
NOTIFICATION_VALUES: [4, 5, 7],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_GAS,
|
||||||
|
NOTIFICATION_SENSOR_ENABLED: False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 3: Carbon Dioxide - Value Id's 1 and 2
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_CARBON_DIOXIDE,
|
||||||
|
NOTIFICATION_VALUES: [1, 2],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_GAS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 3: Carbon Dioxide - All other Value Id's
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_CARBON_DIOXIDE,
|
||||||
|
NOTIFICATION_VALUES: [4, 5, 7],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_GAS,
|
||||||
|
NOTIFICATION_SENSOR_ENABLED: False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 4: Heat - Value Id's 1, 2, 5, 6 (heat/underheat)
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_HEAT,
|
||||||
|
NOTIFICATION_VALUES: [1, 2, 5, 6],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_HEAT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 4: Heat - All other Value Id's
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_HEAT,
|
||||||
|
NOTIFICATION_VALUES: [3, 4, 8, 10, 11],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_HEAT,
|
||||||
|
NOTIFICATION_SENSOR_ENABLED: False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 5: Water - Value Id's 1, 2, 3, 4
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_WATER,
|
||||||
|
NOTIFICATION_VALUES: [1, 2, 3, 4],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_MOISTURE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 5: Water - All other Value Id's
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_WATER,
|
||||||
|
NOTIFICATION_VALUES: [5],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_MOISTURE,
|
||||||
|
NOTIFICATION_SENSOR_ENABLED: False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 6: Access Control - Value Id's 1, 2, 3, 4 (Lock)
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_ACCESS_CONTROL,
|
||||||
|
NOTIFICATION_VALUES: [1, 2, 3, 4],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_LOCK,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 6: Access Control - Value Id 22 (door/window open)
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_ACCESS_CONTROL,
|
||||||
|
NOTIFICATION_VALUES: [22],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_DOOR,
|
||||||
|
NOTIFICATION_OFF_VALUE: 23,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 7: Home Security - Value Id's 1, 2 (intrusion)
|
||||||
|
# Assuming that value 1 and 2 are not present at the same time
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_HOME_SECURITY,
|
||||||
|
NOTIFICATION_VALUES: [1, 2],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_SAFETY,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 7: Home Security - Value Id's 3, 4, 9 (tampering)
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_HOME_SECURITY,
|
||||||
|
NOTIFICATION_VALUES: [3, 4, 9],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_SAFETY,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 7: Home Security - Value Id's 5, 6 (glass breakage)
|
||||||
|
# Assuming that value 5 and 6 are not present at the same time
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_HOME_SECURITY,
|
||||||
|
NOTIFICATION_VALUES: [5, 6],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_SAFETY,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 7: Home Security - Value Id's 7, 8 (motion)
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_HOME_SECURITY,
|
||||||
|
NOTIFICATION_VALUES: [7, 8],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_MOTION,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 8: Power management - Values 1...9
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_POWER_MANAGEMENT,
|
||||||
|
NOTIFICATION_VALUES: [1, 2, 3, 4, 5, 6, 7, 8, 9],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_POWER,
|
||||||
|
NOTIFICATION_SENSOR_ENABLED: False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 8: Power management - Values 10...15
|
||||||
|
# Battery values (mutually exclusive)
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_POWER_MANAGEMENT,
|
||||||
|
NOTIFICATION_VALUES: [10, 11, 12, 13, 14, 15],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_POWER,
|
||||||
|
NOTIFICATION_SENSOR_ENABLED: False,
|
||||||
|
NOTIFICATION_OFF_VALUE: None,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 9: System - Value Id's 1, 2, 6, 7
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_SYSTEM,
|
||||||
|
NOTIFICATION_VALUES: [1, 2, 6, 7],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_PROBLEM,
|
||||||
|
NOTIFICATION_SENSOR_ENABLED: False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 10: Emergency - Value Id's 1, 2, 3
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_EMERGENCY,
|
||||||
|
NOTIFICATION_VALUES: [1, 2, 3],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_PROBLEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 11: Clock - Value Id's 1, 2
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_CLOCK,
|
||||||
|
NOTIFICATION_VALUES: [1, 2],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: None,
|
||||||
|
NOTIFICATION_SENSOR_ENABLED: False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 12: Appliance - All Value Id's
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_APPLIANCE,
|
||||||
|
NOTIFICATION_VALUES: [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
7,
|
||||||
|
8,
|
||||||
|
9,
|
||||||
|
10,
|
||||||
|
11,
|
||||||
|
12,
|
||||||
|
13,
|
||||||
|
14,
|
||||||
|
15,
|
||||||
|
16,
|
||||||
|
17,
|
||||||
|
18,
|
||||||
|
19,
|
||||||
|
20,
|
||||||
|
21,
|
||||||
|
],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: None,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 13: Home Health - Value Id's 1,2,3,4,5
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_APPLIANCE,
|
||||||
|
NOTIFICATION_VALUES: [1, 2, 3, 4, 5],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: None,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 14: Siren
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_SIREN,
|
||||||
|
NOTIFICATION_VALUES: [1],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_SOUND,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 15: Water valve
|
||||||
|
# ignore non-boolean values
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_WATER_VALVE,
|
||||||
|
NOTIFICATION_VALUES: [3, 4],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_PROBLEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 16: Weather
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_WEATHER,
|
||||||
|
NOTIFICATION_VALUES: [1, 2],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_PROBLEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 17: Irrigation
|
||||||
|
# ignore non-boolean values
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_IRRIGATION,
|
||||||
|
NOTIFICATION_VALUES: [1, 2, 3, 4, 5],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: None,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 18: Gas
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_GAS,
|
||||||
|
NOTIFICATION_VALUES: [1, 2, 3, 4],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_GAS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Index 18: Gas
|
||||||
|
NOTIFICATION_TYPE: ValueIndex.NOTIFICATION_GAS,
|
||||||
|
NOTIFICATION_VALUES: [6],
|
||||||
|
NOTIFICATION_DEVICE_CLASS: DEVICE_CLASS_PROBLEM,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
|
"""Set up Z-Wave binary_sensor from config entry."""
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def async_add_binary_sensor(values):
|
||||||
|
"""Add Z-Wave Binary Sensor(s)."""
|
||||||
|
async_add_entities(VALUE_TYPE_SENSORS[values.primary.type](values))
|
||||||
|
|
||||||
|
hass.data[DOMAIN][config_entry.entry_id][DATA_UNSUBSCRIBE].append(
|
||||||
|
async_dispatcher_connect(
|
||||||
|
hass, f"{DOMAIN}_new_{BINARY_SENSOR_DOMAIN}", async_add_binary_sensor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def async_get_legacy_binary_sensors(values):
|
||||||
|
"""Add Legacy/classic Z-Wave Binary Sensor."""
|
||||||
|
return [ZWaveBinarySensor(values)]
|
||||||
|
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def async_get_notification_sensors(values):
|
||||||
|
"""Convert Notification values into binary sensors."""
|
||||||
|
sensors_to_add = []
|
||||||
|
for list_value in values.primary.value["List"]:
|
||||||
|
# check if we have a mapping for this value
|
||||||
|
for item in NOTIFICATION_SENSORS:
|
||||||
|
if item[NOTIFICATION_TYPE] != values.primary.index:
|
||||||
|
continue
|
||||||
|
if list_value["Value"] not in item[NOTIFICATION_VALUES]:
|
||||||
|
continue
|
||||||
|
sensors_to_add.append(
|
||||||
|
ZWaveListValueSensor(
|
||||||
|
# required values
|
||||||
|
values,
|
||||||
|
list_value["Value"],
|
||||||
|
item[NOTIFICATION_DEVICE_CLASS],
|
||||||
|
# optional values
|
||||||
|
item.get(NOTIFICATION_SENSOR_ENABLED, True),
|
||||||
|
item.get(NOTIFICATION_OFF_VALUE, NOTIFICATION_VALUE_CLEAR),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return sensors_to_add
|
||||||
|
|
||||||
|
|
||||||
|
VALUE_TYPE_SENSORS = {
|
||||||
|
ValueType.BOOL: async_get_legacy_binary_sensors,
|
||||||
|
ValueType.LIST: async_get_notification_sensors,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ZWaveBinarySensor(ZWaveDeviceEntity, BinarySensorEntity):
|
||||||
|
"""Representation of a Z-Wave binary_sensor."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self):
|
||||||
|
"""Return if the sensor is on or off."""
|
||||||
|
return self.values.primary.value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def entity_registry_enabled_default(self) -> bool:
|
||||||
|
"""Return if the entity should be enabled when first added to the entity registry."""
|
||||||
|
# Legacy binary sensors are phased out (replaced by notification sensors)
|
||||||
|
# Disable by default to not confuse users
|
||||||
|
for item in self.values.primary.node.values():
|
||||||
|
if item.command_class == CommandClass.NOTIFICATION:
|
||||||
|
# This device properly implements the Notification CC, legacy sensor can be disabled
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class ZWaveListValueSensor(ZWaveDeviceEntity, BinarySensorEntity):
|
||||||
|
"""Representation of a binary_sensor from values in the Z-Wave Notification CommandClass."""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
values,
|
||||||
|
on_value,
|
||||||
|
device_class=None,
|
||||||
|
default_enabled=True,
|
||||||
|
off_value=NOTIFICATION_VALUE_CLEAR,
|
||||||
|
):
|
||||||
|
"""Initialize a ZWaveListValueSensor entity."""
|
||||||
|
super().__init__(values)
|
||||||
|
self._on_value = on_value
|
||||||
|
self._device_class = device_class
|
||||||
|
self._default_enabled = default_enabled
|
||||||
|
self._off_value = off_value
|
||||||
|
# make sure the correct value is selected at startup
|
||||||
|
self._state = False
|
||||||
|
self.on_value_update()
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def on_value_update(self):
|
||||||
|
"""Call when a value is added/updated in the underlying EntityValues Collection."""
|
||||||
|
if self.values.primary.value["Selected_id"] == self._on_value:
|
||||||
|
# Only when the active ID exactly matches our watched ON value, set sensor state to ON
|
||||||
|
self._state = True
|
||||||
|
elif self.values.primary.value["Selected_id"] == self._off_value:
|
||||||
|
# Only when the active ID exactly matches our watched OFF value, set sensor state to OFF
|
||||||
|
self._state = False
|
||||||
|
elif (
|
||||||
|
self._off_value is None
|
||||||
|
and self.values.primary.value["Selected_id"] != self._on_value
|
||||||
|
):
|
||||||
|
# Off value not explicitly specified
|
||||||
|
# Some values are reset by the simple fact they're overruled by another value coming in
|
||||||
|
# For example the battery charging values in Power Management Index
|
||||||
|
self._state = False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Return the name of the entity."""
|
||||||
|
# Append value label to base name
|
||||||
|
base_name = super().name
|
||||||
|
value_label = ""
|
||||||
|
for item in self.values.primary.value["List"]:
|
||||||
|
if item["Value"] == self._on_value:
|
||||||
|
value_label = item["Label"]
|
||||||
|
break
|
||||||
|
# Strip "on location" / "at location" from name
|
||||||
|
# Note: We're assuming that we don't retrieve 2 values with different location
|
||||||
|
value_label = value_label.split(" on ")[0]
|
||||||
|
value_label = value_label.split(" at ")[0]
|
||||||
|
return f"{base_name}: {value_label}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unique_id(self):
|
||||||
|
"""Return the unique_id of the entity."""
|
||||||
|
unique_id = super().unique_id
|
||||||
|
return f"{unique_id}.{self._on_value}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self):
|
||||||
|
"""Return if the sensor is on or off."""
|
||||||
|
return self._state
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_class(self):
|
||||||
|
"""Return the class of this device, from component DEVICE_CLASSES."""
|
||||||
|
return self._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 the more advanced sensors by default to not overwhelm users
|
||||||
|
return self._default_enabled
|
|
@ -1,11 +1,12 @@
|
||||||
"""Constants for the zwave_mqtt integration."""
|
"""Constants for the zwave_mqtt integration."""
|
||||||
|
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
|
||||||
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
||||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||||
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||||
|
|
||||||
DOMAIN = "zwave_mqtt"
|
DOMAIN = "zwave_mqtt"
|
||||||
DATA_UNSUBSCRIBE = "unsubscribe"
|
DATA_UNSUBSCRIBE = "unsubscribe"
|
||||||
PLATFORMS = [LIGHT_DOMAIN, SENSOR_DOMAIN, SWITCH_DOMAIN]
|
PLATFORMS = [BINARY_SENSOR_DOMAIN, LIGHT_DOMAIN, SENSOR_DOMAIN, SWITCH_DOMAIN]
|
||||||
|
|
||||||
# MQTT Topics
|
# MQTT Topics
|
||||||
TOPIC_OPENZWAVE = "OpenZWave"
|
TOPIC_OPENZWAVE = "OpenZWave"
|
||||||
|
|
|
@ -5,6 +5,31 @@ from openzwavemqtt.const import CommandClass, ValueGenre, ValueIndex, ValueType
|
||||||
from . import const
|
from . import const
|
||||||
|
|
||||||
DISCOVERY_SCHEMAS = (
|
DISCOVERY_SCHEMAS = (
|
||||||
|
{ # Binary sensors
|
||||||
|
const.DISC_COMPONENT: "binary_sensor",
|
||||||
|
const.DISC_VALUES: {
|
||||||
|
const.DISC_PRIMARY: {
|
||||||
|
const.DISC_COMMAND_CLASS: CommandClass.SENSOR_BINARY,
|
||||||
|
const.DISC_TYPE: ValueType.BOOL,
|
||||||
|
const.DISC_GENRE: ValueGenre.USER,
|
||||||
|
},
|
||||||
|
"off_delay": {
|
||||||
|
const.DISC_COMMAND_CLASS: CommandClass.CONFIGURATION,
|
||||||
|
const.DISC_INDEX: 9,
|
||||||
|
const.DISC_OPTIONAL: True,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ # Notification CommandClass translates to binary_sensor
|
||||||
|
const.DISC_COMPONENT: "binary_sensor",
|
||||||
|
const.DISC_VALUES: {
|
||||||
|
const.DISC_PRIMARY: {
|
||||||
|
const.DISC_COMMAND_CLASS: CommandClass.NOTIFICATION,
|
||||||
|
const.DISC_GENRE: ValueGenre.USER,
|
||||||
|
const.DISC_TYPE: (ValueType.BOOL, ValueType.LIST),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
{ # Light
|
{ # Light
|
||||||
const.DISC_COMPONENT: "light",
|
const.DISC_COMPONENT: "light",
|
||||||
const.DISC_GENERIC_DEVICE_CLASS: (
|
const.DISC_GENERIC_DEVICE_CLASS: (
|
||||||
|
@ -93,9 +118,8 @@ def check_node_schema(node, schema):
|
||||||
|
|
||||||
def check_value_schema(value, schema):
|
def check_value_schema(value, schema):
|
||||||
"""Check if the value matches the passed value schema."""
|
"""Check if the value matches the passed value schema."""
|
||||||
if (
|
if const.DISC_COMMAND_CLASS in schema and not eq_or_in(
|
||||||
const.DISC_COMMAND_CLASS in schema
|
value.parent.command_class_id, schema[const.DISC_COMMAND_CLASS]
|
||||||
and value.parent.command_class_id not in schema[const.DISC_COMMAND_CLASS]
|
|
||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
if const.DISC_TYPE in schema and not eq_or_in(value.type, schema[const.DISC_TYPE]):
|
if const.DISC_TYPE in schema and not eq_or_in(value.type, schema[const.DISC_TYPE]):
|
||||||
|
|
|
@ -66,3 +66,27 @@ async def sensor_msg_fixture(hass):
|
||||||
message = MQTTMessage(topic=sensor_json["topic"], payload=sensor_json["payload"])
|
message = MQTTMessage(topic=sensor_json["topic"], payload=sensor_json["payload"])
|
||||||
message.encode()
|
message.encode()
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="binary_sensor_msg")
|
||||||
|
async def binary_sensor_msg_fixture(hass):
|
||||||
|
"""Return a mock MQTT msg with a binary_sensor change message."""
|
||||||
|
sensor_json = json.loads(
|
||||||
|
await hass.async_add_executor_job(load_fixture, "zwave_mqtt/binary_sensor.json")
|
||||||
|
)
|
||||||
|
message = MQTTMessage(topic=sensor_json["topic"], payload=sensor_json["payload"])
|
||||||
|
message.encode()
|
||||||
|
return message
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="binary_sensor_alt_msg")
|
||||||
|
async def binary_sensor_alt_msg_fixture(hass):
|
||||||
|
"""Return a mock MQTT msg with a binary_sensor change message."""
|
||||||
|
sensor_json = json.loads(
|
||||||
|
await hass.async_add_executor_job(
|
||||||
|
load_fixture, "zwave_mqtt/binary_sensor_alt.json"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
message = MQTTMessage(topic=sensor_json["topic"], payload=sensor_json["payload"])
|
||||||
|
message.encode()
|
||||||
|
return message
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
"""Test Z-Wave Sensors."""
|
||||||
|
from homeassistant.components.binary_sensor import (
|
||||||
|
DEVICE_CLASS_MOTION,
|
||||||
|
DOMAIN as BINARY_SENSOR_DOMAIN,
|
||||||
|
)
|
||||||
|
from homeassistant.components.zwave_mqtt.const import DOMAIN
|
||||||
|
from homeassistant.const import ATTR_DEVICE_CLASS
|
||||||
|
|
||||||
|
from .common import setup_zwave
|
||||||
|
|
||||||
|
|
||||||
|
async def test_binary_sensor(hass, generic_data, binary_sensor_msg):
|
||||||
|
"""Test setting up config entry."""
|
||||||
|
receive_msg = await setup_zwave(hass, fixture=generic_data)
|
||||||
|
|
||||||
|
# Test Legacy sensor (disabled by default)
|
||||||
|
registry = await hass.helpers.entity_registry.async_get_registry()
|
||||||
|
entity_id = "binary_sensor.trisensor_sensor"
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state is None
|
||||||
|
entry = registry.async_get(entity_id)
|
||||||
|
assert entry
|
||||||
|
assert entry.disabled
|
||||||
|
assert entry.disabled_by == "integration"
|
||||||
|
|
||||||
|
# Test enabling legacy entity
|
||||||
|
updated_entry = registry.async_update_entity(
|
||||||
|
entry.entity_id, **{"disabled_by": None}
|
||||||
|
)
|
||||||
|
assert updated_entry != entry
|
||||||
|
assert updated_entry.disabled is False
|
||||||
|
|
||||||
|
# Test Sensor for Notification CC
|
||||||
|
state = hass.states.get("binary_sensor.trisensor_home_security_motion_detected")
|
||||||
|
assert state
|
||||||
|
assert state.state == "off"
|
||||||
|
assert state.attributes[ATTR_DEVICE_CLASS] == DEVICE_CLASS_MOTION
|
||||||
|
|
||||||
|
# Test incoming state change
|
||||||
|
receive_msg(binary_sensor_msg)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get("binary_sensor.trisensor_home_security_motion_detected")
|
||||||
|
assert state.state == "on"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sensor_enabled(hass, generic_data, binary_sensor_alt_msg):
|
||||||
|
"""Test enabling a legacy binary_sensor."""
|
||||||
|
|
||||||
|
registry = await hass.helpers.entity_registry.async_get_registry()
|
||||||
|
|
||||||
|
entry = registry.async_get_or_create(
|
||||||
|
BINARY_SENSOR_DOMAIN,
|
||||||
|
DOMAIN,
|
||||||
|
"1-37-625737744",
|
||||||
|
suggested_object_id="trisensor_sensor_instance_1_sensor",
|
||||||
|
disabled_by=None,
|
||||||
|
)
|
||||||
|
assert entry.disabled is False
|
||||||
|
|
||||||
|
receive_msg = await setup_zwave(hass, fixture=generic_data)
|
||||||
|
receive_msg(binary_sensor_alt_msg)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get(entry.entity_id)
|
||||||
|
assert state is not None
|
||||||
|
assert state.state == "on"
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"topic": "OpenZWave/1/node/37/instance/1/commandclass/113/value/1970325463777300/",
|
||||||
|
"payload": {
|
||||||
|
"Label": "Home Security",
|
||||||
|
"Value": {
|
||||||
|
"List": [
|
||||||
|
{
|
||||||
|
"Value": 0,
|
||||||
|
"Label": "Clear"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Value": 8,
|
||||||
|
"Label": "Motion Detected at Unknown Location"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Selected": "Motion Detected at Unknown Location",
|
||||||
|
"Selected_id": 8
|
||||||
|
},
|
||||||
|
"Units": "",
|
||||||
|
"Min": 0,
|
||||||
|
"Max": 0,
|
||||||
|
"Type": "List",
|
||||||
|
"Instance": 1,
|
||||||
|
"CommandClass": "COMMAND_CLASS_NOTIFICATION",
|
||||||
|
"Index": 7,
|
||||||
|
"Node": 37,
|
||||||
|
"Genre": "User",
|
||||||
|
"Help": "Home Security Alerts",
|
||||||
|
"ValueIDKey": 1970325463777300,
|
||||||
|
"ReadOnly": false,
|
||||||
|
"WriteOnly": false,
|
||||||
|
"ValueSet": false,
|
||||||
|
"ValuePolled": false,
|
||||||
|
"ChangeVerified": false,
|
||||||
|
"Event": "valueAdded",
|
||||||
|
"TimeStamp": 1579566891
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"topic": "OpenZWave/1/node/37/instance/1/commandclass/48/value/625737744/",
|
||||||
|
"payload": {
|
||||||
|
"Label": "Sensor",
|
||||||
|
"Value": true,
|
||||||
|
"Units": "",
|
||||||
|
"Min": 0,
|
||||||
|
"Max": 0,
|
||||||
|
"Type": "Bool",
|
||||||
|
"Instance": 1,
|
||||||
|
"CommandClass": "COMMAND_CLASS_SENSOR_BINARY",
|
||||||
|
"Index": 0,
|
||||||
|
"Node": 37,
|
||||||
|
"Genre": "User",
|
||||||
|
"Help": "Binary Sensor State",
|
||||||
|
"ValueIDKey": 625737744,
|
||||||
|
"ReadOnly": false,
|
||||||
|
"WriteOnly": false,
|
||||||
|
"ValueSet": false,
|
||||||
|
"ValuePolled": false,
|
||||||
|
"ChangeVerified": false,
|
||||||
|
"Event": "valueAdded",
|
||||||
|
"TimeStamp": 1579566891
|
||||||
|
}
|
||||||
|
}
|
|
@ -105,7 +105,7 @@ OpenZWave/1/node/36/instance/1/commandclass/112/value/56576470933045270/,{ "L
|
||||||
OpenZWave/1/node/36/instance/1/commandclass/112/value/70931694745288724/,{ "Label": "Lock/Unlock Configuration", "Value": { "List": [ { "Value": 0, "Label": "Unlock" }, { "Value": 1, "Label": "Lock" } ], "Selected": "Unlock" }, "Units": "", "Min": 0, "Max": 1, "Type": "List", "Instance": 1, "CommandClass": "COMMAND_CLASS_CONFIGURATION", "Index": 252, "Node": 36, "Genre": "Config", "Help": "Lock/ unlock all configuration parameters", "ValueIDKey": 70931694745288724, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
OpenZWave/1/node/36/instance/1/commandclass/112/value/70931694745288724/,{ "Label": "Lock/Unlock Configuration", "Value": { "List": [ { "Value": 0, "Label": "Unlock" }, { "Value": 1, "Label": "Lock" } ], "Selected": "Unlock" }, "Units": "", "Min": 0, "Max": 1, "Type": "List", "Instance": 1, "CommandClass": "COMMAND_CLASS_CONFIGURATION", "Index": 252, "Node": 36, "Genre": "Config", "Help": "Lock/ unlock all configuration parameters", "ValueIDKey": 70931694745288724, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
||||||
OpenZWave/1/node/36/instance/1/commandclass/112/value/71776119675420692/,{ "Label": "Reset To Factory Defaults", "Value": { "List": [ { "Value": 0, "Label": "Normal" }, { "Value": 1, "Label": "Reset to factory default setting" }, { "Value": 1431655765, "Label": "Reset to factory default setting and removed from the z-wave network" } ], "Selected": "Reset to factory default setting" }, "Units": "", "Min": 0, "Max": 0, "Type": "List", "Instance": 1, "CommandClass": "COMMAND_CLASS_CONFIGURATION", "Index": 255, "Node": 36, "Genre": "Config", "Help": "Reset to factory defaults", "ValueIDKey": 71776119675420692, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
OpenZWave/1/node/36/instance/1/commandclass/112/value/71776119675420692/,{ "Label": "Reset To Factory Defaults", "Value": { "List": [ { "Value": 0, "Label": "Normal" }, { "Value": 1, "Label": "Reset to factory default setting" }, { "Value": 1431655765, "Label": "Reset to factory default setting and removed from the z-wave network" } ], "Selected": "Reset to factory default setting" }, "Units": "", "Min": 0, "Max": 0, "Type": "List", "Instance": 1, "CommandClass": "COMMAND_CLASS_CONFIGURATION", "Index": 255, "Node": 36, "Genre": "Config", "Help": "Reset to factory defaults", "ValueIDKey": 71776119675420692, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
||||||
OpenZWave/1/node/36/instance/1/commandclass/113/,{ "Instance": 1, "CommandClassId": 113, "CommandClass": "COMMAND_CLASS_NOTIFICATION", "TimeStamp": 1579566891}
|
OpenZWave/1/node/36/instance/1/commandclass/113/,{ "Instance": 1, "CommandClassId": 113, "CommandClass": "COMMAND_CLASS_NOTIFICATION", "TimeStamp": 1579566891}
|
||||||
OpenZWave/1/node/36/instance/1/commandclass/113/value/1407375493578772/,{ "Label": "Instance 1: Water", "Value": { "List": [ { "Value": 0, "Label": "Clear" }, { "Value": 2, "Label": "Water Leak at Unknown Location" } ], "Selected": "Clear" }, "Units": "", "Min": 0, "Max": 0, "Type": "List", "Instance": 1, "CommandClass": "COMMAND_CLASS_NOTIFICATION", "Index": 5, "Node": 36, "Genre": "User", "Help": "Water Alerts", "ValueIDKey": 1407375493578772, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
OpenZWave/1/node/36/instance/1/commandclass/113/value/1407375493578772/,{ "Label": "Instance 1: Water", "Value": { "List": [ { "Value": 0, "Label": "Clear" }, { "Value": 2, "Label": "Water Leak at Unknown Location" } ], "Selected": "Clear", "Selected_id": 0 }, "Units": "", "Min": 0, "Max": 0, "Type": "List", "Instance": 1, "CommandClass": "COMMAND_CLASS_NOTIFICATION", "Index": 5, "Node": 36, "Genre": "User", "Help": "Water Alerts", "ValueIDKey": 1407375493578772, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
||||||
OpenZWave/1/node/36/instance/1/commandclass/113/value/72057594647953425/,{ "Label": "Instance 1: Previous Event Cleared", "Value": 0, "Units": "", "Min": 0, "Max": 255, "Type": "Byte", "Instance": 1, "CommandClass": "COMMAND_CLASS_NOTIFICATION", "Index": 256, "Node": 36, "Genre": "User", "Help": "Previous Event that was sent", "ValueIDKey": 72057594647953425, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
OpenZWave/1/node/36/instance/1/commandclass/113/value/72057594647953425/,{ "Label": "Instance 1: Previous Event Cleared", "Value": 0, "Units": "", "Min": 0, "Max": 255, "Type": "Byte", "Instance": 1, "CommandClass": "COMMAND_CLASS_NOTIFICATION", "Index": 256, "Node": 36, "Genre": "User", "Help": "Previous Event that was sent", "ValueIDKey": 72057594647953425, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
||||||
OpenZWave/1/node/36/instance/1/commandclass/114/,{ "Instance": 1, "CommandClassId": 114, "CommandClass": "COMMAND_CLASS_MANUFACTURER_SPECIFIC", "TimeStamp": 1579566891}
|
OpenZWave/1/node/36/instance/1/commandclass/114/,{ "Instance": 1, "CommandClassId": 114, "CommandClass": "COMMAND_CLASS_MANUFACTURER_SPECIFIC", "TimeStamp": 1579566891}
|
||||||
OpenZWave/1/node/36/instance/1/commandclass/114/value/618430483/,{ "Label": "Loaded Config Revision", "Value": 10, "Units": "", "Min": -2147483648, "Max": 2147483647, "Type": "Int", "Instance": 1, "CommandClass": "COMMAND_CLASS_MANUFACTURER_SPECIFIC", "Index": 0, "Node": 36, "Genre": "System", "Help": "Revision of the Config file currently loaded", "ValueIDKey": 618430483, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
OpenZWave/1/node/36/instance/1/commandclass/114/value/618430483/,{ "Label": "Loaded Config Revision", "Value": 10, "Units": "", "Min": -2147483648, "Max": 2147483647, "Type": "Int", "Instance": 1, "CommandClass": "COMMAND_CLASS_MANUFACTURER_SPECIFIC", "Index": 0, "Node": 36, "Genre": "System", "Help": "Revision of the Config file currently loaded", "ValueIDKey": 618430483, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
||||||
|
@ -142,7 +142,7 @@ OpenZWave/1/node/36/instance/2/commandclass/94/value/618102817/,{ "Label": "I
|
||||||
OpenZWave/1/node/36/instance/2/commandclass/94/value/281475594813478/,{ "Label": "Instance 2: InstallerIcon", "Value": 3079, "Units": "", "Min": -32768, "Max": 32767, "Type": "Short", "Instance": 2, "CommandClass": "COMMAND_CLASS_ZWAVEPLUS_INFO", "Index": 1, "Node": 36, "Genre": "System", "Help": "Icon File to use for the Installer Application", "ValueIDKey": 281475594813478, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
OpenZWave/1/node/36/instance/2/commandclass/94/value/281475594813478/,{ "Label": "Instance 2: InstallerIcon", "Value": 3079, "Units": "", "Min": -32768, "Max": 32767, "Type": "Short", "Instance": 2, "CommandClass": "COMMAND_CLASS_ZWAVEPLUS_INFO", "Index": 1, "Node": 36, "Genre": "System", "Help": "Icon File to use for the Installer Application", "ValueIDKey": 281475594813478, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
||||||
OpenZWave/1/node/36/instance/2/commandclass/94/value/562950571524134/,{ "Label": "Instance 2: UserIcon", "Value": 3079, "Units": "", "Min": -32768, "Max": 32767, "Type": "Short", "Instance": 2, "CommandClass": "COMMAND_CLASS_ZWAVEPLUS_INFO", "Index": 2, "Node": 36, "Genre": "System", "Help": "Icon File to use for the User Application", "ValueIDKey": 562950571524134, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
OpenZWave/1/node/36/instance/2/commandclass/94/value/562950571524134/,{ "Label": "Instance 2: UserIcon", "Value": 3079, "Units": "", "Min": -32768, "Max": 32767, "Type": "Short", "Instance": 2, "CommandClass": "COMMAND_CLASS_ZWAVEPLUS_INFO", "Index": 2, "Node": 36, "Genre": "System", "Help": "Icon File to use for the User Application", "ValueIDKey": 562950571524134, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
||||||
OpenZWave/1/node/36/instance/2/commandclass/113/,{ "Instance": 2, "CommandClassId": 113, "CommandClass": "COMMAND_CLASS_NOTIFICATION", "TimeStamp": 1579566891}
|
OpenZWave/1/node/36/instance/2/commandclass/113/,{ "Instance": 2, "CommandClassId": 113, "CommandClass": "COMMAND_CLASS_NOTIFICATION", "TimeStamp": 1579566891}
|
||||||
OpenZWave/1/node/36/instance/2/commandclass/113/value/1407375493578788/,{ "Label": "Instance 2: Water", "Value": { "List": [ { "Value": 0, "Label": "Clear" }, { "Value": 2, "Label": "Water Leak at Unknown Location" } ], "Selected": "Clear" }, "Units": "", "Min": 0, "Max": 0, "Type": "List", "Instance": 2, "CommandClass": "COMMAND_CLASS_NOTIFICATION", "Index": 5, "Node": 36, "Genre": "User", "Help": "Water Alerts", "ValueIDKey": 1407375493578788, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
OpenZWave/1/node/36/instance/2/commandclass/113/value/1407375493578788/,{ "Label": "Instance 2: Water", "Value": { "List": [ { "Value": 0, "Label": "Clear" }, { "Value": 2, "Label": "Water Leak at Unknown Location" } ], "Selected": "Clear", "Selected_id": 0 }, "Units": "", "Min": 0, "Max": 0, "Type": "List", "Instance": 2, "CommandClass": "COMMAND_CLASS_NOTIFICATION", "Index": 5, "Node": 36, "Genre": "User", "Help": "Water Alerts", "ValueIDKey": 1407375493578788, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
||||||
OpenZWave/1/node/36/instance/2/commandclass/113/value/72057594647953441/,{ "Label": "Instance 2: Previous Event Cleared", "Value": 0, "Units": "", "Min": 0, "Max": 255, "Type": "Byte", "Instance": 2, "CommandClass": "COMMAND_CLASS_NOTIFICATION", "Index": 256, "Node": 36, "Genre": "User", "Help": "Previous Event that was sent", "ValueIDKey": 72057594647953441, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
OpenZWave/1/node/36/instance/2/commandclass/113/value/72057594647953441/,{ "Label": "Instance 2: Previous Event Cleared", "Value": 0, "Units": "", "Min": 0, "Max": 255, "Type": "Byte", "Instance": 2, "CommandClass": "COMMAND_CLASS_NOTIFICATION", "Index": 256, "Node": 36, "Genre": "User", "Help": "Previous Event that was sent", "ValueIDKey": 72057594647953441, "ReadOnly": false, "WriteOnly": false, "ValueSet": false, "ValuePolled": false, "ChangeVerified": false, "Event": "valueAdded", "TimeStamp": 1579566891}
|
||||||
OpenZWave/1/node/36/association/1/,{ "Name": "Lifeline", "Help": "", "MaxAssociations": 5, "Members": [ "1.1" ], "TimeStamp": 1579566891}
|
OpenZWave/1/node/36/association/1/,{ "Name": "Lifeline", "Help": "", "MaxAssociations": 5, "Members": [ "1.1" ], "TimeStamp": 1579566891}
|
||||||
OpenZWave/1/node/36/association/2/,{ "Name": "Send the configuration parameter 0x88", "Help": "", "MaxAssociations": 5, "Members": [], "TimeStamp": 1579566891}
|
OpenZWave/1/node/36/association/2/,{ "Name": "Send the configuration parameter 0x88", "Help": "", "MaxAssociations": 5, "Members": [], "TimeStamp": 1579566891}
|
||||||
|
|
Can't render this file because it contains an unexpected character in line 1 and column 26.
|
Loading…
Reference in New Issue