Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions homeassistant/components/zwave/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@
vol.Required(ATTR_ENTITY_ID): cv.entity_id,
})

RESET_NODE_METERS_SCHEMA = vol.Schema({
vol.Required(const.ATTR_NODE_ID): vol.Coerce(int),
vol.Optional(const.ATTR_INSTANCE, default=1): vol.Coerce(int)
})

CHANGE_ASSOCIATION_SCHEMA = vol.Schema({
vol.Required(const.ATTR_ASSOCIATION): cv.string,
vol.Required(const.ATTR_NODE_ID): vol.Coerce(int),
Expand Down Expand Up @@ -499,6 +504,26 @@ def refresh_node(service):
node = network.nodes[node_id]
node.refresh_info()

def reset_node_meters(service):
"""Reset meter counters of a node."""
node_id = service.data.get(const.ATTR_NODE_ID)
instance = service.data.get(const.ATTR_INSTANCE)
node = network.nodes[node_id]
for value in (
node.get_values(class_id=const.COMMAND_CLASS_METER)
.values()):
if value.index != const.METER_RESET_INDEX:
continue
if value.instance != instance:
continue
network.manager.pressButton(value.value_id)
network.manager.releaseButton(value.value_id)
_LOGGER.info("Resetting meters on node %s instance %s....",
node_id, instance)
return
_LOGGER.info("Node %s on instance %s does not have resettable "
"meters.", node_id, instance)

def start_zwave(_service_or_event):
"""Startup Z-Wave network."""
_LOGGER.info("Starting Z-Wave network...")
Expand Down Expand Up @@ -606,6 +631,11 @@ def start_zwave(_service_or_event):
descriptions[
const.SERVICE_REFRESH_NODE],
schema=NODE_SERVICE_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_RESET_NODE_METERS,
reset_node_meters,
descriptions[
const.SERVICE_RESET_NODE_METERS],
schema=RESET_NODE_METERS_SCHEMA)

# Setup autoheal
if autoheal:
Expand Down
3 changes: 3 additions & 0 deletions homeassistant/components/zwave/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
SERVICE_RENAME_NODE = "rename_node"
SERVICE_REFRESH_ENTITY = "refresh_entity"
SERVICE_REFRESH_NODE = "refresh_node"
SERVICE_RESET_NODE_METERS = "reset_node_meters"

EVENT_SCENE_ACTIVATED = "zwave.scene_activated"
EVENT_NODE_EVENT = "zwave.node_event"
Expand Down Expand Up @@ -329,3 +330,5 @@
DISC_TYPE = "type"
DISC_VALUES = "values"
DISC_WRITEONLY = "writeonly"

METER_RESET_INDEX = 33
8 changes: 8 additions & 0 deletions homeassistant/components/zwave/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,11 @@ rename_node:
name:
description: New Name
example: 'kitchen'

reset_node_meters:
description: Resets the meter counters of a node.
fields:
node_id:
description: Node id of the device to reset meters for. (integer)
instance:
description: (Optional) Instance of association. Defaults to instance 1.
46 changes: 43 additions & 3 deletions tests/components/zwave/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,17 +144,17 @@ def test_setup_platform(hass, mock_openzwave):
async_add_devices = MagicMock()

result = yield from zwave.async_setup_platform(
hass, None, async_add_devices, None)
hass, None, async_add_devices, None)
assert not result
assert not async_add_devices.called

result = yield from zwave.async_setup_platform(
hass, None, async_add_devices, {const.DISCOVERY_DEVICE: 123})
hass, None, async_add_devices, {const.DISCOVERY_DEVICE: 123})
assert not result
assert not async_add_devices.called

result = yield from zwave.async_setup_platform(
hass, None, async_add_devices, {const.DISCOVERY_DEVICE: 456})
hass, None, async_add_devices, {const.DISCOVERY_DEVICE: 456})
assert result
assert async_add_devices.called
assert len(async_add_devices.mock_calls) == 1
Expand Down Expand Up @@ -1015,6 +1015,46 @@ def test_set_wakeup(self):

assert value.data == 15

def test_reset_node_meters(self):
"""Test zwave reset_node_meters service."""
value = MockValue(
instance=1,
index=8,
data=99.5,
command_class=const.COMMAND_CLASS_METER,
)
reset_value = MockValue(
instance=1,
index=33,
command_class=const.COMMAND_CLASS_METER,
)
node = MockNode(node_id=14)
node.values = {8: value, 33: reset_value}
node.get_values.return_value = node.values
self.zwave_network.nodes = {14: node}

self.hass.services.call('zwave', 'reset_node_meters', {
const.ATTR_NODE_ID: 14,
const.ATTR_INSTANCE: 2,
})
self.hass.block_till_done()

assert not self.zwave_network.manager.pressButton.called
assert not self.zwave_network.manager.releaseButton.called

self.hass.services.call('zwave', 'reset_node_meters', {
const.ATTR_NODE_ID: 14,
})
self.hass.block_till_done()

assert self.zwave_network.manager.pressButton.called
value_id, = self.zwave_network.manager.pressButton.mock_calls.pop(0)[1]
assert value_id == reset_value.value_id
assert self.zwave_network.manager.releaseButton.called
value_id, = (
self.zwave_network.manager.releaseButton.mock_calls.pop(0)[1])
assert value_id == reset_value.value_id

def test_add_association(self):
"""Test zwave change_association service."""
ZWaveGroup = self.mock_openzwave.group.ZWaveGroup
Expand Down