From ae3973144c5bce5009fbb85ca832ae6bb8a31de9 Mon Sep 17 00:00:00 2001 From: Adam Mills Date: Wed, 14 Jun 2017 08:41:20 -0400 Subject: [PATCH] Discover Z-Wave values by index (#7853) * Discover Z-Wave values by index * Add URLs for enums (Some Assembly Required) * URLs on one line * Move lint suppression to single line --- homeassistant/components/zwave/__init__.py | 2 +- homeassistant/components/zwave/const.py | 36 ++++++++++++++++-- .../components/zwave/discovery_schemas.py | 38 +++++++++---------- homeassistant/components/zwave/util.py | 19 ++-------- tests/components/zwave/test_init.py | 4 +- 5 files changed, 56 insertions(+), 43 deletions(-) diff --git a/homeassistant/components/zwave/__init__.py b/homeassistant/components/zwave/__init__.py index f3507211907..e82ce286e01 100755 --- a/homeassistant/components/zwave/__init__.py +++ b/homeassistant/components/zwave/__init__.py @@ -533,7 +533,7 @@ def setup(hass, config): for value in ( node.get_values(class_id=const.COMMAND_CLASS_METER) .values()): - if value.index != const.METER_RESET_INDEX: + if value.index != const.INDEX_METER_RESET: continue if value.instance != instance: continue diff --git a/homeassistant/components/zwave/const.py b/homeassistant/components/zwave/const.py index 6f8c7d1fe75..57e77fe49cb 100644 --- a/homeassistant/components/zwave/const.py +++ b/homeassistant/components/zwave/const.py @@ -326,14 +326,42 @@ DISC_GENERIC_DEVICE_CLASS = "generic_device_class" DISC_GENRE = "genre" DISC_INDEX = "index" DISC_INSTANCE = "instance" -DISC_LABEL = "label" DISC_NODE_ID = "node_id" DISC_OPTIONAL = "optional" DISC_PRIMARY = "primary" -DISC_READONLY = "readonly" +DISC_SCHEMAS = "schemas" DISC_SPECIFIC_DEVICE_CLASS = "specific_device_class" DISC_TYPE = "type" DISC_VALUES = "values" -DISC_WRITEONLY = "writeonly" -METER_RESET_INDEX = 33 +# noqa +# https://github.com/OpenZWave/open-zwave/blob/67f180eb565f0054f517ff395c71ecd706f6a837/cpp/src/command_classes/Alarm.cpp#L49 +# See also: +# https://github.com/OpenZWave/open-zwave/blob/67f180eb565f0054f517ff395c71ecd706f6a837/cpp/src/command_classes/Alarm.cpp#L275 +# https://github.com/OpenZWave/open-zwave/blob/67f180eb565f0054f517ff395c71ecd706f6a837/cpp/src/command_classes/Alarm.cpp#L278 +INDEX_ALARM_TYPE = 0 +INDEX_ALARM_LEVEL = 1 +INDEX_ALARM_ACCESS_CONTROL = 9 + +# https://github.com/OpenZWave/open-zwave/blob/67f180eb565f0054f517ff395c71ecd706f6a837/cpp/src/command_classes/DoorLock.cpp#L77 +INDEX_DOOR_LOCK_LOCK = 0 + +# https://github.com/OpenZWave/open-zwave/blob/67f180eb565f0054f517ff395c71ecd706f6a837/cpp/src/command_classes/Meter.cpp#L114 +# See also: +# https://github.com/OpenZWave/open-zwave/blob/67f180eb565f0054f517ff395c71ecd706f6a837/cpp/src/command_classes/Meter.cpp#L279 +INDEX_METER_POWER = 8 +INDEX_METER_RESET = 33 + +# https://github.com/OpenZWave/open-zwave/blob/67f180eb565f0054f517ff395c71ecd706f6a837/cpp/src/command_classes/SensorMultilevel.cpp#L50 +INDEX_SENSOR_MULTILEVEL_TEMPERATURE = 1 +INDEX_SENSOR_MULTILEVEL_POWER = 4 + +# https://github.com/OpenZWave/open-zwave/blob/67f180eb565f0054f517ff395c71ecd706f6a837/cpp/src/command_classes/Color.cpp#L109 +INDEX_SWITCH_COLOR_COLOR = 0 +INDEX_SWITCH_COLOR_CHANNELS = 2 + +# https://github.com/OpenZWave/open-zwave/blob/67f180eb565f0054f517ff395c71ecd706f6a837/cpp/src/command_classes/SwitchMultilevel.cpp#L54 +INDEX_SWITCH_MULTILEVEL_LEVEL = 0 +INDEX_SWITCH_MULTILEVEL_BRIGHT = 1 +INDEX_SWITCH_MULTILEVEL_DIM = 2 +INDEX_SWITCH_MULTILEVEL_DURATION = 5 diff --git a/homeassistant/components/zwave/discovery_schemas.py b/homeassistant/components/zwave/discovery_schemas.py index 17c37556aea..c880aeb3b31 100644 --- a/homeassistant/components/zwave/discovery_schemas.py +++ b/homeassistant/components/zwave/discovery_schemas.py @@ -3,9 +3,12 @@ from . import const DEFAULT_VALUES_SCHEMA = { 'power': { - const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SENSOR_MULTILEVEL, - const.COMMAND_CLASS_METER], - const.DISC_LABEL: ['Power'], + const.DISC_SCHEMAS: [ + {const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SENSOR_MULTILEVEL], + const.DISC_INDEX: [const.INDEX_SENSOR_MULTILEVEL_POWER]}, + {const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_METER], + const.DISC_INDEX: [const.INDEX_METER_POWER]}, + ], const.DISC_OPTIONAL: True, }, } @@ -36,7 +39,7 @@ DISCOVERY_SCHEMAS = [ }, 'temperature': { const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SENSOR_MULTILEVEL], - const.DISC_LABEL: 'Temperature', + const.DISC_INDEX: [const.INDEX_SENSOR_MULTILEVEL_TEMPERATURE], const.DISC_OPTIONAL: True, }, 'mode': { @@ -81,12 +84,12 @@ DISCOVERY_SCHEMAS = [ }, 'open': { const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL], - const.DISC_LABEL: ['Open', 'Up', 'Bright'], + const.DISC_INDEX: [const.INDEX_SWITCH_MULTILEVEL_BRIGHT], const.DISC_OPTIONAL: True, }, 'close': { const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL], - const.DISC_LABEL: ['Close', 'Down', 'Dim'], + const.DISC_INDEX: [const.INDEX_SWITCH_MULTILEVEL_DIM], const.DISC_OPTIONAL: True, }})}, {const.DISC_COMPONENT: 'cover', # Garage Door @@ -118,28 +121,22 @@ DISCOVERY_SCHEMAS = [ const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{ const.DISC_PRIMARY: { const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL], - const.DISC_GENRE: const.GENRE_USER, + const.DISC_INDEX: [const.INDEX_SWITCH_MULTILEVEL_LEVEL], const.DISC_TYPE: const.TYPE_BYTE, }, 'dimming_duration': { const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_MULTILEVEL], - const.DISC_GENRE: const.GENRE_SYSTEM, - const.DISC_TYPE: const.TYPE_BYTE, - const.DISC_LABEL: 'Dimming Duration', + const.DISC_INDEX: [const.INDEX_SWITCH_MULTILEVEL_DURATION], const.DISC_OPTIONAL: True, }, 'color': { const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_COLOR], - const.DISC_GENRE: const.GENRE_USER, - const.DISC_TYPE: const.TYPE_STRING, - const.DISC_READONLY: False, - const.DISC_WRITEONLY: False, + const.DISC_INDEX: [const.INDEX_SWITCH_COLOR_COLOR], const.DISC_OPTIONAL: True, }, 'color_channels': { const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_SWITCH_COLOR], - const.DISC_GENRE: const.GENRE_SYSTEM, - const.DISC_TYPE: const.TYPE_INT, + const.DISC_INDEX: [const.INDEX_SWITCH_COLOR_CHANNELS], const.DISC_OPTIONAL: True, }})}, {const.DISC_COMPONENT: 'lock', @@ -150,22 +147,21 @@ DISCOVERY_SCHEMAS = [ const.DISC_VALUES: dict(DEFAULT_VALUES_SCHEMA, **{ const.DISC_PRIMARY: { const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_DOOR_LOCK], - const.DISC_TYPE: const.TYPE_BOOL, - const.DISC_GENRE: const.GENRE_USER, + const.DISC_INDEX: [const.INDEX_DOOR_LOCK_LOCK], }, 'access_control': { const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_ALARM], - const.DISC_LABEL: 'Access Control', + const.DISC_INDEX: [const.INDEX_ALARM_ACCESS_CONTROL], const.DISC_OPTIONAL: True, }, 'alarm_type': { const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_ALARM], - const.DISC_LABEL: 'Alarm Type', + const.DISC_INDEX: [const.INDEX_ALARM_TYPE], const.DISC_OPTIONAL: True, }, 'alarm_level': { const.DISC_COMMAND_CLASS: [const.COMMAND_CLASS_ALARM], - const.DISC_LABEL: 'Alarm Level', + const.DISC_INDEX: [const.INDEX_ALARM_LEVEL], const.DISC_OPTIONAL: True, }, 'v2btze_advanced': { diff --git a/homeassistant/components/zwave/util.py b/homeassistant/components/zwave/util.py index b589e73ceb4..6abdc180742 100644 --- a/homeassistant/components/zwave/util.py +++ b/homeassistant/components/zwave/util.py @@ -43,21 +43,6 @@ def check_value_schema(value, schema): _LOGGER.debug("value.genre %s not in genre %s", value.genre, schema[const.DISC_GENRE]) return False - if (const.DISC_READONLY in schema and - value.is_read_only is not schema[const.DISC_READONLY]): - _LOGGER.debug("value.is_read_only %s not %s", - value.is_read_only, schema[const.DISC_READONLY]) - return False - if (const.DISC_WRITEONLY in schema and - value.is_write_only is not schema[const.DISC_WRITEONLY]): - _LOGGER.debug("value.is_write_only %s not %s", - value.is_write_only, schema[const.DISC_WRITEONLY]) - return False - if (const.DISC_LABEL in schema and - value.label not in schema[const.DISC_LABEL]): - _LOGGER.debug("value.label %s not in label %s", - value.label, schema[const.DISC_LABEL]) - return False if (const.DISC_INDEX in schema and value.index not in schema[const.DISC_INDEX]): _LOGGER.debug("value.index %s not in index %s", @@ -68,6 +53,10 @@ def check_value_schema(value, schema): _LOGGER.debug("value.instance %s not in instance %s", value.instance, schema[const.DISC_INSTANCE]) return False + if const.DISC_SCHEMAS in schema: + for schema_item in schema[const.DISC_SCHEMAS]: + if not check_value_schema(value, schema_item): + return False return True diff --git a/tests/components/zwave/test_init.py b/tests/components/zwave/test_init.py index 8b539d3a7c9..eac33168fb7 100644 --- a/tests/components/zwave/test_init.py +++ b/tests/components/zwave/test_init.py @@ -308,9 +308,9 @@ def test_value_discovery_existing_entity(hass, mock_openzwave): with patch.object(zwave.node_entity.ZWaveBaseEntity, 'maybe_schedule_update', new=mock_update): temperature = MockValue( - data=23.5, node=node, index=12, instance=13, + data=23.5, node=node, index=1, instance=13, command_class=const.COMMAND_CLASS_SENSOR_MULTILEVEL, - label='Temperature', genre=const.GENRE_USER, units='C') + genre=const.GENRE_USER, units='C') hass.async_add_job(mock_receivers[0], node, temperature) yield from hass.async_block_till_done()