Consolidate config panels (#8857)

* Remove automation panel registration

* Move Z-Wave config API to config.zwave

* Remove no longer needed test

* Lint

* Update frontend
pull/8871/merge
Paulus Schoutsen 2017-08-06 12:05:34 -07:00 committed by GitHub
parent 4e79517971
commit 9575cbde09
23 changed files with 462 additions and 483 deletions

View File

@ -27,7 +27,6 @@ from homeassistant.helpers.restore_state import async_get_last_state
from homeassistant.loader import get_platform
from homeassistant.util.dt import utcnow
import homeassistant.helpers.config_validation as cv
from homeassistant.components.frontend import register_built_in_panel
DOMAIN = 'automation'
DEPENDENCIES = ['group']
@ -232,10 +231,6 @@ def async_setup(hass, config):
DOMAIN, service, turn_onoff_service_handler,
descriptions.get(service), schema=SERVICE_SCHEMA)
if 'frontend' in hass.config.components:
register_built_in_panel(hass, 'automation', 'Automations',
'mdi:playlist-play')
return True

View File

@ -1,12 +1,17 @@
"""Provide configuration end points for Z-Wave."""
import asyncio
import homeassistant.core as ha
from homeassistant.const import HTTP_NOT_FOUND
from homeassistant.components.http import HomeAssistantView
from homeassistant.components.config import EditKeyBasedConfigView
from homeassistant.components.zwave import DEVICE_CONFIG_SCHEMA_ENTRY
from homeassistant.components.zwave import const, DEVICE_CONFIG_SCHEMA_ENTRY
import homeassistant.helpers.config_validation as cv
CONFIG_PATH = 'zwave_device_config.yaml'
OZW_LOG_FILENAME = 'OZW_Log.txt'
URL_API_OZW_LOG = '/api/zwave/ozwlog'
@asyncio.coroutine
@ -16,4 +21,123 @@ def async_setup(hass):
'zwave', 'device_config', CONFIG_PATH, cv.entity_id,
DEVICE_CONFIG_SCHEMA_ENTRY
))
hass.http.register_view(ZWaveNodeValueView)
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
class ZWaveNodeValueView(HomeAssistantView):
"""View to return the node values."""
url = r"/api/zwave/values/{node_id:\d+}"
name = "api:zwave:values"
@ha.callback
def get(self, request, node_id):
"""Retrieve groups of node."""
nodeid = int(node_id)
hass = request.app['hass']
values_list = hass.data[const.DATA_ENTITY_VALUES]
values_data = {}
# Return a list of values for this node that are used as a
# primary value for an entity
for entity_values in values_list:
if entity_values.primary.node.node_id != nodeid:
continue
values_data[entity_values.primary.value_id] = {
'label': entity_values.primary.label,
'index': entity_values.primary.index,
'instance': entity_values.primary.instance,
}
return self.json(values_data)
class ZWaveNodeGroupView(HomeAssistantView):
"""View to return the nodes group configuration."""
url = r"/api/zwave/groups/{node_id:\d+}"
name = "api:zwave:groups"
@ha.callback
def get(self, request, node_id):
"""Retrieve groups of node."""
nodeid = int(node_id)
hass = request.app['hass']
network = hass.data.get(const.DATA_NETWORK)
node = network.nodes.get(nodeid)
if node is None:
return self.json_message('Node not found', HTTP_NOT_FOUND)
groupdata = node.groups
groups = {}
for key, value in groupdata.items():
groups[key] = {'associations': value.associations,
'association_instances':
value.associations_instances,
'label': value.label,
'max_associations': value.max_associations}
return self.json(groups)
class ZWaveNodeConfigView(HomeAssistantView):
"""View to return the nodes configuration options."""
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(const.DATA_NETWORK)
node = network.nodes.get(nodeid)
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}
return self.json(config)
class ZWaveUserCodeView(HomeAssistantView):
"""View to return the nodes usercode configuration."""
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(const.DATA_NETWORK)
node = network.nodes.get(nodeid)
if node is None:
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)
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)

View File

@ -3,23 +3,21 @@
FINGERPRINTS = {
"compatibility.js": "1686167ff210e001f063f5c606b2e74b",
"core.js": "2a7d01e45187c7d4635da05065b5e54e",
"frontend.html": "da3a65fd69361319864767a3ce0b4b9d",
"frontend.html": "3579bb550f8a407d452f70eb11c04b21",
"mdi.html": "e91f61a039ed0a9936e7ee5360da3870",
"micromarkdown-js.html": "93b5ec4016f0bba585521cf4d18dec1a",
"panels/ha-panel-automation.html": "6c3a3345b63f3a36d32f43cff3e10c53",
"panels/ha-panel-config.html": "3d7ef351e5154bbc909662a20ce812e2",
"panels/ha-panel-config.html": "a8f9761410139dca558c44db21465470",
"panels/ha-panel-dev-event.html": "d409e7ab537d9fe629126d122345279c",
"panels/ha-panel-dev-info.html": "b0e55eb657fd75f21aba2426ac0cedc0",
"panels/ha-panel-dev-mqtt.html": "94b222b013a98583842de3e72d5888c6",
"panels/ha-panel-dev-service.html": "61b164e0c0964782a539cba7008bb716",
"panels/ha-panel-dev-service.html": "94790b45e4b05e8722dba192940b16f6",
"panels/ha-panel-dev-state.html": "7948d3dba058f31517d880df8ed0e857",
"panels/ha-panel-dev-template.html": "f47b6910d8e4880e22cc508ca452f9b6",
"panels/ha-panel-hassio.html": "b46e7619f3c355f872d5370741d89f6a",
"panels/ha-panel-history.html": "788d6324badd9f189a3c8f593f76301e",
"panels/ha-panel-history.html": "fe2daac10a14f51fa3eb7d23978df1f7",
"panels/ha-panel-iframe.html": "56930204d6e067a3d600cf030f4b34c8",
"panels/ha-panel-kiosk.html": "b40aa5cb52dd7675bea744afcf9eebf8",
"panels/ha-panel-logbook.html": "771afdcf48dc7e308b0282417d2e02d8",
"panels/ha-panel-map.html": "c2544fff3eedb487d44105cf94b335ec",
"panels/ha-panel-shopping-list.html": "d8cfd0ecdb3aa6214c0f6908c34c7141",
"panels/ha-panel-zwave.html": "48a71bd864f1f047ff74322be6430f00"
"panels/ha-panel-shopping-list.html": "d8cfd0ecdb3aa6214c0f6908c34c7141"
}

File diff suppressed because one or more lines are too long

@ -1 +1 @@
Subproject commit 1ea7137c78b3df577f5df72a6c9bbe91bb5f7cd0
Subproject commit e81326cb6507d15ab94b4d69de87b909ef3e383e

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<html><head></head><body><dom-module id="ha-panel-history"><template><style include="iron-flex ha-style">.content{padding:0 16px 16px;}vaadin-date-picker{--vaadin-date-picker-clear-icon:{display:none;};margin-bottom:24px;margin-right:16px;max-width:200px;}paper-dropdown-menu{max-width:100px;}paper-item{cursor:pointer;}</style><ha-state-history-data hass="[[hass]]" filter-type="[[_filterType]]" start-time="[[_computeStartTime(_currentDate)]]" end-time="[[_computeEndTime(_currentDate, _periodIndex)]]" data="{{stateHistoryInput}}" is-loading="{{isLoadingData}}"></ha-state-history-data><app-header-layout has-scrolling-region=""><app-header slot="header" fixed=""><app-toolbar><ha-menu-button narrow="[[narrow]]" show-menu="[[showMenu]]"></ha-menu-button><div main-title="">History</div></app-toolbar></app-header><div class="flex content"><div class="flex layout horizontal wrap"><vaadin-date-picker id="picker" value="{{_currentDate}}" label="Showing entries for" disabled="[[isLoadingData]]"></vaadin-date-picker><paper-dropdown-menu label-float="" label="Period" disabled="[[isLoadingData]]"><paper-listbox slot="dropdown-content" selected="{{_periodIndex}}"><paper-item>1 day</paper-item><paper-item>3 days</paper-item><paper-item>1 week</paper-item></paper-listbox></paper-dropdown-menu></div><state-history-charts history-data="[[stateHistoryOutput]]" is-loading-data="[[isLoadingData]]"></state-history-charts></div></app-header-layout></template></dom-module><script>Polymer({is:"ha-panel-history",properties:{hass:{type:Object},narrow:{type:Boolean},showMenu:{type:Boolean,value:!1},stateHistoryInput:{type:Object,value:null,observer:"stateHistoryObserver"},stateHistoryOutput:{type:Object,value:null},_periodIndex:{type:Number,value:0},isLoadingData:{type:Boolean,value:!1},_currentDate:{type:String,value:function(){var t=new Date;return new Date(Date.UTC(t.getFullYear(),t.getMonth(),t.getDate())).toISOString().split("T")[0]}},_filterType:{type:String,value:"date"}},datepickerFocus:function(){this.datePicker.adjustPosition()},attached:function(){var t=new Date;this.$.picker.set("i18n.parseDate",function(){return t}),this.$.picker.set("i18n.formatDate",function(e){return t=e,window.hassUtil.formatDate(e)})},_computeStartTime:function(t){if(t){var e=t.split("-");return e[1]=parseInt(e[1])-1,new Date(e[0],e[1],e[2])}},_computeEndTime:function(t,e){var a=this._computeStartTime(t),r=new Date(a);return r.setDate(a.getDate()+this._computeFilterDays(e)),r},_computeFilterDays:function(t){switch(t){case 1:return 3;case 2:return 7;default:return 1}},stateHistoryObserver:function(t){this.async(function(){t===this.stateHistoryInput&&(this.stateHistoryOutput=t)}.bind(this),1)}});</script></body></html>
<html><head></head><body><dom-module id="ha-panel-history"><template><style include="iron-flex ha-style">.content{padding:0 16px 16px;}vaadin-date-picker{--vaadin-date-picker-clear-icon:{display:none;};margin-bottom:24px;margin-right:16px;max-width:200px;}paper-dropdown-menu{max-width:100px;}paper-item{cursor:pointer;}</style><ha-state-history-data hass="[[hass]]" filter-type="[[_filterType]]" start-time="[[_computeStartTime(_currentDate)]]" end-time="[[endTime]]" data="{{stateHistoryInput}}" is-loading="{{isLoadingData}}"></ha-state-history-data><app-header-layout has-scrolling-region=""><app-header slot="header" fixed=""><app-toolbar><ha-menu-button narrow="[[narrow]]" show-menu="[[showMenu]]"></ha-menu-button><div main-title="">History</div></app-toolbar></app-header><div class="flex content"><div class="flex layout horizontal wrap"><vaadin-date-picker id="picker" value="{{_currentDate}}" label="Showing entries for" disabled="[[isLoadingData]]"></vaadin-date-picker><paper-dropdown-menu label-float="" label="Period" disabled="[[isLoadingData]]"><paper-listbox slot="dropdown-content" selected="{{_periodIndex}}"><paper-item>1 day</paper-item><paper-item>3 days</paper-item><paper-item>1 week</paper-item></paper-listbox></paper-dropdown-menu></div><state-history-charts history-data="[[stateHistoryOutput]]" is-loading-data="[[isLoadingData]]" end-time="[[endTime]]"></state-history-charts></div></app-header-layout></template></dom-module><script>Polymer({is:"ha-panel-history",properties:{hass:{type:Object},narrow:{type:Boolean},showMenu:{type:Boolean,value:!1},stateHistoryInput:{type:Object,value:null,observer:"stateHistoryObserver"},stateHistoryOutput:{type:Object,value:null},_periodIndex:{type:Number,value:0},isLoadingData:{type:Boolean,value:!1},endTime:{type:Object,computed:"_computeEndTime(_currentDate, _periodIndex)"},_currentDate:{type:String,value:function(){var t=new Date;return new Date(Date.UTC(t.getFullYear(),t.getMonth(),t.getDate())).toISOString().split("T")[0]}},_filterType:{type:String,value:"date"}},datepickerFocus:function(){this.datePicker.adjustPosition()},attached:function(){var t=new Date;this.$.picker.set("i18n.parseDate",function(){return t}),this.$.picker.set("i18n.formatDate",function(e){return t=e,window.hassUtil.formatDate(e)})},_computeStartTime:function(t){if(t){var e=t.split("-");return e[1]=parseInt(e[1])-1,new Date(e[0],e[1],e[2])}},_computeEndTime:function(t,e){var n=this._computeStartTime(t),r=new Date(n);return r.setDate(n.getDate()+this._computeFilterDays(e)),r},_computeFilterDays:function(t){switch(t){case 1:return 3;case 2:return 7;default:return 1}},stateHistoryObserver:function(t){this.async(function(){t===this.stateHistoryInput&&(this.stateHistoryOutput=t)}.bind(this),1)}});</script></body></html>

File diff suppressed because one or more lines are too long

View File

@ -37,7 +37,7 @@
/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */
'use strict';
var precacheConfig = [["/","91486fe0099ad4d5d5a9b11cfdf70b7b"],["/frontend/panels/dev-event-d409e7ab537d9fe629126d122345279c.html","936814991f2a5e23d61d29f0d40f81b8"],["/frontend/panels/dev-info-b0e55eb657fd75f21aba2426ac0cedc0.html","1fa953b0224470f70d4e87bbe4dff191"],["/frontend/panels/dev-mqtt-94b222b013a98583842de3e72d5888c6.html","dc3ddfac58397feda97317358f0aecbb"],["/frontend/panels/dev-service-61b164e0c0964782a539cba7008bb716.html","86e4a07af018a9e020e3ab822c924a44"],["/frontend/panels/dev-state-7948d3dba058f31517d880df8ed0e857.html","ff8156bb1a52490fcc07466556fce0e1"],["/frontend/panels/dev-template-f47b6910d8e4880e22cc508ca452f9b6.html","9aa0675e01373c6bc2737438bb84a9ec"],["/frontend/panels/map-c2544fff3eedb487d44105cf94b335ec.html","113c5bf9a68a74c62e50cd354034e78b"],["/static/compatibility-1686167ff210e001f063f5c606b2e74b.js","6ee7b5e2dd82b510c3bd92f7e215988e"],["/static/core-2a7d01e45187c7d4635da05065b5e54e.js","90a0a8a6a6dd0ca41b16f40e7d23924d"],["/static/frontend-da3a65fd69361319864767a3ce0b4b9d.html","18b3bebc403a3b2a686c3d6f3482b1f6"],["/static/mdi-e91f61a039ed0a9936e7ee5360da3870.html","5e587bc82719b740a4f0798722a83aee"],["static/fonts/roboto/Roboto-Bold.ttf","d329cc8b34667f114a95422aaad1b063"],["static/fonts/roboto/Roboto-Light.ttf","7b5fb88f12bec8143f00e21bc3222124"],["static/fonts/roboto/Roboto-Medium.ttf","fe13e4170719c2fc586501e777bde143"],["static/fonts/roboto/Roboto-Regular.ttf","ac3f799d5bbaf5196fab15ab8de8431c"],["static/icons/favicon-192x192.png","419903b8422586a7e28021bbe9011175"],["static/icons/favicon.ico","04235bda7843ec2fceb1cbe2bc696cf4"],["static/images/card_media_player_bg.png","a34281d1c1835d338a642e90930e61aa"]];
var precacheConfig = [["/","eed923f1a5a5b99ebb16c3a529c8c579"],["/frontend/panels/dev-event-d409e7ab537d9fe629126d122345279c.html","936814991f2a5e23d61d29f0d40f81b8"],["/frontend/panels/dev-info-b0e55eb657fd75f21aba2426ac0cedc0.html","1fa953b0224470f70d4e87bbe4dff191"],["/frontend/panels/dev-mqtt-94b222b013a98583842de3e72d5888c6.html","dc3ddfac58397feda97317358f0aecbb"],["/frontend/panels/dev-service-94790b45e4b05e8722dba192940b16f6.html","f59d4cd23fd188420a37959086641493"],["/frontend/panels/dev-state-7948d3dba058f31517d880df8ed0e857.html","ff8156bb1a52490fcc07466556fce0e1"],["/frontend/panels/dev-template-f47b6910d8e4880e22cc508ca452f9b6.html","9aa0675e01373c6bc2737438bb84a9ec"],["/frontend/panels/map-c2544fff3eedb487d44105cf94b335ec.html","113c5bf9a68a74c62e50cd354034e78b"],["/static/compatibility-1686167ff210e001f063f5c606b2e74b.js","6ee7b5e2dd82b510c3bd92f7e215988e"],["/static/core-2a7d01e45187c7d4635da05065b5e54e.js","90a0a8a6a6dd0ca41b16f40e7d23924d"],["/static/frontend-3579bb550f8a407d452f70eb11c04b21.html","72fb9d8c000ba9585f1bfd556b8c9bcc"],["/static/mdi-e91f61a039ed0a9936e7ee5360da3870.html","5e587bc82719b740a4f0798722a83aee"],["static/fonts/roboto/Roboto-Bold.ttf","d329cc8b34667f114a95422aaad1b063"],["static/fonts/roboto/Roboto-Light.ttf","7b5fb88f12bec8143f00e21bc3222124"],["static/fonts/roboto/Roboto-Medium.ttf","fe13e4170719c2fc586501e777bde143"],["static/fonts/roboto/Roboto-Regular.ttf","ac3f799d5bbaf5196fab15ab8de8431c"],["static/icons/favicon-192x192.png","419903b8422586a7e28021bbe9011175"],["static/icons/favicon.ico","04235bda7843ec2fceb1cbe2bc696cf4"],["static/images/card_media_player_bg.png","a34281d1c1835d338a642e90930e61aa"]];
var cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');

View File

@ -27,9 +27,7 @@ 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, DATA_DEVICES, DATA_NETWORK, DATA_ENTITY_VALUES
from .node_entity import ZWaveBaseEntity, ZWaveNodeEntity
@ -69,9 +67,6 @@ DEFAULT_CONF_INVERT_OPENCLOSE_BUTTONS = False
DEFAULT_CONF_REFRESH_VALUE = False
DEFAULT_CONF_REFRESH_DELAY = 5
OZW_LOG_FILENAME = 'OZW_Log.txt'
URL_API_OZW_LOG = '/api/zwave/ozwlog'
RENAME_NODE_SCHEMA = vol.Schema({
vol.Required(const.ATTR_NODE_ID): vol.Coerce(int),
vol.Required(const.ATTR_NAME): cv.string,
@ -664,15 +659,6 @@ def setup(hass, config):
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave)
if 'frontend' in hass.config.components:
register_built_in_panel(hass, 'zwave', 'Z-Wave', 'mdi:nfc')
hass.http.register_view(api.ZWaveNodeValueView)
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

View File

@ -1,121 +0,0 @@
"""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__)
class ZWaveNodeValueView(HomeAssistantView):
"""View to return the node values."""
url = r"/api/zwave/values/{node_id:\d+}"
name = "api:zwave:values"
@ha.callback
def get(self, request, node_id):
"""Retrieve groups of node."""
nodeid = int(node_id)
hass = request.app['hass']
values_list = hass.data[const.DATA_ENTITY_VALUES]
values_data = {}
# Return a list of values for this node that are used as a
# primary value for an entity
for entity_values in values_list:
if entity_values.primary.node.node_id != nodeid:
continue
values_data[entity_values.primary.value_id] = {
'label': entity_values.primary.label,
'index': entity_values.primary.index,
'instance': entity_values.primary.instance,
}
return self.json(values_data)
class ZWaveNodeGroupView(HomeAssistantView):
"""View to return the nodes group configuration."""
url = r"/api/zwave/groups/{node_id:\d+}"
name = "api:zwave:groups"
@ha.callback
def get(self, request, node_id):
"""Retrieve groups of node."""
nodeid = int(node_id)
hass = request.app['hass']
network = hass.data.get(const.DATA_NETWORK)
node = network.nodes.get(nodeid)
if node is None:
return self.json_message('Node not found', HTTP_NOT_FOUND)
groupdata = node.groups
groups = {}
for key, value in groupdata.items():
groups[key] = {'associations': value.associations,
'association_instances':
value.associations_instances,
'label': value.label,
'max_associations': value.max_associations}
return self.json(groups)
class ZWaveNodeConfigView(HomeAssistantView):
"""View to return the nodes configuration options."""
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(const.DATA_NETWORK)
node = network.nodes.get(nodeid)
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}
return self.json(config)
class ZWaveUserCodeView(HomeAssistantView):
"""View to return the nodes usercode configuration."""
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(const.DATA_NETWORK)
node = network.nodes.get(nodeid)
if node is None:
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)
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)

View File

@ -1,11 +1,18 @@
"""Test Z-Wave config panel."""
import asyncio
import json
from unittest.mock import patch
from unittest.mock import MagicMock, patch
from homeassistant.bootstrap import async_setup_component
from homeassistant.components import config
from homeassistant.components.zwave import DATA_NETWORK, const
from homeassistant.components.config.zwave import (
ZWaveNodeValueView, ZWaveNodeGroupView, ZWaveNodeConfigView,
ZWaveUserCodeView)
from tests.common import mock_http_component_app
from tests.mock.zwave import MockNode, MockValue, MockEntityValues
VIEW_NAME = 'api:config:zwave:device_config'
@ -126,3 +133,286 @@ def test_update_device_config_invalid_json(hass, test_client):
'/api/config/zwave/device_config/hello.beer', data='not json')
assert resp.status == 400
@asyncio.coroutine
def test_get_values(hass, test_client):
"""Test getting values on node."""
app = mock_http_component_app(hass)
ZWaveNodeValueView().register(app.router)
node = MockNode(node_id=1)
value = MockValue(value_id=123456, node=node, label='Test Label',
instance=1, index=2)
values = MockEntityValues(primary=value)
node2 = MockNode(node_id=2)
value2 = MockValue(value_id=234567, node=node2, label='Test Label 2')
values2 = MockEntityValues(primary=value2)
hass.data[const.DATA_ENTITY_VALUES] = [values, values2]
client = yield from test_client(app)
resp = yield from client.get('/api/zwave/values/1')
assert resp.status == 200
result = yield from resp.json()
assert result == {
'123456': {
'label': 'Test Label',
'instance': 1,
'index': 2,
}
}
@asyncio.coroutine
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[DATA_NETWORK] = MagicMock()
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)
resp = yield from client.get('/api/zwave/groups/2')
assert resp.status == 200
result = yield from resp.json()
assert result == {
'1': {
'association_instances': 'inst',
'associations': 'assoc',
'label': 'the label',
'max_associations': 'max'
}
}
@asyncio.coroutine
def test_get_groups_nogroups(hass, test_client):
"""Test getting groupdata on node with no groups."""
app = mock_http_component_app(hass)
ZWaveNodeGroupView().register(app.router)
network = hass.data[DATA_NETWORK] = MagicMock()
node = MockNode(node_id=2)
network.nodes = {2: node}
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):
"""Test getting groupdata on nonexisting node."""
app = mock_http_component_app(hass)
ZWaveNodeGroupView().register(app.router)
network = hass.data[DATA_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(hass, test_client):
"""Test getting config on node."""
app = mock_http_component_app(hass)
ZWaveNodeConfigView().register(app.router)
network = hass.data[DATA_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'
node.values = {12: value}
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 == {'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[DATA_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
def test_get_config_nonode(hass, test_client):
"""Test getting config on nonexisting node."""
app = mock_http_component_app(hass)
ZWaveNodeConfigView().register(app.router)
network = hass.data[DATA_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_nonode(hass, test_client):
"""Test getting usercodes on nonexisting node."""
app = mock_http_component_app(hass)
ZWaveUserCodeView().register(app.router)
network = hass.data[DATA_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 usercodes on node."""
app = mock_http_component_app(hass)
ZWaveUserCodeView().register(app.router)
network = hass.data[DATA_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')
assert resp.status == 200
result = yield from resp.json()
assert result == {'0': {'code': '1234',
'label': 'label',
'length': 4}}
@asyncio.coroutine
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[DATA_NETWORK] = MagicMock()
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/18')
assert resp.status == 200
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[DATA_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 == {}

View File

@ -1,292 +0,0 @@
"""Test Z-Wave config panel."""
import asyncio
from unittest.mock import MagicMock
from homeassistant.components.zwave import DATA_NETWORK, const
from homeassistant.components.zwave.api import (
ZWaveNodeValueView, ZWaveNodeGroupView, ZWaveNodeConfigView,
ZWaveUserCodeView)
from tests.common import mock_http_component_app
from tests.mock.zwave import MockNode, MockValue, MockEntityValues
@asyncio.coroutine
def test_get_values(hass, test_client):
"""Test getting values on node."""
app = mock_http_component_app(hass)
ZWaveNodeValueView().register(app.router)
node = MockNode(node_id=1)
value = MockValue(value_id=123456, node=node, label='Test Label',
instance=1, index=2)
values = MockEntityValues(primary=value)
node2 = MockNode(node_id=2)
value2 = MockValue(value_id=234567, node=node2, label='Test Label 2')
values2 = MockEntityValues(primary=value2)
hass.data[const.DATA_ENTITY_VALUES] = [values, values2]
client = yield from test_client(app)
resp = yield from client.get('/api/zwave/values/1')
assert resp.status == 200
result = yield from resp.json()
assert result == {
'123456': {
'label': 'Test Label',
'instance': 1,
'index': 2,
}
}
@asyncio.coroutine
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[DATA_NETWORK] = MagicMock()
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)
resp = yield from client.get('/api/zwave/groups/2')
assert resp.status == 200
result = yield from resp.json()
assert result == {
'1': {
'association_instances': 'inst',
'associations': 'assoc',
'label': 'the label',
'max_associations': 'max'
}
}
@asyncio.coroutine
def test_get_groups_nogroups(hass, test_client):
"""Test getting groupdata on node with no groups."""
app = mock_http_component_app(hass)
ZWaveNodeGroupView().register(app.router)
network = hass.data[DATA_NETWORK] = MagicMock()
node = MockNode(node_id=2)
network.nodes = {2: node}
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):
"""Test getting groupdata on nonexisting node."""
app = mock_http_component_app(hass)
ZWaveNodeGroupView().register(app.router)
network = hass.data[DATA_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(hass, test_client):
"""Test getting config on node."""
app = mock_http_component_app(hass)
ZWaveNodeConfigView().register(app.router)
network = hass.data[DATA_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'
node.values = {12: value}
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 == {'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[DATA_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
def test_get_config_nonode(hass, test_client):
"""Test getting config on nonexisting node."""
app = mock_http_component_app(hass)
ZWaveNodeConfigView().register(app.router)
network = hass.data[DATA_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_nonode(hass, test_client):
"""Test getting usercodes on nonexisting node."""
app = mock_http_component_app(hass)
ZWaveUserCodeView().register(app.router)
network = hass.data[DATA_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 usercodes on node."""
app = mock_http_component_app(hass)
ZWaveUserCodeView().register(app.router)
network = hass.data[DATA_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')
assert resp.status == 200
result = yield from resp.json()
assert result == {'0': {'code': '1234',
'label': 'label',
'length': 4}}
@asyncio.coroutine
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[DATA_NETWORK] = MagicMock()
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/18')
assert resp.status == 200
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[DATA_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 == {}

View File

@ -16,7 +16,7 @@ import unittest
from unittest.mock import patch, MagicMock
from tests.common import (
get_test_home_assistant, async_fire_time_changed, mock_http_component)
get_test_home_assistant, async_fire_time_changed)
from tests.mock.zwave import MockNetwork, MockNode, MockValue, MockEntityValues
@ -120,21 +120,6 @@ def test_auto_heal_disabled(hass, mock_openzwave):
assert not network.heal.called
@asyncio.coroutine
def test_frontend_panel_register(hass, mock_openzwave):
"""Test network auto-heal disabled."""
mock_http_component(hass)
hass.config.components |= set(['frontend'])
with patch('homeassistant.components.zwave.'
'register_built_in_panel') as mock_register:
assert (yield from async_setup_component(hass, 'zwave', {
'zwave': {
'autoheal': False,
}}))
assert mock_register.called
assert len(mock_register.mock_calls) == 1
@asyncio.coroutine
def test_setup_platform(hass, mock_openzwave):
"""Test invalid device config."""