mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 17:27:10 +00:00
Add ability to set Zwave protection commandclass (#15390)
* Add API for protection commandclass * Adjusting * tests * Spelling * Missed flake8 * Period * spelling * Review changes * removing additional .keys() * period * Move i/o out into executor pool * Move i/o out into executor pool * Forgot get method * Do it right... I feel stupid * Long lines * Merging
This commit is contained in:
parent
3204501174
commit
1b94fe3613
@ -29,6 +29,7 @@ def async_setup(hass):
|
||||
hass.http.register_view(ZWaveUserCodeView)
|
||||
hass.http.register_view(ZWaveLogView)
|
||||
hass.http.register_view(ZWaveConfigWriteView)
|
||||
hass.http.register_view(ZWaveProtectionView)
|
||||
|
||||
return True
|
||||
|
||||
@ -196,3 +197,59 @@ class ZWaveUserCodeView(HomeAssistantView):
|
||||
'label': value.label,
|
||||
'length': len(value.data)}
|
||||
return self.json(usercodes)
|
||||
|
||||
|
||||
class ZWaveProtectionView(HomeAssistantView):
|
||||
"""View for the protection commandclass of a node."""
|
||||
|
||||
url = r"/api/zwave/protection/{node_id:\d+}"
|
||||
name = "api:zwave:protection"
|
||||
|
||||
async def get(self, request, node_id):
|
||||
"""Retrieve the protection commandclass options of node."""
|
||||
nodeid = int(node_id)
|
||||
hass = request.app['hass']
|
||||
network = hass.data.get(const.DATA_NETWORK)
|
||||
|
||||
def _fetch_protection():
|
||||
"""Helper to get protection data."""
|
||||
node = network.nodes.get(nodeid)
|
||||
if node is None:
|
||||
return self.json_message('Node not found', HTTP_NOT_FOUND)
|
||||
protection_options = {}
|
||||
if not node.has_command_class(const.COMMAND_CLASS_PROTECTION):
|
||||
return self.json(protection_options)
|
||||
protections = node.get_protections()
|
||||
protection_options = {
|
||||
'value_id': '{0:d}'.format(list(protections)[0]),
|
||||
'selected': node.get_protection_item(list(protections)[0]),
|
||||
'options': node.get_protection_items(list(protections)[0])}
|
||||
return self.json(protection_options)
|
||||
|
||||
return await hass.async_add_executor_job(_fetch_protection)
|
||||
|
||||
async def post(self, request, node_id):
|
||||
"""Change the selected option in protection commandclass."""
|
||||
nodeid = int(node_id)
|
||||
hass = request.app['hass']
|
||||
network = hass.data.get(const.DATA_NETWORK)
|
||||
protection_data = await request.json()
|
||||
|
||||
def _set_protection():
|
||||
"""Helper to get protection data."""
|
||||
node = network.nodes.get(nodeid)
|
||||
selection = protection_data["selection"]
|
||||
value_id = int(protection_data[const.ATTR_VALUE_ID])
|
||||
if node is None:
|
||||
return self.json_message('Node not found', HTTP_NOT_FOUND)
|
||||
if not node.has_command_class(const.COMMAND_CLASS_PROTECTION):
|
||||
return self.json_message(
|
||||
'No protection commandclass on this node', HTTP_NOT_FOUND)
|
||||
state = node.set_protection(value_id, selection)
|
||||
if not state:
|
||||
return self.json_message(
|
||||
'Protection setting did not complete', 202)
|
||||
return self.json_message(
|
||||
'Protection setting succsessfully set', HTTP_OK)
|
||||
|
||||
return await hass.async_add_executor_job(_set_protection)
|
||||
|
@ -367,3 +367,192 @@ def test_save_config(hass, client):
|
||||
result = yield from resp.json()
|
||||
assert network.write_config.called
|
||||
assert result == {'message': 'Z-Wave configuration saved to file.'}
|
||||
|
||||
|
||||
async def test_get_protection_values(hass, client):
|
||||
"""Test getting protection values on node."""
|
||||
network = hass.data[DATA_NETWORK] = MagicMock()
|
||||
node = MockNode(node_id=18,
|
||||
command_classes=[const.COMMAND_CLASS_PROTECTION])
|
||||
value = MockValue(
|
||||
value_id=123456,
|
||||
index=0,
|
||||
instance=1,
|
||||
command_class=const.COMMAND_CLASS_PROTECTION)
|
||||
value.label = 'Protection Test'
|
||||
value.data_items = ['Unprotected', 'Protection by Sequence',
|
||||
'No Operation Possible']
|
||||
value.data = 'Unprotected'
|
||||
network.nodes = {18: node}
|
||||
node.value = value
|
||||
|
||||
node.get_protection_item.return_value = "Unprotected"
|
||||
node.get_protection_items.return_value = value.data_items
|
||||
node.get_protections.return_value = {value.value_id: 'Object'}
|
||||
|
||||
resp = await client.get('/api/zwave/protection/18')
|
||||
|
||||
assert resp.status == 200
|
||||
result = await resp.json()
|
||||
assert node.get_protections.called
|
||||
assert node.get_protection_item.called
|
||||
assert node.get_protection_items.called
|
||||
assert result == {
|
||||
'value_id': '123456',
|
||||
'selected': 'Unprotected',
|
||||
'options': ['Unprotected', 'Protection by Sequence',
|
||||
'No Operation Possible']
|
||||
}
|
||||
|
||||
|
||||
async def test_get_protection_values_nonexisting_node(hass, client):
|
||||
"""Test getting protection values on node with wrong nodeid."""
|
||||
network = hass.data[DATA_NETWORK] = MagicMock()
|
||||
node = MockNode(node_id=18,
|
||||
command_classes=[const.COMMAND_CLASS_PROTECTION])
|
||||
value = MockValue(
|
||||
value_id=123456,
|
||||
index=0,
|
||||
instance=1,
|
||||
command_class=const.COMMAND_CLASS_PROTECTION)
|
||||
value.label = 'Protection Test'
|
||||
value.data_items = ['Unprotected', 'Protection by Sequence',
|
||||
'No Operation Possible']
|
||||
value.data = 'Unprotected'
|
||||
network.nodes = {17: node}
|
||||
node.value = value
|
||||
|
||||
resp = await client.get('/api/zwave/protection/18')
|
||||
|
||||
assert resp.status == 404
|
||||
result = await resp.json()
|
||||
assert not node.get_protections.called
|
||||
assert not node.get_protection_item.called
|
||||
assert not node.get_protection_items.called
|
||||
assert result == {'message': 'Node not found'}
|
||||
|
||||
|
||||
async def test_get_protection_values_without_protectionclass(hass, client):
|
||||
"""Test getting protection values on node without protectionclass."""
|
||||
network = hass.data[DATA_NETWORK] = MagicMock()
|
||||
node = MockNode(node_id=18)
|
||||
value = MockValue(
|
||||
value_id=123456,
|
||||
index=0,
|
||||
instance=1)
|
||||
network.nodes = {18: node}
|
||||
node.value = value
|
||||
|
||||
resp = await client.get('/api/zwave/protection/18')
|
||||
|
||||
assert resp.status == 200
|
||||
result = await resp.json()
|
||||
assert not node.get_protections.called
|
||||
assert not node.get_protection_item.called
|
||||
assert not node.get_protection_items.called
|
||||
assert result == {}
|
||||
|
||||
|
||||
async def test_set_protection_value(hass, client):
|
||||
"""Test setting protection value on node."""
|
||||
network = hass.data[DATA_NETWORK] = MagicMock()
|
||||
node = MockNode(node_id=18,
|
||||
command_classes=[const.COMMAND_CLASS_PROTECTION])
|
||||
value = MockValue(
|
||||
value_id=123456,
|
||||
index=0,
|
||||
instance=1,
|
||||
command_class=const.COMMAND_CLASS_PROTECTION)
|
||||
value.label = 'Protection Test'
|
||||
value.data_items = ['Unprotected', 'Protection by Sequence',
|
||||
'No Operation Possible']
|
||||
value.data = 'Unprotected'
|
||||
network.nodes = {18: node}
|
||||
node.value = value
|
||||
|
||||
resp = await client.post(
|
||||
'/api/zwave/protection/18', data=json.dumps({
|
||||
'value_id': '123456', 'selection': 'Protection by Sequence'}))
|
||||
|
||||
assert resp.status == 200
|
||||
result = await resp.json()
|
||||
assert node.set_protection.called
|
||||
assert result == {'message': 'Protection setting succsessfully set'}
|
||||
|
||||
|
||||
async def test_set_protection_value_failed(hass, client):
|
||||
"""Test setting protection value failed on node."""
|
||||
network = hass.data[DATA_NETWORK] = MagicMock()
|
||||
node = MockNode(node_id=18,
|
||||
command_classes=[const.COMMAND_CLASS_PROTECTION])
|
||||
value = MockValue(
|
||||
value_id=123456,
|
||||
index=0,
|
||||
instance=1,
|
||||
command_class=const.COMMAND_CLASS_PROTECTION)
|
||||
value.label = 'Protection Test'
|
||||
value.data_items = ['Unprotected', 'Protection by Sequence',
|
||||
'No Operation Possible']
|
||||
value.data = 'Unprotected'
|
||||
network.nodes = {18: node}
|
||||
node.value = value
|
||||
node.set_protection.return_value = False
|
||||
|
||||
resp = await client.post(
|
||||
'/api/zwave/protection/18', data=json.dumps({
|
||||
'value_id': '123456', 'selection': 'Protecton by Seuence'}))
|
||||
|
||||
assert resp.status == 202
|
||||
result = await resp.json()
|
||||
assert node.set_protection.called
|
||||
assert result == {'message': 'Protection setting did not complete'}
|
||||
|
||||
|
||||
async def test_set_protection_value_nonexisting_node(hass, client):
|
||||
"""Test setting protection value on nonexisting node."""
|
||||
network = hass.data[DATA_NETWORK] = MagicMock()
|
||||
node = MockNode(node_id=17,
|
||||
command_classes=[const.COMMAND_CLASS_PROTECTION])
|
||||
value = MockValue(
|
||||
value_id=123456,
|
||||
index=0,
|
||||
instance=1,
|
||||
command_class=const.COMMAND_CLASS_PROTECTION)
|
||||
value.label = 'Protection Test'
|
||||
value.data_items = ['Unprotected', 'Protection by Sequence',
|
||||
'No Operation Possible']
|
||||
value.data = 'Unprotected'
|
||||
network.nodes = {17: node}
|
||||
node.value = value
|
||||
node.set_protection.return_value = False
|
||||
|
||||
resp = await client.post(
|
||||
'/api/zwave/protection/18', data=json.dumps({
|
||||
'value_id': '123456', 'selection': 'Protecton by Seuence'}))
|
||||
|
||||
assert resp.status == 404
|
||||
result = await resp.json()
|
||||
assert not node.set_protection.called
|
||||
assert result == {'message': 'Node not found'}
|
||||
|
||||
|
||||
async def test_set_protection_value_missing_class(hass, client):
|
||||
"""Test setting protection value on node without protectionclass."""
|
||||
network = hass.data[DATA_NETWORK] = MagicMock()
|
||||
node = MockNode(node_id=17)
|
||||
value = MockValue(
|
||||
value_id=123456,
|
||||
index=0,
|
||||
instance=1)
|
||||
network.nodes = {17: node}
|
||||
node.value = value
|
||||
node.set_protection.return_value = False
|
||||
|
||||
resp = await client.post(
|
||||
'/api/zwave/protection/17', data=json.dumps({
|
||||
'value_id': '123456', 'selection': 'Protecton by Seuence'}))
|
||||
|
||||
assert resp.status == 404
|
||||
result = await resp.json()
|
||||
assert not node.set_protection.called
|
||||
assert result == {'message': 'No protection commandclass on this node'}
|
||||
|
Loading…
x
Reference in New Issue
Block a user