Skip to content

Commit

Permalink
Add Raise/Lower/Stop support for covers (#52)
Browse files Browse the repository at this point in the history
* Add Raise/Lower/Stop support
  • Loading branch information
bdraco committed May 2, 2020
1 parent 2b9969c commit c6c560d
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 2 deletions.
1 change: 1 addition & 0 deletions pylintrc
Expand Up @@ -4,3 +4,4 @@ reports=no
disable=
too-many-arguments,
too-many-instance-attributes,
too-many-public-methods,
34 changes: 34 additions & 0 deletions pylutron_caseta/smartbridge.py
Expand Up @@ -200,6 +200,40 @@ def set_value(self, device_id, value):
"Parameter": [{"Type": "Level", "Value": value}]}}}
self._writer.write(cmd)

def _send_zone_create_request(self, device_id, command):
zone_id = self._get_zone_id(device_id)
if not zone_id:
return
self._writer.write({
"CommuniqueType": "CreateRequest",
"Header": {"Url": "/zone/%s/commandprocessor" % zone_id},
"Body": {
"Command": {
"CommandType": command
}
}
})

def stop_cover(self, device_id):
"""Will stop a cover."""
self._send_zone_create_request(device_id, "Stop")

def raise_cover(self, device_id):
"""Will raise a cover."""
self._send_zone_create_request(device_id, "Raise")
# If set_value is called, we get an optimistic callback right
# away with the value, if we use Raise we have to set it
# as one won't come unless Stop is called or something goes wrong.
self.devices[device_id]['current_state'] = 100

def lower_cover(self, device_id):
"""Will lower a cover."""
self._send_zone_create_request(device_id, "Lower")
# If set_value is called, we get an optimistic callback right
# away with the value, if we use Lower we have to set it
# as one won't come unless Stop is called or something goes wrong.
self.devices[device_id]['current_state'] = 0

def set_fan(self, device_id, value):
"""
Will set the value for a fan device with the given device ID.
Expand Down
15 changes: 15 additions & 0 deletions tests/responses/devices.json
Expand Up @@ -162,6 +162,21 @@
"href": "/devicerule/122"
}
]
},
{
"href": "/device/7",
"Name": "Living Shade 3",
"FullyQualifiedName": ["Living Room", "Living Shade 3"],
"Parent": {
"href": "/project"
},
"SerialNumber": 1234,
"ModelNumber": "QSYC-J-RCVR",
"DeviceType": "QsWirelessShade",
"LocalZones": [{"href": "/zone/6"}],
"AssociatedArea": {"href": "/area/4"},
"LinkNodes": [{"href": "/device/10/linknode/9"}],
"DeviceRules": [{"href": "/devicerule/10"}]
}
]
}
Expand Down
63 changes: 61 additions & 2 deletions tests/test_smartbridge.py
Expand Up @@ -119,14 +119,18 @@ async def _accept_connection(self, reader, writer, wait):
)
# Finally, we should check the zone status on each zone
requested_zones = []
for _ in range(0, 2):
for _ in range(0, 3):
value = await wait(writer.queue.get())
logging.info("Read %s", value)
assert value["CommuniqueType"] == "ReadRequest"
requested_zones.append(value["Header"]["Url"])
writer.queue.task_done()
requested_zones.sort()
assert requested_zones == ["/zone/1/status", "/zone/2/status"]
assert requested_zones == [
"/zone/1/status",
"/zone/2/status",
"/zone/6/status"
]

async def disconnect(self, exception=None):
"""Disconnect SmartBridge."""
Expand Down Expand Up @@ -320,6 +324,15 @@ async def test_device_list(bridge):
"current_state": -1,
"fan_speed": None,
"zone": None},
"7": {
"device_id": "7",
"name": "Living Room_Living Shade 3",
"type": "QsWirelessShade",
"model": "QSYC-J-RCVR",
"serial": 1234,
"current_state": -1,
"fan_speed": None,
"zone": "6"}
}

assert devices == expected_devices
Expand Down Expand Up @@ -591,6 +604,52 @@ async def test_set_fan(bridge):
"FanSpeedParameters": {"FanSpeed": "Medium"}}}}


@pytest.mark.asyncio
async def test_lower_cover(bridge):
"""Test that lowering a cover produces the right commands."""
devices = bridge.target.get_devices()
bridge.target.lower_cover('7')
command = await asyncio.wait_for(bridge.writer.queue.get(), 10)
bridge.writer.queue.task_done()
assert command == {
"CommuniqueType": "CreateRequest",
"Header": {"Url": "/zone/6/commandprocessor"},
"Body": {
"Command": {
"CommandType": "Lower"}}}
assert devices['7']['current_state'] == 0


@pytest.mark.asyncio
async def test_raise_cover(bridge):
"""Test that raising a cover produces the right commands."""
devices = bridge.target.get_devices()
bridge.target.raise_cover('7')
command = await asyncio.wait_for(bridge.writer.queue.get(), 10)
bridge.writer.queue.task_done()
assert command == {
"CommuniqueType": "CreateRequest",
"Header": {"Url": "/zone/6/commandprocessor"},
"Body": {
"Command": {
"CommandType": "Raise"}}}
assert devices['7']['current_state'] == 100


@pytest.mark.asyncio
async def test_stop_cover(bridge):
"""Test that stopping a cover produces the right commands."""
bridge.target.stop_cover('7')
command = await asyncio.wait_for(bridge.writer.queue.get(), 10)
bridge.writer.queue.task_done()
assert command == {
"CommuniqueType": "CreateRequest",
"Header": {"Url": "/zone/6/commandprocessor"},
"Body": {
"Command": {
"CommandType": "Stop"}}}


@pytest.mark.asyncio
async def test_activate_scene(bridge):
"""Test that activating scenes produces the right commands."""
Expand Down

0 comments on commit c6c560d

Please sign in to comment.