Skip to content

Commit 109fb9b

Browse files
authored
v0.6.7
- Add Three Axis capability and well-known device attribute. - Updates `apply_attribute_update` to accept `unit` and `data`
2 parents ac34b89 + 0946396 commit 109fb9b

File tree

4 files changed

+48
-14
lines changed

4 files changed

+48
-14
lines changed

pysmartthings/capability.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
'thermostatMode': ['thermostatMode', 'supportedThermostatModes'],
8585
'thermostatOperatingState': ['thermostatOperatingState'],
8686
'thermostatSetpoint': ['thermostatSetpoint'],
87+
'threeAxis': ['threeAxis'],
8788
'tvChannel': ['tvChannel'],
8889
'tvocMeasurement': ['tvocLevel'],
8990
'ultravioletIndex': ['ultravioletIndex'],
@@ -173,6 +174,7 @@ class Capability:
173174
thermostat_mode = 'thermostatMode'
174175
thermostat_operating_state = 'thermostatOperatingState'
175176
thermostat_setpoint = 'thermostatSetpoint'
177+
three_axis = 'threeAxis'
176178
tv_channel = 'tvChannel'
177179
tvoc_measurement = 'tvocMeasurement'
178180
ultraviolet_index = 'ultravioletIndex'
@@ -286,6 +288,7 @@ class Attribute:
286288
thermostat_operating_state = 'thermostatOperatingState'
287289
thermostat_setpoint = 'thermostatSetpoint'
288290
thermostat_setpoint_range = 'thermostatSetpointRange'
291+
three_axis = 'threeAxis'
289292
tv_channel = 'tvChannel'
290293
tvoc_level = 'tvocLevel'
291294
ultraviolet_index = 'ultravioletIndex'

pysmartthings/const.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
"""Define consts for the pysmartthings package."""
22

33
__title__ = "pysmartthings"
4-
__version__ = "0.6.6"
4+
__version__ = "0.6.7"

pysmartthings/device.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import colorsys
44
from enum import Enum
55
import re
6-
from typing import Any, Dict, Mapping, Optional, Sequence
6+
from typing import Any, Dict, Mapping, Optional, Sequence, Tuple
77

88
from .api import Api
99
from .capability import ATTRIBUTE_ON_VALUES, Attribute, Capability
@@ -184,7 +184,7 @@ def is_on(self, attribute: str) -> bool:
184184
ATTRIBUTE_ON_VALUES[attribute]
185185

186186
def update_attribute_value(self, attribute: str, value):
187-
"""Update the value of an attribute while mantaining unit and data."""
187+
"""Update the value of an attribute while maintaining unit and data."""
188188
status = self._attributes[attribute]
189189
self._attributes[attribute] = Status(value, status.unit, status.data)
190190

@@ -539,6 +539,11 @@ def air_conditioner_mode(self) -> Optional[str]:
539539
"""Get the air conditioner mode attribute."""
540540
return self._attributes[Attribute.air_conditioner_mode].value
541541

542+
@property
543+
def three_axis(self) -> Optional[Tuple[int, int, int]]:
544+
"""Get the three axis attribute."""
545+
return self._attributes[Attribute.three_axis].value
546+
542547

543548
class DeviceStatus(DeviceStatusBase):
544549
"""Define the device status."""
@@ -553,14 +558,18 @@ def __init__(self, api: Api, device_id: str, data=None):
553558
self.apply_data(data)
554559

555560
def apply_attribute_update(self, component_id: str, capability: str,
556-
attribute: str, value: Any):
561+
attribute: str, value: Any,
562+
unit: Optional[str] = None,
563+
data: Optional[Dict] = None):
557564
"""Apply an update to a specific attribute."""
558-
# capability future usage.
559-
if component_id == 'main':
560-
self.update_attribute_value(attribute, value)
561-
elif component_id in self._components.keys():
562-
self._components[component_id].update_attribute_value(
563-
attribute, value)
565+
component = self
566+
if component_id != 'main' and component_id in self._components:
567+
component = self._components[component_id]
568+
569+
# preserve unit until fixed in the API
570+
old_status = component.attributes[attribute]
571+
component.attributes[attribute] = Status(
572+
value, unit or old_status.unit, data)
564573

565574
def apply_data(self, data: dict):
566575
"""Apply the values from the given data structure."""

tests/test_device.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
import pytest
44

55
from pysmartthings.capability import Attribute, Capability
6-
from pysmartthings.device import Device, DeviceEntity, DeviceStatus, DeviceType
6+
from pysmartthings.device import (
7+
Device, DeviceEntity, DeviceStatus, DeviceType, Status)
78

89
from .conftest import DEVICE_ID, LOCATION_ID, ROOM_ID
910
from .utilities import get_json
@@ -807,11 +808,30 @@ def test_apply_attribute_update():
807808
"""Tests the apply_attribute_update method."""
808809
# Arrange
809810
data = get_json('device_status.json')
810-
status = DeviceStatus(None, DEVICE_ID, data)
811+
device = DeviceStatus(None, DEVICE_ID, data)
811812
# Act
812-
status.apply_attribute_update('main', 'switchLevel', 'level', 50)
813+
device.apply_attribute_update(
814+
'main', Capability.switch_level, Attribute.level, 50, '%',
815+
{'test': 'test'})
813816
# Assert
814-
assert status.level == 50
817+
status = device.attributes[Attribute.level]
818+
assert status.value == 50
819+
assert status.unit == '%'
820+
assert status.data == {'test': 'test'}
821+
822+
@staticmethod
823+
def test_apply_attribute_update_preserve_unit():
824+
"""Tests the apply_attribute_update preserves the old unit."""
825+
# Arrange
826+
data = get_json('device_status.json')
827+
device = DeviceStatus(None, DEVICE_ID, data)
828+
device.attributes[Capability.switch_level] = Status(40, '%', None)
829+
# Act
830+
device.apply_attribute_update(
831+
'main', Capability.switch_level, Attribute.level, 50)
832+
# Assert
833+
status = device.attributes[Attribute.level]
834+
assert status.unit == '%'
815835

816836
@staticmethod
817837
def test_apply_attribute_update_child_status():
@@ -1007,6 +1027,7 @@ def test_well_known_attributes():
10071027
status.update_attribute_value(Attribute.door, 'open')
10081028
status.update_attribute_value(Attribute.window_shade, 'closed')
10091029
status.update_attribute_value(Attribute.data, {'test': 'test'})
1030+
status.update_attribute_value(Attribute.three_axis, [0, 0, 0])
10101031
# Act/Assert
10111032
assert status.humidity == 50
10121033
assert status.temperature == 55
@@ -1017,6 +1038,7 @@ def test_well_known_attributes():
10171038
assert status.door == 'open'
10181039
assert status.window_shade == 'closed'
10191040
assert status.data == {'test': 'test'}
1041+
assert status.three_axis == [0, 0, 0]
10201042

10211043
@staticmethod
10221044
def test_well_known_ocf_attributes():

0 commit comments

Comments
 (0)