From 9a12cc979cac5d3ec21260a1bfa62a4ee43b39bc Mon Sep 17 00:00:00 2001 From: turbokongen Date: Thu, 13 Apr 2017 18:03:30 +0200 Subject: [PATCH 01/18] # This is a combination of 3 commits. # The first commit's message is: Add seperate zwave panel # The 2nd commit message will be skipped: # unused import # The 3rd commit message will be skipped: # Use get for config --- homeassistant/components/frontend/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index 617db06be2cc1..7a22f902add10 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -179,6 +179,10 @@ def setup(hass, config): register_built_in_panel(hass, 'map', 'Map', 'mdi:account-location') + zwave = config.get('zwave') + if zwave: + register_built_in_panel(hass, 'zwave', 'Z-Wave', 'mdi:nfc') + for panel in ('dev-event', 'dev-info', 'dev-service', 'dev-state', 'dev-template'): register_built_in_panel(hass, panel) From 9fe352caf9bb8d3617a187d5ac0387083151e2b6 Mon Sep 17 00:00:00 2001 From: turbokongen Date: Thu, 13 Apr 2017 18:03:30 +0200 Subject: [PATCH 02/18] Add seperate zwave panel --- homeassistant/components/frontend/__init__.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index 7a22f902add10..617db06be2cc1 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -179,10 +179,6 @@ def setup(hass, config): register_built_in_panel(hass, 'map', 'Map', 'mdi:account-location') - zwave = config.get('zwave') - if zwave: - register_built_in_panel(hass, 'zwave', 'Z-Wave', 'mdi:nfc') - for panel in ('dev-event', 'dev-info', 'dev-service', 'dev-state', 'dev-template'): register_built_in_panel(hass, panel) From 8566f5a62ba3c0495f4ba671a84067f3f8b85a04 Mon Sep 17 00:00:00 2001 From: turbokongen Date: Mon, 1 May 2017 00:06:05 +0200 Subject: [PATCH 03/18] more info --- homeassistant/components/zwave/__init__.py | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/homeassistant/components/zwave/__init__.py b/homeassistant/components/zwave/__init__.py index 4033e195be03b..860f3528fd157 100755 --- a/homeassistant/components/zwave/__init__.py +++ b/homeassistant/components/zwave/__init__.py @@ -13,6 +13,8 @@ import voluptuous as vol +from homeassistant.components.http import HomeAssistantView +from homeassistant.const import HTTP_NOT_FOUND from homeassistant.core import CoreState from homeassistant.loader import get_platform from homeassistant.helpers import discovery @@ -22,6 +24,7 @@ from homeassistant.helpers.entity_values import EntityValues from homeassistant.helpers.event import track_time_change from homeassistant.util import convert, slugify +import homeassistant.core as ha import homeassistant.config as conf_util import homeassistant.helpers.config_validation as cv from homeassistant.helpers.dispatcher import ( @@ -607,10 +610,63 @@ def start_zwave(_service_or_event): if 'frontend' in hass.config.components: register_built_in_panel(hass, 'zwave', 'Z-Wave', 'mdi:nfc') + hass.http.register_view(ZWaveNodeGroupView) + hass.http.register_view(ZWaveNodeConfigView) return True +class ZWaveNodeGroupView(HomeAssistantView): + """View to return the nodes group configuration.""" + + url = "/api/zwave/groups/{node_id}" + name = "api:zwave:groups" + + @ha.callback + def get(self, request, node_id): + """Retrieve groups of node.""" + hass = request.app['hass'] + network = hass.data.get(ZWAVE_NETWORK) + _LOGGER.info(network.nodes[int(node_id)]) + node = network.nodes[int(node_id)] + groups = node.groups_to_dict() + _LOGGER.info('Groups: %s', groups) + if groups: + return self.json(groups) + else: + return self.json_message('Node not found', HTTP_NOT_FOUND) + + +class ZWaveNodeConfigView(HomeAssistantView): + """View to return the nodes configuration options.""" + + url = "/api/zwave/config/{node_id}" + name = "api:zwave:config" + + @ha.callback + def get(self, request, node_id): + """Retrieve configurations of node.""" + hass = request.app['hass'] + network = hass.data.get(ZWAVE_NETWORK) + node = network.nodes[int(node_id)] + config = {} + for value in ( + node.get_values(class_id=const.COMMAND_CLASS_CONFIGURATION) + .values()): + config[value.index] = {'label': value.label, + 'type': value.type, + 'help': value.help, + 'data_items': value.data_items, + 'data': value.data, + 'max': value.max, + 'min': value.min} + _LOGGER.info('Config: %s', config) + if config: + return self.json(config) + else: + return self.json_message('Node not found', HTTP_NOT_FOUND) + + class ZWaveDeviceEntityValues(): """Manages entity access to the underlying zwave value objects.""" From 21a68df55d716181d3e806d78f0d7999de28db28 Mon Sep 17 00:00:00 2001 From: turbokongen Date: Mon, 1 May 2017 13:36:22 +0200 Subject: [PATCH 04/18] Add usercodeview --- homeassistant/components/zwave/__init__.py | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/homeassistant/components/zwave/__init__.py b/homeassistant/components/zwave/__init__.py index 860f3528fd157..96e4f0dd7d9df 100755 --- a/homeassistant/components/zwave/__init__.py +++ b/homeassistant/components/zwave/__init__.py @@ -69,6 +69,8 @@ DEFAULT_CONF_REFRESH_DELAY = 5 DATA_ZWAVE_DICT = 'zwave_devices' +OZW_LOG_FILENAME = 'OZW_Log.txt' +URL_API_OZW_LOG = '/api/zwave/ozwlog' ZWAVE_NETWORK = 'zwave_network' RENAME_NODE_SCHEMA = vol.Schema({ @@ -612,6 +614,9 @@ def start_zwave(_service_or_event): register_built_in_panel(hass, 'zwave', 'Z-Wave', 'mdi:nfc') hass.http.register_view(ZWaveNodeGroupView) hass.http.register_view(ZWaveNodeConfigView) + hass.http.register_view(ZWaveUserCodeView) + hass.http.register_static_path( + URL_API_OZW_LOG, hass.config.path(OZW_LOG_FILENAME), False) return True @@ -667,6 +672,39 @@ def get(self, request, node_id): return self.json_message('Node not found', HTTP_NOT_FOUND) +class ZWaveUserCodeView(HomeAssistantView): + """View to return the nodes usercode configuration.""" + + url = "/api/zwave/usercodes/{node_id}" + name = "api:zwave:usercodes" + + @ha.callback + def get(self, request, node_id): + """Retrieve usercodes of node.""" + hass = request.app['hass'] + network = hass.data.get(ZWAVE_NETWORK) + node = network.nodes[int(node_id)] + usercodes = {} + if node.has_command_class(const.COMMAND_CLASS_USER_CODE): + for value in ( + node.get_values(class_id=const.COMMAND_CLASS_USER_CODE) + .values()): + if value.genre != const.GENRE_USER: + continue + usercodes[value.index] = {'code': value.data, + 'label': value.label, + 'length': len(value.data)} + _LOGGER.info('Usercodes: %s', usercodes) + if usercodes: + return self.json(usercodes) + else: + return self.json_message('Node does not have usercodes', + HTTP_NOT_FOUND) + else: + return self.json_message('Node does not have usercodes', + HTTP_NOT_FOUND) + + class ZWaveDeviceEntityValues(): """Manages entity access to the underlying zwave value objects.""" From e2894aa37269a41b5d814512a6d2066f0d1caf2f Mon Sep 17 00:00:00 2001 From: turbokongen Date: Wed, 3 May 2017 20:20:02 +0200 Subject: [PATCH 05/18] Improve api --- homeassistant/components/zwave/__init__.py | 26 +++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/zwave/__init__.py b/homeassistant/components/zwave/__init__.py index 96e4f0dd7d9df..1ff942aa96f6c 100755 --- a/homeassistant/components/zwave/__init__.py +++ b/homeassistant/components/zwave/__init__.py @@ -630,11 +630,23 @@ class ZWaveNodeGroupView(HomeAssistantView): @ha.callback def get(self, request, node_id): """Retrieve groups of node.""" + from openzwave.group import ZWaveGroup + hass = request.app['hass'] network = hass.data.get(ZWAVE_NETWORK) - _LOGGER.info(network.nodes[int(node_id)]) - node = network.nodes[int(node_id)] - groups = node.groups_to_dict() + _LOGGER.info(network.nodes.get(int(node_id))) + node = network.nodes.get(int(node_id)) + if node is None: + return self.json_message('Node not found', HTTP_NOT_FOUND) + groupdata = node.groups_to_dict() + groups = {} + for key in groupdata.keys(): + groupnode = ZWaveGroup(key, network, int(node_id)) + groups[key] = {'associations': groupnode.associations, + 'association_instances': + groupnode.associations_instances, + 'label': groupnode.label, + 'max_associations': groupnode.max_associations} _LOGGER.info('Groups: %s', groups) if groups: return self.json(groups) @@ -653,7 +665,9 @@ def get(self, request, node_id): """Retrieve configurations of node.""" hass = request.app['hass'] network = hass.data.get(ZWAVE_NETWORK) - node = network.nodes[int(node_id)] + node = network.nodes.get(int(node_id)) + if node is None: + return self.json_message('Node not found', HTTP_NOT_FOUND) config = {} for value in ( node.get_values(class_id=const.COMMAND_CLASS_CONFIGURATION) @@ -683,7 +697,9 @@ def get(self, request, node_id): """Retrieve usercodes of node.""" hass = request.app['hass'] network = hass.data.get(ZWAVE_NETWORK) - node = network.nodes[int(node_id)] + node = network.nodes.get[int(node_id)] + if node is None: + return self.json_message('Node not found', HTTP_NOT_FOUND) usercodes = {} if node.has_command_class(const.COMMAND_CLASS_USER_CODE): for value in ( From a2262d67ac0775e7219d2bab2676134df6d6e4a3 Mon Sep 17 00:00:00 2001 From: turbokongen Date: Fri, 5 May 2017 21:18:32 +0200 Subject: [PATCH 06/18] Improve api --- homeassistant/components/zwave/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/zwave/__init__.py b/homeassistant/components/zwave/__init__.py index 1ff942aa96f6c..85254b99003c6 100755 --- a/homeassistant/components/zwave/__init__.py +++ b/homeassistant/components/zwave/__init__.py @@ -697,7 +697,7 @@ def get(self, request, node_id): """Retrieve usercodes of node.""" hass = request.app['hass'] network = hass.data.get(ZWAVE_NETWORK) - node = network.nodes.get[int(node_id)] + node = network.nodes.get(int(node_id)) if node is None: return self.json_message('Node not found', HTTP_NOT_FOUND) usercodes = {} From 8d646fd693743dbd30796c47df6a9edbe06b6bcb Mon Sep 17 00:00:00 2001 From: turbokongen Date: Fri, 5 May 2017 22:08:02 +0200 Subject: [PATCH 07/18] Separate api into own file. --- homeassistant/components/zwave/__init__.py | 114 ++------------------- homeassistant/components/zwave/api.py | 111 ++++++++++++++++++++ 2 files changed, 117 insertions(+), 108 deletions(-) create mode 100644 homeassistant/components/zwave/api.py diff --git a/homeassistant/components/zwave/__init__.py b/homeassistant/components/zwave/__init__.py index 85254b99003c6..c49983b3178ab 100755 --- a/homeassistant/components/zwave/__init__.py +++ b/homeassistant/components/zwave/__init__.py @@ -13,8 +13,6 @@ import voluptuous as vol -from homeassistant.components.http import HomeAssistantView -from homeassistant.const import HTTP_NOT_FOUND from homeassistant.core import CoreState from homeassistant.loader import get_platform from homeassistant.helpers import discovery @@ -24,13 +22,13 @@ from homeassistant.helpers.entity_values import EntityValues from homeassistant.helpers.event import track_time_change from homeassistant.util import convert, slugify -import homeassistant.core as ha import homeassistant.config as conf_util import homeassistant.helpers.config_validation as cv from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send) from homeassistant.components.frontend import register_built_in_panel +from . import api from . import const from .const import DOMAIN from .node_entity import ZWaveBaseEntity, ZWaveNodeEntity @@ -388,7 +386,7 @@ def stop_network(_service_or_event): def rename_node(service): """Rename a node.""" node_id = service.data.get(const.ATTR_NODE_ID) - node = hass.data[ZWAVE_NETWORK].nodes[node_id] + node = network.nodes[node_id] name = service.data.get(const.ATTR_NAME) node.name = name _LOGGER.info( @@ -506,7 +504,7 @@ def start_zwave(_service_or_event): # to be ready. for i in range(const.NETWORK_READY_WAIT_SECS): _LOGGER.debug( - "network state: %d %s", hass.data[ZWAVE_NETWORK].state, + "network state: %d %s", network.state, network.state_str) if network.state >= network.STATE_AWAKED: _LOGGER.info("Z-Wave ready after %d seconds", i) @@ -612,115 +610,15 @@ def start_zwave(_service_or_event): if 'frontend' in hass.config.components: register_built_in_panel(hass, 'zwave', 'Z-Wave', 'mdi:nfc') - hass.http.register_view(ZWaveNodeGroupView) - hass.http.register_view(ZWaveNodeConfigView) - hass.http.register_view(ZWaveUserCodeView) + hass.http.register_view(api.ZWaveNodeGroupView) + hass.http.register_view(api.ZWaveNodeConfigView) + hass.http.register_view(api.ZWaveUserCodeView) hass.http.register_static_path( URL_API_OZW_LOG, hass.config.path(OZW_LOG_FILENAME), False) return True -class ZWaveNodeGroupView(HomeAssistantView): - """View to return the nodes group configuration.""" - - url = "/api/zwave/groups/{node_id}" - name = "api:zwave:groups" - - @ha.callback - def get(self, request, node_id): - """Retrieve groups of node.""" - from openzwave.group import ZWaveGroup - - hass = request.app['hass'] - network = hass.data.get(ZWAVE_NETWORK) - _LOGGER.info(network.nodes.get(int(node_id))) - node = network.nodes.get(int(node_id)) - if node is None: - return self.json_message('Node not found', HTTP_NOT_FOUND) - groupdata = node.groups_to_dict() - groups = {} - for key in groupdata.keys(): - groupnode = ZWaveGroup(key, network, int(node_id)) - groups[key] = {'associations': groupnode.associations, - 'association_instances': - groupnode.associations_instances, - 'label': groupnode.label, - 'max_associations': groupnode.max_associations} - _LOGGER.info('Groups: %s', groups) - if groups: - return self.json(groups) - else: - return self.json_message('Node not found', HTTP_NOT_FOUND) - - -class ZWaveNodeConfigView(HomeAssistantView): - """View to return the nodes configuration options.""" - - url = "/api/zwave/config/{node_id}" - name = "api:zwave:config" - - @ha.callback - def get(self, request, node_id): - """Retrieve configurations of node.""" - hass = request.app['hass'] - network = hass.data.get(ZWAVE_NETWORK) - node = network.nodes.get(int(node_id)) - if node is None: - return self.json_message('Node not found', HTTP_NOT_FOUND) - config = {} - for value in ( - node.get_values(class_id=const.COMMAND_CLASS_CONFIGURATION) - .values()): - config[value.index] = {'label': value.label, - 'type': value.type, - 'help': value.help, - 'data_items': value.data_items, - 'data': value.data, - 'max': value.max, - 'min': value.min} - _LOGGER.info('Config: %s', config) - if config: - return self.json(config) - else: - return self.json_message('Node not found', HTTP_NOT_FOUND) - - -class ZWaveUserCodeView(HomeAssistantView): - """View to return the nodes usercode configuration.""" - - url = "/api/zwave/usercodes/{node_id}" - name = "api:zwave:usercodes" - - @ha.callback - def get(self, request, node_id): - """Retrieve usercodes of node.""" - hass = request.app['hass'] - network = hass.data.get(ZWAVE_NETWORK) - node = network.nodes.get(int(node_id)) - if node is None: - return self.json_message('Node not found', HTTP_NOT_FOUND) - usercodes = {} - if node.has_command_class(const.COMMAND_CLASS_USER_CODE): - for value in ( - node.get_values(class_id=const.COMMAND_CLASS_USER_CODE) - .values()): - if value.genre != const.GENRE_USER: - continue - usercodes[value.index] = {'code': value.data, - 'label': value.label, - 'length': len(value.data)} - _LOGGER.info('Usercodes: %s', usercodes) - if usercodes: - return self.json(usercodes) - else: - return self.json_message('Node does not have usercodes', - HTTP_NOT_FOUND) - else: - return self.json_message('Node does not have usercodes', - HTTP_NOT_FOUND) - - class ZWaveDeviceEntityValues(): """Manages entity access to the underlying zwave value objects.""" diff --git a/homeassistant/components/zwave/api.py b/homeassistant/components/zwave/api.py new file mode 100644 index 0000000000000..df3ae6414b1c2 --- /dev/null +++ b/homeassistant/components/zwave/api.py @@ -0,0 +1,111 @@ +"""API class to give info to the Z-Wave panel.""" + +import logging +import homeassistant.core as ha +from homeassistant.components.http import HomeAssistantView +from homeassistant.const import HTTP_NOT_FOUND +from . import const + +_LOGGER = logging.getLogger(__name__) + +ZWAVE_NETWORK = 'zwave_network' + + +class ZWaveNodeGroupView(HomeAssistantView): + """View to return the nodes group configuration.""" + + url = "/api/zwave/groups/{node_id}" + name = "api:zwave:groups" + + @ha.callback + def get(self, request, node_id): + """Retrieve groups of node.""" + from openzwave.group import ZWaveGroup + + hass = request.app['hass'] + network = hass.data.get(ZWAVE_NETWORK) + _LOGGER.info(network.nodes.get(int(node_id))) + node = network.nodes.get(int(node_id)) + if node is None: + return self.json_message('Node not found', HTTP_NOT_FOUND) + groupdata = node.groups_to_dict() + groups = {} + for key in groupdata.keys(): + groupnode = ZWaveGroup(key, network, int(node_id)) + groups[key] = {'associations': groupnode.associations, + 'association_instances': + groupnode.associations_instances, + 'label': groupnode.label, + 'max_associations': groupnode.max_associations} + _LOGGER.info('Groups: %s', groups) + if groups: + return self.json(groups) + else: + return self.json_message('Node not found', HTTP_NOT_FOUND) + + +class ZWaveNodeConfigView(HomeAssistantView): + """View to return the nodes configuration options.""" + + url = "/api/zwave/config/{node_id}" + name = "api:zwave:config" + + @ha.callback + def get(self, request, node_id): + """Retrieve configurations of node.""" + hass = request.app['hass'] + network = hass.data.get(ZWAVE_NETWORK) + node = network.nodes.get(int(node_id)) + if node is None: + return self.json_message('Node not found', HTTP_NOT_FOUND) + config = {} + for value in ( + node.get_values(class_id=const.COMMAND_CLASS_CONFIGURATION) + .values()): + config[value.index] = {'label': value.label, + 'type': value.type, + 'help': value.help, + 'data_items': value.data_items, + 'data': value.data, + 'max': value.max, + 'min': value.min} + _LOGGER.info('Config: %s', config) + if config: + return self.json(config) + else: + return self.json_message('Node not found', HTTP_NOT_FOUND) + + +class ZWaveUserCodeView(HomeAssistantView): + """View to return the nodes usercode configuration.""" + + url = "/api/zwave/usercodes/{node_id}" + name = "api:zwave:usercodes" + + @ha.callback + def get(self, request, node_id): + """Retrieve usercodes of node.""" + hass = request.app['hass'] + network = hass.data.get(ZWAVE_NETWORK) + node = network.nodes.get(int(node_id)) + if node is None: + return self.json_message('Node not found', HTTP_NOT_FOUND) + usercodes = {} + if node.has_command_class(const.COMMAND_CLASS_USER_CODE): + for value in ( + node.get_values(class_id=const.COMMAND_CLASS_USER_CODE) + .values()): + if value.genre != const.GENRE_USER: + continue + usercodes[value.index] = {'code': value.data, + 'label': value.label, + 'length': len(value.data)} + _LOGGER.info('Usercodes: %s', usercodes) + if usercodes: + return self.json(usercodes) + else: + return self.json_message('Node does not have usercodes', + HTTP_NOT_FOUND) + else: + return self.json_message('Node does not have usercodes', + HTTP_NOT_FOUND) From 9d6ffb15440e20ac4142be2cf7d1848b6a59ce3e Mon Sep 17 00:00:00 2001 From: turbokongen Date: Fri, 5 May 2017 22:43:28 +0200 Subject: [PATCH 08/18] disable missing import --- homeassistant/components/zwave/api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/zwave/api.py b/homeassistant/components/zwave/api.py index df3ae6414b1c2..b25f12d545c6c 100644 --- a/homeassistant/components/zwave/api.py +++ b/homeassistant/components/zwave/api.py @@ -20,6 +20,7 @@ class ZWaveNodeGroupView(HomeAssistantView): @ha.callback def get(self, request, node_id): """Retrieve groups of node.""" + # pylint: disable=import-error from openzwave.group import ZWaveGroup hass = request.app['hass'] From 68d347ae5863259f554828877be9297eea25c2e1 Mon Sep 17 00:00:00 2001 From: turbokongen Date: Sun, 7 May 2017 09:16:01 +0200 Subject: [PATCH 09/18] review changes --- homeassistant/components/zwave/api.py | 62 +++++++++++---------------- 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/homeassistant/components/zwave/api.py b/homeassistant/components/zwave/api.py index b25f12d545c6c..a6f8bc9faeb9f 100644 --- a/homeassistant/components/zwave/api.py +++ b/homeassistant/components/zwave/api.py @@ -14,7 +14,7 @@ class ZWaveNodeGroupView(HomeAssistantView): """View to return the nodes group configuration.""" - url = "/api/zwave/groups/{node_id}" + url = r"/api/zwave/groups/{node_id:\d+}" name = "api:zwave:groups" @ha.callback @@ -23,40 +23,38 @@ def get(self, request, node_id): # pylint: disable=import-error from openzwave.group import ZWaveGroup + nodeid = int(node_id) hass = request.app['hass'] network = hass.data.get(ZWAVE_NETWORK) - _LOGGER.info(network.nodes.get(int(node_id))) - node = network.nodes.get(int(node_id)) + _LOGGER.info(network.nodes.get(nodeid)) + node = network.nodes.get(nodeid) if node is None: return self.json_message('Node not found', HTTP_NOT_FOUND) groupdata = node.groups_to_dict() groups = {} - for key in groupdata.keys(): - groupnode = ZWaveGroup(key, network, int(node_id)) + for key in groupdata: + groupnode = ZWaveGroup(key, network, nodeid) groups[key] = {'associations': groupnode.associations, 'association_instances': groupnode.associations_instances, 'label': groupnode.label, 'max_associations': groupnode.max_associations} - _LOGGER.info('Groups: %s', groups) - if groups: - return self.json(groups) - else: - return self.json_message('Node not found', HTTP_NOT_FOUND) + return self.json(groups) class ZWaveNodeConfigView(HomeAssistantView): """View to return the nodes configuration options.""" - url = "/api/zwave/config/{node_id}" + url = r"/api/zwave/config/{node_id:\d+}" name = "api:zwave:config" @ha.callback def get(self, request, node_id): """Retrieve configurations of node.""" + nodeid = int(node_id) hass = request.app['hass'] network = hass.data.get(ZWAVE_NETWORK) - node = network.nodes.get(int(node_id)) + node = network.nodes.get(nodeid) if node is None: return self.json_message('Node not found', HTTP_NOT_FOUND) config = {} @@ -70,43 +68,33 @@ def get(self, request, node_id): 'data': value.data, 'max': value.max, 'min': value.min} - _LOGGER.info('Config: %s', config) - if config: - return self.json(config) - else: - return self.json_message('Node not found', HTTP_NOT_FOUND) + return self.json(config) class ZWaveUserCodeView(HomeAssistantView): """View to return the nodes usercode configuration.""" - url = "/api/zwave/usercodes/{node_id}" + url = r"/api/zwave/usercodes/{node_id:\d+}" name = "api:zwave:usercodes" @ha.callback def get(self, request, node_id): """Retrieve usercodes of node.""" + nodeid = int(node_id) hass = request.app['hass'] network = hass.data.get(ZWAVE_NETWORK) - node = network.nodes.get(int(node_id)) + node = network.nodes.get(nodeid) if node is None: return self.json_message('Node not found', HTTP_NOT_FOUND) usercodes = {} - if node.has_command_class(const.COMMAND_CLASS_USER_CODE): - for value in ( - node.get_values(class_id=const.COMMAND_CLASS_USER_CODE) - .values()): - if value.genre != const.GENRE_USER: - continue - usercodes[value.index] = {'code': value.data, - 'label': value.label, - 'length': len(value.data)} - _LOGGER.info('Usercodes: %s', usercodes) - if usercodes: - return self.json(usercodes) - else: - return self.json_message('Node does not have usercodes', - HTTP_NOT_FOUND) - else: - return self.json_message('Node does not have usercodes', - HTTP_NOT_FOUND) + if not node.has_command_class(const.COMMAND_CLASS_USER_CODE): + return self.json(usercodes, HTTP_NOT_FOUND) + for value in ( + node.get_values(class_id=const.COMMAND_CLASS_USER_CODE) + .values()): + if value.genre != const.GENRE_USER: + continue + usercodes[value.index] = {'code': value.data, + 'label': value.label, + 'length': len(value.data)} + return self.json(usercodes) From 21ddefaaddcdae55e92045f368e9ba61c7c5e7eb Mon Sep 17 00:00:00 2001 From: turbokongen Date: Mon, 8 May 2017 19:43:06 +0200 Subject: [PATCH 10/18] Tests 1 --- homeassistant/components/zwave/api.py | 1 - tests/components/zwave/test_api.py | 63 +++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 tests/components/zwave/test_api.py diff --git a/homeassistant/components/zwave/api.py b/homeassistant/components/zwave/api.py index a6f8bc9faeb9f..0049412e9d6c2 100644 --- a/homeassistant/components/zwave/api.py +++ b/homeassistant/components/zwave/api.py @@ -26,7 +26,6 @@ def get(self, request, node_id): nodeid = int(node_id) hass = request.app['hass'] network = hass.data.get(ZWAVE_NETWORK) - _LOGGER.info(network.nodes.get(nodeid)) node = network.nodes.get(nodeid) if node is None: return self.json_message('Node not found', HTTP_NOT_FOUND) diff --git a/tests/components/zwave/test_api.py b/tests/components/zwave/test_api.py new file mode 100644 index 0000000000000..50a9cabe22ea7 --- /dev/null +++ b/tests/components/zwave/test_api.py @@ -0,0 +1,63 @@ +"""Test Z-Wave config panel.""" +import asyncio +from unittest.mock import MagicMock +from homeassistant.components.zwave import ZWAVE_NETWORK +from homeassistant.components.zwave.api import ( + ZWaveNodeGroupView, ZWaveNodeConfigView, ZWaveUserCodeView) +from tests.common import mock_http_component_app + + +@asyncio.coroutine +def test_get_groups_nogroups_node(hass, test_client, mock_openzwave): + """Test getting groupdata on node without groups.""" + hass.data[ZWAVE_NETWORK] = MagicMock() + app = mock_http_component_app(hass) + ZWaveGroup = mock_openzwave.group.ZWaveGroup + group = MagicMock() + ZWaveGroup.return_value = group + ZWaveNodeGroupView().register(app.router) + + client = yield from test_client(app) + + resp = yield from client.get('/api/zwave/groups/2') + + assert resp.status == 200 + result = yield from resp.json() + + assert result == {} + + +@asyncio.coroutine +def test_get_config_noconfig_node(hass, test_client): + """Test getting config on node without config.""" + hass.data[ZWAVE_NETWORK] = MagicMock() + app = mock_http_component_app(hass) + + ZWaveNodeConfigView().register(app.router) + + client = yield from test_client(app) + + resp = yield from client.get('/api/zwave/config/2') + + assert resp.status == 200 + result = yield from resp.json() + + assert result == {} + + +@asyncio.coroutine +def test_get_usercodes_nousercode_node(hass, test_client): + """Test getting usercodes on node without usercodes.""" + hass.data[ZWAVE_NETWORK] = MagicMock() + app = mock_http_component_app(hass) + + ZWaveUserCodeView().register(app.router) + + client = yield from test_client(app) + + resp = yield from client.get('/api/zwave/usercodes/18') + + assert resp.status == 200 + result = yield from resp.json() + + assert result == {} From 82db12e105a54b969cb63f528e0475d98ca5a93e Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 9 May 2017 00:01:20 -0700 Subject: [PATCH 11/18] Verify that we fetch data from groups --- tests/components/zwave/test_api.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/tests/components/zwave/test_api.py b/tests/components/zwave/test_api.py index 50a9cabe22ea7..54dfcc6bbbed2 100644 --- a/tests/components/zwave/test_api.py +++ b/tests/components/zwave/test_api.py @@ -10,13 +10,18 @@ @asyncio.coroutine def test_get_groups_nogroups_node(hass, test_client, mock_openzwave): """Test getting groupdata on node without groups.""" - hass.data[ZWAVE_NETWORK] = MagicMock() app = mock_http_component_app(hass) - ZWaveGroup = mock_openzwave.group.ZWaveGroup - group = MagicMock() - ZWaveGroup.return_value = group ZWaveNodeGroupView().register(app.router) + network = hass.data[ZWAVE_NETWORK] = MagicMock() + network.nodes.get().groups_to_dict.return_value = {'1': None} + group = MagicMock() + group.associations = 'assoc' + group.associations_instances = 'inst' + group.label = 'the label' + group.max_associations = 'max' + mock_openzwave.group.ZWaveGroup.return_value = group + client = yield from test_client(app) resp = yield from client.get('/api/zwave/groups/2') @@ -24,7 +29,14 @@ def test_get_groups_nogroups_node(hass, test_client, mock_openzwave): assert resp.status == 200 result = yield from resp.json() - assert result == {} + assert result == { + '1': { + 'association_instances': 'inst', + 'associations': 'assoc', + 'label': 'the label', + 'max_associations': 'max' + } + } @asyncio.coroutine From 5fd17680c3f8e2c596ed360a1396435ebf7b16a6 Mon Sep 17 00:00:00 2001 From: turbokongen Date: Tue, 9 May 2017 14:49:37 +0200 Subject: [PATCH 12/18] Tests groups --- tests/components/zwave/test_api.py | 85 +++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/tests/components/zwave/test_api.py b/tests/components/zwave/test_api.py index 54dfcc6bbbed2..70acc61a4eee8 100644 --- a/tests/components/zwave/test_api.py +++ b/tests/components/zwave/test_api.py @@ -8,8 +8,8 @@ @asyncio.coroutine -def test_get_groups_nogroups_node(hass, test_client, mock_openzwave): - """Test getting groupdata on node without groups.""" +def test_get_groups(hass, test_client, mock_openzwave): + """Test getting groupdata on node.""" app = mock_http_component_app(hass) ZWaveNodeGroupView().register(app.router) @@ -38,6 +38,48 @@ def test_get_groups_nogroups_node(hass, test_client, mock_openzwave): } } +@asyncio.coroutine +def test_get_groups_nogroups(hass, test_client, mock_openzwave): + """Test getting groupdata on node without groups.""" + app = mock_http_component_app(hass) + ZWaveNodeGroupView().register(app.router) + + network = hass.data[ZWAVE_NETWORK] = MagicMock() + network.nodes.get().groups_to_dict.return_value = {} + group = MagicMock() + group.associations = None + group.associations_instances = None + group.label = None + group.max_associations = None + mock_openzwave.group.ZWaveGroup.return_value = group + + client = yield from test_client(app) + + resp = yield from client.get('/api/zwave/groups/2') + + assert resp.status == 200 + result = yield from resp.json() + + assert result == {} + +@asyncio.coroutine +def test_get_groups_nonode(hass, test_client, mock_openzwave): + """Test getting groupdata on nonexisting node.""" + app = mock_http_component_app(hass) + ZWaveNodeGroupView().register(app.router) + + network = hass.data[ZWAVE_NETWORK] = MagicMock() + network.nodes = {1: 1, 5: 5} + + client = yield from test_client(app) + + resp = yield from client.get('/api/zwave/groups/2') + + assert resp.status == 404 + result = yield from resp.json() + + assert result == {'message': 'Node not found'} + @asyncio.coroutine def test_get_config_noconfig_node(hass, test_client): @@ -57,6 +99,25 @@ def test_get_config_noconfig_node(hass, test_client): assert result == {} +@asyncio.coroutine +def test_get_config_nonode(hass, test_client, mock_openzwave): + """Test getting groupdata on nonexisting node.""" + app = mock_http_component_app(hass) + ZWaveNodeConfigView().register(app.router) + + network = hass.data[ZWAVE_NETWORK] = MagicMock() + network.nodes = {1: 1, 5: 5} + + client = yield from test_client(app) + + resp = yield from client.get('/api/zwave/config/2') + + assert resp.status == 404 + result = yield from resp.json() + + assert result == {'message': 'Node not found'} + + @asyncio.coroutine def test_get_usercodes_nousercode_node(hass, test_client): """Test getting usercodes on node without usercodes.""" @@ -73,3 +134,23 @@ def test_get_usercodes_nousercode_node(hass, test_client): result = yield from resp.json() assert result == {} + + +@asyncio.coroutine +def test_get_usercodes_nonode(hass, test_client, mock_openzwave): + """Test getting groupdata on nonexisting node.""" + app = mock_http_component_app(hass) + ZWaveUserCodeView().register(app.router) + + network = hass.data[ZWAVE_NETWORK] = MagicMock() + network.nodes = {1: 1, 5: 5} + + client = yield from test_client(app) + + resp = yield from client.get('/api/zwave/usercodes/2') + + assert resp.status == 404 + result = yield from resp.json() + + assert result == {'message': 'Node not found'} + From e1d682b3a9928eeca93cae4d5ea7034d67353340 Mon Sep 17 00:00:00 2001 From: turbokongen Date: Tue, 9 May 2017 16:54:12 +0200 Subject: [PATCH 13/18] config 1 --- tests/components/zwave/test_api.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/tests/components/zwave/test_api.py b/tests/components/zwave/test_api.py index 70acc61a4eee8..9cd684eaee71f 100644 --- a/tests/components/zwave/test_api.py +++ b/tests/components/zwave/test_api.py @@ -1,10 +1,11 @@ """Test Z-Wave config panel.""" import asyncio from unittest.mock import MagicMock -from homeassistant.components.zwave import ZWAVE_NETWORK +from homeassistant.components.zwave import ZWAVE_NETWORK, const from homeassistant.components.zwave.api import ( ZWaveNodeGroupView, ZWaveNodeConfigView, ZWaveUserCodeView) from tests.common import mock_http_component_app +from tests.mock.zwave import MockNode, MockValue @asyncio.coroutine @@ -38,6 +39,7 @@ def test_get_groups(hass, test_client, mock_openzwave): } } + @asyncio.coroutine def test_get_groups_nogroups(hass, test_client, mock_openzwave): """Test getting groupdata on node without groups.""" @@ -62,6 +64,7 @@ def test_get_groups_nogroups(hass, test_client, mock_openzwave): assert result == {} + @asyncio.coroutine def test_get_groups_nonode(hass, test_client, mock_openzwave): """Test getting groupdata on nonexisting node.""" @@ -84,11 +87,24 @@ def test_get_groups_nonode(hass, test_client, mock_openzwave): @asyncio.coroutine def test_get_config_noconfig_node(hass, test_client): """Test getting config on node without config.""" - hass.data[ZWAVE_NETWORK] = MagicMock() app = mock_http_component_app(hass) - ZWaveNodeConfigView().register(app.router) + network = hass.data[ZWAVE_NETWORK] = MagicMock() + node = MockNode(node_id=2) + value = MockValue( + index=12, + command_class=const.COMMAND_CLASS_CONFIGURATION) + value.label = 'label' + value.help = 'help' + value.type = 'type' + value.data = 'data' + value.data_items = ['item1', 'item2'] + value.max = 'max' + value.min = 'min' + network.nodes = node + node.get_values.return_value = node.value + client = yield from test_client(app) resp = yield from client.get('/api/zwave/config/2') @@ -96,11 +112,11 @@ def test_get_config_noconfig_node(hass, test_client): assert resp.status == 200 result = yield from resp.json() - assert result == {} + assert result == {'label': 'label'} @asyncio.coroutine -def test_get_config_nonode(hass, test_client, mock_openzwave): +def test_get_config_nonode(hass, test_client): """Test getting groupdata on nonexisting node.""" app = mock_http_component_app(hass) ZWaveNodeConfigView().register(app.router) @@ -137,7 +153,7 @@ def test_get_usercodes_nousercode_node(hass, test_client): @asyncio.coroutine -def test_get_usercodes_nonode(hass, test_client, mock_openzwave): +def test_get_usercodes_nonode(hass, test_client): """Test getting groupdata on nonexisting node.""" app = mock_http_component_app(hass) ZWaveUserCodeView().register(app.router) @@ -153,4 +169,3 @@ def test_get_usercodes_nonode(hass, test_client, mock_openzwave): result = yield from resp.json() assert result == {'message': 'Node not found'} - From 9ffcbfecf79ce600807211a5cdfad4d30efea7df Mon Sep 17 00:00:00 2001 From: turbokongen Date: Tue, 9 May 2017 18:59:48 +0200 Subject: [PATCH 14/18] usercode 1 --- tests/components/zwave/test_api.py | 92 +++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 14 deletions(-) diff --git a/tests/components/zwave/test_api.py b/tests/components/zwave/test_api.py index 9cd684eaee71f..b0994f4e59334 100644 --- a/tests/components/zwave/test_api.py +++ b/tests/components/zwave/test_api.py @@ -85,7 +85,7 @@ def test_get_groups_nonode(hass, test_client, mock_openzwave): @asyncio.coroutine -def test_get_config_noconfig_node(hass, test_client): +def test_get_config(hass, test_client): """Test getting config on node without config.""" app = mock_http_component_app(hass) ZWaveNodeConfigView().register(app.router) @@ -102,8 +102,9 @@ def test_get_config_noconfig_node(hass, test_client): value.data_items = ['item1', 'item2'] value.max = 'max' value.min = 'min' - network.nodes = node - node.get_values.return_value = node.value + node.values = {12: value} + network.nodes = {2: node} + node.get_values.return_value = node.values client = yield from test_client(app) @@ -112,7 +113,35 @@ def test_get_config_noconfig_node(hass, test_client): assert resp.status == 200 result = yield from resp.json() - assert result == {'label': 'label'} + assert result == {'12': {'data': 'data', + 'data_items': ['item1', 'item2'], + 'help': 'help', + 'label': 'label', + 'max': 'max', + 'min': 'min', + 'type': 'type'}} + + +@asyncio.coroutine +def test_get_config_noconfig_node(hass, test_client): + """Test getting config on node without config.""" + app = mock_http_component_app(hass) + ZWaveNodeConfigView().register(app.router) + + network = hass.data[ZWAVE_NETWORK] = MagicMock() + node = MockNode(node_id=2) + + network.nodes = {2: node} + node.get_values.return_value = node.values + + client = yield from test_client(app) + + resp = yield from client.get('/api/zwave/config/2') + + assert resp.status == 200 + result = yield from resp.json() + + assert result == {} @asyncio.coroutine @@ -135,13 +164,43 @@ def test_get_config_nonode(hass, test_client): @asyncio.coroutine -def test_get_usercodes_nousercode_node(hass, test_client): - """Test getting usercodes on node without usercodes.""" - hass.data[ZWAVE_NETWORK] = MagicMock() +def test_get_usercodes_nonode(hass, test_client): + """Test getting groupdata on nonexisting node.""" app = mock_http_component_app(hass) + ZWaveUserCodeView().register(app.router) + network = hass.data[ZWAVE_NETWORK] = MagicMock() + network.nodes = {1: 1, 5: 5} + + client = yield from test_client(app) + + resp = yield from client.get('/api/zwave/usercodes/2') + + assert resp.status == 404 + result = yield from resp.json() + + assert result == {'message': 'Node not found'} + + +@asyncio.coroutine +def test_get_usercodes(hass, test_client): + """Test getting config on node without config.""" + app = mock_http_component_app(hass) ZWaveUserCodeView().register(app.router) + network = hass.data[ZWAVE_NETWORK] = MagicMock() + node = MockNode(node_id=18, + command_classes=[const.COMMAND_CLASS_USER_CODE]) + value = MockValue( + index=0, + command_class=const.COMMAND_CLASS_USER_CODE) + value.genre = const.GENRE_USER + value.label = 'label' + value.data = '1234' + node.values = {0: value} + network.nodes = {18: node} + node.get_values.return_value = node.values + client = yield from test_client(app) resp = yield from client.get('/api/zwave/usercodes/18') @@ -149,23 +208,28 @@ def test_get_usercodes_nousercode_node(hass, test_client): assert resp.status == 200 result = yield from resp.json() - assert result == {} + assert result == {'0': {'code': '1234', + 'label': 'label', + 'length': 4}} @asyncio.coroutine -def test_get_usercodes_nonode(hass, test_client): - """Test getting groupdata on nonexisting node.""" +def test_get_usercode_nousercode_node(hass, test_client): + """Test getting usercodes on node without usercodes.""" app = mock_http_component_app(hass) ZWaveUserCodeView().register(app.router) network = hass.data[ZWAVE_NETWORK] = MagicMock() - network.nodes = {1: 1, 5: 5} + node = MockNode(node_id=18) + + network.nodes = {18: node} + node.get_values.return_value = node.values client = yield from test_client(app) - resp = yield from client.get('/api/zwave/usercodes/2') + resp = yield from client.get('/api/zwave/usercodes/18') - assert resp.status == 404 + assert resp.status == 200 result = yield from resp.json() - assert result == {'message': 'Node not found'} + assert result == {} From d4c4b02f0c1f77783e37a3b460c7a8226d98a35b Mon Sep 17 00:00:00 2001 From: turbokongen Date: Tue, 9 May 2017 19:08:55 +0200 Subject: [PATCH 15/18] Api mods --- homeassistant/components/zwave/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/zwave/api.py b/homeassistant/components/zwave/api.py index 0049412e9d6c2..c4d2281d03124 100644 --- a/homeassistant/components/zwave/api.py +++ b/homeassistant/components/zwave/api.py @@ -87,7 +87,7 @@ def get(self, request, node_id): return self.json_message('Node not found', HTTP_NOT_FOUND) usercodes = {} if not node.has_command_class(const.COMMAND_CLASS_USER_CODE): - return self.json(usercodes, HTTP_NOT_FOUND) + return self.json(usercodes) for value in ( node.get_values(class_id=const.COMMAND_CLASS_USER_CODE) .values()): From c553554f85a405e7062435461fc2bc38b2bccf37 Mon Sep 17 00:00:00 2001 From: turbokongen Date: Tue, 9 May 2017 19:50:50 +0200 Subject: [PATCH 16/18] Tweak API --- homeassistant/components/zwave/api.py | 16 +++++-------- tests/components/zwave/test_api.py | 33 ++++++++++++--------------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/homeassistant/components/zwave/api.py b/homeassistant/components/zwave/api.py index c4d2281d03124..9e3066f91c522 100644 --- a/homeassistant/components/zwave/api.py +++ b/homeassistant/components/zwave/api.py @@ -20,24 +20,20 @@ class ZWaveNodeGroupView(HomeAssistantView): @ha.callback def get(self, request, node_id): """Retrieve groups of node.""" - # pylint: disable=import-error - from openzwave.group import ZWaveGroup - nodeid = int(node_id) hass = request.app['hass'] network = hass.data.get(ZWAVE_NETWORK) node = network.nodes.get(nodeid) if node is None: return self.json_message('Node not found', HTTP_NOT_FOUND) - groupdata = node.groups_to_dict() + groupdata = node.groups groups = {} - for key in groupdata: - groupnode = ZWaveGroup(key, network, nodeid) - groups[key] = {'associations': groupnode.associations, + for key, value in groupdata.items(): + groups[key] = {'associations': value.associations, 'association_instances': - groupnode.associations_instances, - 'label': groupnode.label, - 'max_associations': groupnode.max_associations} + value.associations_instances, + 'label': value.label, + 'max_associations': value.max_associations} return self.json(groups) diff --git a/tests/components/zwave/test_api.py b/tests/components/zwave/test_api.py index b0994f4e59334..028eb22be7043 100644 --- a/tests/components/zwave/test_api.py +++ b/tests/components/zwave/test_api.py @@ -9,19 +9,19 @@ @asyncio.coroutine -def test_get_groups(hass, test_client, mock_openzwave): +def test_get_groups(hass, test_client): """Test getting groupdata on node.""" app = mock_http_component_app(hass) ZWaveNodeGroupView().register(app.router) network = hass.data[ZWAVE_NETWORK] = MagicMock() - network.nodes.get().groups_to_dict.return_value = {'1': None} - group = MagicMock() - group.associations = 'assoc' - group.associations_instances = 'inst' - group.label = 'the label' - group.max_associations = 'max' - mock_openzwave.group.ZWaveGroup.return_value = group + node = MockNode(node_id=2) + node.groups.associations = 'assoc' + node.groups.associations_instances = 'inst' + node.groups.label = 'the label' + node.groups.max_associations = 'max' + node.groups = {1: node.groups} + network.nodes = {2: node} client = yield from test_client(app) @@ -41,19 +41,15 @@ def test_get_groups(hass, test_client, mock_openzwave): @asyncio.coroutine -def test_get_groups_nogroups(hass, test_client, mock_openzwave): - """Test getting groupdata on node without groups.""" +def test_get_groups_nogroups(hass, test_client): + """Test getting groupdata on node.""" app = mock_http_component_app(hass) ZWaveNodeGroupView().register(app.router) network = hass.data[ZWAVE_NETWORK] = MagicMock() - network.nodes.get().groups_to_dict.return_value = {} - group = MagicMock() - group.associations = None - group.associations_instances = None - group.label = None - group.max_associations = None - mock_openzwave.group.ZWaveGroup.return_value = group + node = MockNode(node_id=2) + + network.nodes = {2: node} client = yield from test_client(app) @@ -65,8 +61,9 @@ def test_get_groups_nogroups(hass, test_client, mock_openzwave): assert result == {} + @asyncio.coroutine -def test_get_groups_nonode(hass, test_client, mock_openzwave): +def test_get_groups_nonode(hass, test_client): """Test getting groupdata on nonexisting node.""" app = mock_http_component_app(hass) ZWaveNodeGroupView().register(app.router) From 08ee17143080582a57a6b993089ae25d373f55a2 Mon Sep 17 00:00:00 2001 From: turbokongen Date: Tue, 9 May 2017 19:56:41 +0200 Subject: [PATCH 17/18] docstrings --- tests/components/zwave/test_api.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/components/zwave/test_api.py b/tests/components/zwave/test_api.py index 028eb22be7043..a3e5ac4c1f0e7 100644 --- a/tests/components/zwave/test_api.py +++ b/tests/components/zwave/test_api.py @@ -42,7 +42,7 @@ def test_get_groups(hass, test_client): @asyncio.coroutine def test_get_groups_nogroups(hass, test_client): - """Test getting groupdata on node.""" + """Test getting groupdata on node with no groups.""" app = mock_http_component_app(hass) ZWaveNodeGroupView().register(app.router) @@ -83,7 +83,7 @@ def test_get_groups_nonode(hass, test_client): @asyncio.coroutine def test_get_config(hass, test_client): - """Test getting config on node without config.""" + """Test getting config on node.""" app = mock_http_component_app(hass) ZWaveNodeConfigView().register(app.router) @@ -143,7 +143,7 @@ def test_get_config_noconfig_node(hass, test_client): @asyncio.coroutine def test_get_config_nonode(hass, test_client): - """Test getting groupdata on nonexisting node.""" + """Test getting config on nonexisting node.""" app = mock_http_component_app(hass) ZWaveNodeConfigView().register(app.router) @@ -162,7 +162,7 @@ def test_get_config_nonode(hass, test_client): @asyncio.coroutine def test_get_usercodes_nonode(hass, test_client): - """Test getting groupdata on nonexisting node.""" + """Test getting usercodes on nonexisting node.""" app = mock_http_component_app(hass) ZWaveUserCodeView().register(app.router) @@ -181,7 +181,7 @@ def test_get_usercodes_nonode(hass, test_client): @asyncio.coroutine def test_get_usercodes(hass, test_client): - """Test getting config on node without config.""" + """Test getting usercodes on node.""" app = mock_http_component_app(hass) ZWaveUserCodeView().register(app.router) From a008efe34fbfa29214692ff7b4f4407b4e913aa7 Mon Sep 17 00:00:00 2001 From: turbokongen Date: Tue, 9 May 2017 20:56:46 +0200 Subject: [PATCH 18/18] 100% api testing --- tests/components/zwave/test_api.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/tests/components/zwave/test_api.py b/tests/components/zwave/test_api.py index a3e5ac4c1f0e7..aabfd39024c70 100644 --- a/tests/components/zwave/test_api.py +++ b/tests/components/zwave/test_api.py @@ -61,7 +61,6 @@ def test_get_groups_nogroups(hass, test_client): assert result == {} - @asyncio.coroutine def test_get_groups_nonode(hass, test_client): """Test getting groupdata on nonexisting node.""" @@ -230,3 +229,32 @@ def test_get_usercode_nousercode_node(hass, test_client): result = yield from resp.json() assert result == {} + + +@asyncio.coroutine +def test_get_usercodes_no_genreuser(hass, test_client): + """Test getting usercodes on node missing genre user.""" + app = mock_http_component_app(hass) + ZWaveUserCodeView().register(app.router) + + network = hass.data[ZWAVE_NETWORK] = MagicMock() + node = MockNode(node_id=18, + command_classes=[const.COMMAND_CLASS_USER_CODE]) + value = MockValue( + index=0, + command_class=const.COMMAND_CLASS_USER_CODE) + value.genre = const.GENRE_SYSTEM + value.label = 'label' + value.data = '1234' + node.values = {0: value} + network.nodes = {18: node} + node.get_values.return_value = node.values + + client = yield from test_client(app) + + resp = yield from client.get('/api/zwave/usercodes/18') + + assert resp.status == 200 + result = yield from resp.json() + + assert result == {}