mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Fix COMMAND_CLASS_BARRIER_OPERATOR for dev branch of OpenZwave (#8574)
* Update zwave.py to work with updated OpenZwave library Update zwave.py to work with updated OpenZwave library * Update zwave.py * Update zwave.py * Update to fix garage door openers Update to fix garage door support for latest version of openzwavelib * Update to cover.zwave list of states Update to cover.zwave to provide list of states based on dev version of openzwave lib * Some values not saved * Formatting fix * Formatting fix * Variable typo * Formatting fix * Formatting * Variable Update Variable Update and properties added * Formatting fixes * Formatting Fix * Update test case for door states * Formatting / Testing process fix * Formatting * Formatting / Test Fixes * Variable rename * Added members to CoverDevice * Removed un-needed else * Formatting * Formatting * Variable name changes and const updates * Changed variable names to cover_state * Added constains into const.py * Updated to change the main state on the cover device * Fixes * Formatting fixes * Formatting/Variables * Formatting * Variable fixes * Import update * Formatting / Variables * Update test for new states * Revert state changes * Test fix * Variable Fix * Formatting * Variable typo * Missing constant * Variable fix * Requested changes * Added is_opening * Added is_closing * Updated test based on changes * Formatting * Changed cover_state back to _state * Formatting and variable fixes * Test fixes * Formatting and variable touchup * Formatting * Optimizations * Add new cover features to demo * Add tests for demo cover closing/opening * Remove unused STATE_STOPPED * Add tests for new zwave cover values
This commit is contained in:
parent
0ab0e35d59
commit
e8ce41874c
@ -23,7 +23,7 @@ from homeassistant.const import (
|
|||||||
SERVICE_OPEN_COVER, SERVICE_CLOSE_COVER, SERVICE_SET_COVER_POSITION,
|
SERVICE_OPEN_COVER, SERVICE_CLOSE_COVER, SERVICE_SET_COVER_POSITION,
|
||||||
SERVICE_STOP_COVER, SERVICE_OPEN_COVER_TILT, SERVICE_CLOSE_COVER_TILT,
|
SERVICE_STOP_COVER, SERVICE_OPEN_COVER_TILT, SERVICE_CLOSE_COVER_TILT,
|
||||||
SERVICE_STOP_COVER_TILT, SERVICE_SET_COVER_TILT_POSITION, STATE_OPEN,
|
SERVICE_STOP_COVER_TILT, SERVICE_SET_COVER_TILT_POSITION, STATE_OPEN,
|
||||||
STATE_CLOSED, STATE_UNKNOWN, ATTR_ENTITY_ID)
|
STATE_CLOSED, STATE_UNKNOWN, STATE_OPENING, STATE_CLOSING, ATTR_ENTITY_ID)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -225,6 +225,11 @@ class CoverDevice(Entity):
|
|||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self):
|
||||||
"""Return the state of the cover."""
|
"""Return the state of the cover."""
|
||||||
|
if self.is_opening:
|
||||||
|
return STATE_OPENING
|
||||||
|
if self.is_closing:
|
||||||
|
return STATE_CLOSING
|
||||||
|
|
||||||
closed = self.is_closed
|
closed = self.is_closed
|
||||||
|
|
||||||
if closed is None:
|
if closed is None:
|
||||||
@ -262,6 +267,16 @@ class CoverDevice(Entity):
|
|||||||
|
|
||||||
return supported_features
|
return supported_features
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_opening(self):
|
||||||
|
"""Return if the cover is opening or not."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_closing(self):
|
||||||
|
"""Return if the cover is closing or not."""
|
||||||
|
pass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_closed(self):
|
def is_closed(self):
|
||||||
"""Return if the cover is closed or not."""
|
"""Return if the cover is closed or not."""
|
||||||
|
@ -35,10 +35,12 @@ class DemoCover(CoverDevice):
|
|||||||
self._set_position = None
|
self._set_position = None
|
||||||
self._set_tilt_position = None
|
self._set_tilt_position = None
|
||||||
self._tilt_position = tilt_position
|
self._tilt_position = tilt_position
|
||||||
self._closing = True
|
self._requested_closing = True
|
||||||
self._closing_tilt = True
|
self._requested_closing_tilt = True
|
||||||
self._unsub_listener_cover = None
|
self._unsub_listener_cover = None
|
||||||
self._unsub_listener_cover_tilt = None
|
self._unsub_listener_cover_tilt = None
|
||||||
|
self._is_opening = False
|
||||||
|
self._is_closing = False
|
||||||
if position is None:
|
if position is None:
|
||||||
self._closed = True
|
self._closed = True
|
||||||
else:
|
else:
|
||||||
@ -69,6 +71,16 @@ class DemoCover(CoverDevice):
|
|||||||
"""Return if the cover is closed."""
|
"""Return if the cover is closed."""
|
||||||
return self._closed
|
return self._closed
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_closing(self):
|
||||||
|
"""Return if the cover is closing."""
|
||||||
|
return self._is_closing
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_opening(self):
|
||||||
|
"""Return if the cover is opening."""
|
||||||
|
return self._is_opening
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_class(self):
|
def device_class(self):
|
||||||
"""Return the class of this device, from component DEVICE_CLASSES."""
|
"""Return the class of this device, from component DEVICE_CLASSES."""
|
||||||
@ -90,8 +102,10 @@ class DemoCover(CoverDevice):
|
|||||||
self.schedule_update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
self._is_closing = True
|
||||||
self._listen_cover()
|
self._listen_cover()
|
||||||
self._closing = True
|
self._requested_closing = True
|
||||||
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def close_cover_tilt(self, **kwargs):
|
def close_cover_tilt(self, **kwargs):
|
||||||
"""Close the cover tilt."""
|
"""Close the cover tilt."""
|
||||||
@ -99,7 +113,7 @@ class DemoCover(CoverDevice):
|
|||||||
return
|
return
|
||||||
|
|
||||||
self._listen_cover_tilt()
|
self._listen_cover_tilt()
|
||||||
self._closing_tilt = True
|
self._requested_closing_tilt = True
|
||||||
|
|
||||||
def open_cover(self, **kwargs):
|
def open_cover(self, **kwargs):
|
||||||
"""Open the cover."""
|
"""Open the cover."""
|
||||||
@ -110,8 +124,10 @@ class DemoCover(CoverDevice):
|
|||||||
self.schedule_update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
self._is_opening = True
|
||||||
self._listen_cover()
|
self._listen_cover()
|
||||||
self._closing = False
|
self._requested_closing = False
|
||||||
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
def open_cover_tilt(self, **kwargs):
|
def open_cover_tilt(self, **kwargs):
|
||||||
"""Open the cover tilt."""
|
"""Open the cover tilt."""
|
||||||
@ -119,7 +135,7 @@ class DemoCover(CoverDevice):
|
|||||||
return
|
return
|
||||||
|
|
||||||
self._listen_cover_tilt()
|
self._listen_cover_tilt()
|
||||||
self._closing_tilt = False
|
self._requested_closing_tilt = False
|
||||||
|
|
||||||
def set_cover_position(self, position, **kwargs):
|
def set_cover_position(self, position, **kwargs):
|
||||||
"""Move the cover to a specific position."""
|
"""Move the cover to a specific position."""
|
||||||
@ -128,7 +144,7 @@ class DemoCover(CoverDevice):
|
|||||||
return
|
return
|
||||||
|
|
||||||
self._listen_cover()
|
self._listen_cover()
|
||||||
self._closing = position < self._position
|
self._requested_closing = position < self._position
|
||||||
|
|
||||||
def set_cover_tilt_position(self, tilt_position, **kwargs):
|
def set_cover_tilt_position(self, tilt_position, **kwargs):
|
||||||
"""Move the cover til to a specific position."""
|
"""Move the cover til to a specific position."""
|
||||||
@ -137,10 +153,12 @@ class DemoCover(CoverDevice):
|
|||||||
return
|
return
|
||||||
|
|
||||||
self._listen_cover_tilt()
|
self._listen_cover_tilt()
|
||||||
self._closing_tilt = tilt_position < self._tilt_position
|
self._requested_closing_tilt = tilt_position < self._tilt_position
|
||||||
|
|
||||||
def stop_cover(self, **kwargs):
|
def stop_cover(self, **kwargs):
|
||||||
"""Stop the cover."""
|
"""Stop the cover."""
|
||||||
|
self._is_closing = False
|
||||||
|
self._is_opening = False
|
||||||
if self._position is None:
|
if self._position is None:
|
||||||
return
|
return
|
||||||
if self._unsub_listener_cover is not None:
|
if self._unsub_listener_cover is not None:
|
||||||
@ -166,7 +184,7 @@ class DemoCover(CoverDevice):
|
|||||||
|
|
||||||
def _time_changed_cover(self, now):
|
def _time_changed_cover(self, now):
|
||||||
"""Track time changes."""
|
"""Track time changes."""
|
||||||
if self._closing:
|
if self._requested_closing:
|
||||||
self._position -= 10
|
self._position -= 10
|
||||||
else:
|
else:
|
||||||
self._position += 10
|
self._position += 10
|
||||||
@ -186,7 +204,7 @@ class DemoCover(CoverDevice):
|
|||||||
|
|
||||||
def _time_changed_cover_tilt(self, now):
|
def _time_changed_cover_tilt(self, now):
|
||||||
"""Track time changes."""
|
"""Track time changes."""
|
||||||
if self._closing_tilt:
|
if self._requested_closing_tilt:
|
||||||
self._tilt_position -= 10
|
self._tilt_position -= 10
|
||||||
else:
|
else:
|
||||||
self._tilt_position += 10
|
self._tilt_position += 10
|
||||||
|
@ -110,24 +110,36 @@ class ZwaveGarageDoor(zwave.ZWaveDeviceEntity, CoverDevice):
|
|||||||
def __init__(self, values):
|
def __init__(self, values):
|
||||||
"""Initialize the zwave garage door."""
|
"""Initialize the zwave garage door."""
|
||||||
ZWaveDeviceEntity.__init__(self, values, DOMAIN)
|
ZWaveDeviceEntity.__init__(self, values, DOMAIN)
|
||||||
|
self._state = None
|
||||||
self.update_properties()
|
self.update_properties()
|
||||||
|
|
||||||
def update_properties(self):
|
def update_properties(self):
|
||||||
"""Handle data changes for node values."""
|
"""Handle data changes for node values."""
|
||||||
self._state = self.values.primary.data
|
self._state = self.values.primary.data
|
||||||
|
_LOGGER.debug("self._state=%s", self._state)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_opening(self):
|
||||||
|
"""Return true if cover is in an opening state."""
|
||||||
|
return self._state == "Opening"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_closing(self):
|
||||||
|
"""Return true if cover is in an closing state."""
|
||||||
|
return self._state == "Closing"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_closed(self):
|
def is_closed(self):
|
||||||
"""Return the current position of Zwave garage door."""
|
"""Return the current position of Zwave garage door."""
|
||||||
return not self._state
|
return self._state == "Closed"
|
||||||
|
|
||||||
def close_cover(self):
|
def close_cover(self):
|
||||||
"""Close the garage door."""
|
"""Close the garage door."""
|
||||||
self.values.primary.data = False
|
self.values.primary.data = "Closed"
|
||||||
|
|
||||||
def open_cover(self):
|
def open_cover(self):
|
||||||
"""Open the garage door."""
|
"""Open the garage door."""
|
||||||
self.values.primary.data = True
|
self.values.primary.data = "Opened"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_class(self):
|
def device_class(self):
|
||||||
|
@ -188,7 +188,9 @@ STATE_HOME = 'home'
|
|||||||
STATE_NOT_HOME = 'not_home'
|
STATE_NOT_HOME = 'not_home'
|
||||||
STATE_UNKNOWN = 'unknown'
|
STATE_UNKNOWN = 'unknown'
|
||||||
STATE_OPEN = 'open'
|
STATE_OPEN = 'open'
|
||||||
|
STATE_OPENING = 'opening'
|
||||||
STATE_CLOSED = 'closed'
|
STATE_CLOSED = 'closed'
|
||||||
|
STATE_CLOSING = 'closing'
|
||||||
STATE_PLAYING = 'playing'
|
STATE_PLAYING = 'playing'
|
||||||
STATE_PAUSED = 'paused'
|
STATE_PAUSED = 'paused'
|
||||||
STATE_IDLE = 'idle'
|
STATE_IDLE = 'idle'
|
||||||
|
@ -38,29 +38,37 @@ class TestCoverDemo(unittest.TestCase):
|
|||||||
def test_close_cover(self):
|
def test_close_cover(self):
|
||||||
"""Test closing the cover."""
|
"""Test closing the cover."""
|
||||||
state = self.hass.states.get(ENTITY_COVER)
|
state = self.hass.states.get(ENTITY_COVER)
|
||||||
|
self.assertEqual(state.state, 'open')
|
||||||
self.assertEqual(70, state.attributes.get('current_position'))
|
self.assertEqual(70, state.attributes.get('current_position'))
|
||||||
cover.close_cover(self.hass, ENTITY_COVER)
|
cover.close_cover(self.hass, ENTITY_COVER)
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get(ENTITY_COVER)
|
||||||
|
self.assertEqual(state.state, 'closing')
|
||||||
for _ in range(7):
|
for _ in range(7):
|
||||||
future = dt_util.utcnow() + timedelta(seconds=1)
|
future = dt_util.utcnow() + timedelta(seconds=1)
|
||||||
fire_time_changed(self.hass, future)
|
fire_time_changed(self.hass, future)
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
|
|
||||||
state = self.hass.states.get(ENTITY_COVER)
|
state = self.hass.states.get(ENTITY_COVER)
|
||||||
|
self.assertEqual(state.state, 'closed')
|
||||||
self.assertEqual(0, state.attributes.get('current_position'))
|
self.assertEqual(0, state.attributes.get('current_position'))
|
||||||
|
|
||||||
def test_open_cover(self):
|
def test_open_cover(self):
|
||||||
"""Test opening the cover."""
|
"""Test opening the cover."""
|
||||||
state = self.hass.states.get(ENTITY_COVER)
|
state = self.hass.states.get(ENTITY_COVER)
|
||||||
|
self.assertEqual(state.state, 'open')
|
||||||
self.assertEqual(70, state.attributes.get('current_position'))
|
self.assertEqual(70, state.attributes.get('current_position'))
|
||||||
cover.open_cover(self.hass, ENTITY_COVER)
|
cover.open_cover(self.hass, ENTITY_COVER)
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
|
state = self.hass.states.get(ENTITY_COVER)
|
||||||
|
self.assertEqual(state.state, 'opening')
|
||||||
for _ in range(7):
|
for _ in range(7):
|
||||||
future = dt_util.utcnow() + timedelta(seconds=1)
|
future = dt_util.utcnow() + timedelta(seconds=1)
|
||||||
fire_time_changed(self.hass, future)
|
fire_time_changed(self.hass, future)
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
|
|
||||||
state = self.hass.states.get(ENTITY_COVER)
|
state = self.hass.states.get(ENTITY_COVER)
|
||||||
|
self.assertEqual(state.state, 'open')
|
||||||
self.assertEqual(100, state.attributes.get('current_position'))
|
self.assertEqual(100, state.attributes.get('current_position'))
|
||||||
|
|
||||||
def test_set_cover_position(self):
|
def test_set_cover_position(self):
|
||||||
|
@ -161,31 +161,46 @@ def test_roller_reverse_open_close(hass, mock_openzwave):
|
|||||||
def test_garage_value_changed(hass, mock_openzwave):
|
def test_garage_value_changed(hass, mock_openzwave):
|
||||||
"""Test position changed."""
|
"""Test position changed."""
|
||||||
node = MockNode()
|
node = MockNode()
|
||||||
value = MockValue(data=False, node=node,
|
value = MockValue(data="Closed", node=node,
|
||||||
command_class=const.COMMAND_CLASS_BARRIER_OPERATOR)
|
command_class=const.COMMAND_CLASS_BARRIER_OPERATOR)
|
||||||
values = MockEntityValues(primary=value, node=node)
|
values = MockEntityValues(primary=value, node=node)
|
||||||
device = zwave.get_device(hass=hass, node=node, values=values,
|
device = zwave.get_device(hass=hass, node=node, values=values,
|
||||||
node_config={})
|
node_config={})
|
||||||
|
|
||||||
assert device.is_closed
|
assert device.is_closed
|
||||||
|
assert not device.is_opening
|
||||||
|
assert not device.is_closing
|
||||||
|
|
||||||
value.data = True
|
value.data = "Opening"
|
||||||
value_changed(value)
|
value_changed(value)
|
||||||
|
|
||||||
assert not device.is_closed
|
assert not device.is_closed
|
||||||
|
assert device.is_opening
|
||||||
|
assert not device.is_closing
|
||||||
|
|
||||||
|
value.data = "Opened"
|
||||||
|
value_changed(value)
|
||||||
|
assert not device.is_closed
|
||||||
|
assert not device.is_opening
|
||||||
|
assert not device.is_closing
|
||||||
|
|
||||||
|
value.data = "Closing"
|
||||||
|
value_changed(value)
|
||||||
|
assert not device.is_closed
|
||||||
|
assert not device.is_opening
|
||||||
|
assert device.is_closing
|
||||||
|
|
||||||
|
|
||||||
def test_garage_commands(hass, mock_openzwave):
|
def test_garage_commands(hass, mock_openzwave):
|
||||||
"""Test position changed."""
|
"""Test position changed."""
|
||||||
node = MockNode()
|
node = MockNode()
|
||||||
value = MockValue(data=False, node=node,
|
value = MockValue(data="Closed", node=node,
|
||||||
command_class=const.COMMAND_CLASS_BARRIER_OPERATOR)
|
command_class=const.COMMAND_CLASS_BARRIER_OPERATOR)
|
||||||
values = MockEntityValues(primary=value, node=node)
|
values = MockEntityValues(primary=value, node=node)
|
||||||
device = zwave.get_device(hass=hass, node=node, values=values,
|
device = zwave.get_device(hass=hass, node=node, values=values,
|
||||||
node_config={})
|
node_config={})
|
||||||
|
|
||||||
assert value.data is False
|
assert value.data == "Closed"
|
||||||
device.open_cover()
|
device.open_cover()
|
||||||
assert value.data is True
|
assert value.data == "Opened"
|
||||||
device.close_cover()
|
device.close_cover()
|
||||||
assert value.data is False
|
assert value.data == "Closed"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user