Skip to content

Commit 68d0918

Browse files
authored
Release 0.6.8
- Update test dependencies - Add capabilities and well-known properties and methods for `airConditionerFanMode` and `airFlowDirection` and updated `airConditionerMode` to latest spec - Add scripts for generating capability and attribute constants from inventory. - Release under Apache Software License 2.0
2 parents 109fb9b + 7f65b29 commit 68d0918

File tree

11 files changed

+371
-28
lines changed

11 files changed

+371
-28
lines changed

.vscode/settings.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"python.pythonPath": ".venv\\Scripts\\python.exe",
3+
"[python]": {
4+
"editor.rulers": [79]
5+
}
6+
}

LICENSE

Lines changed: 207 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,207 @@
1-
MIT License
2-
3-
Copyright (c) 2018 Andrew Sayre
4-
5-
Permission is hereby granted, free of charge, to any person obtaining a copy
6-
of this software and associated documentation files (the "Software"), to deal
7-
in the Software without restriction, including without limitation the rights
8-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9-
copies of the Software, and to permit persons to whom the Software is
10-
furnished to do so, subject to the following conditions:
11-
12-
The above copyright notice and this permission notice shall be included in all
13-
copies or substantial portions of the Software.
14-
15-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21-
SOFTWARE.
1+
Apache License
2+
Version 2.0, January 2004
3+
http://www.apache.org/licenses/
4+
5+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6+
7+
1. Definitions.
8+
9+
"License" shall mean the terms and conditions for use, reproduction, and
10+
distribution as defined by Sections 1 through 9 of this document.
11+
12+
"Licensor" shall mean the copyright owner or entity authorized by the
13+
copyright owner that is granting the License.
14+
15+
"Legal Entity" shall mean the union of the acting entity and all other
16+
entities that control, are controlled by, or are under common control with
17+
that entity. For the purposes of this definition, "control" means (i) the
18+
power, direct or indirect, to cause the direction or management of such
19+
entity, whether by contract or otherwise, or (ii) ownership of
20+
fifty percent (50%) or more of the outstanding shares, or (iii) beneficial
21+
ownership of such entity.
22+
23+
"You" (or "Your") shall mean an individual or Legal Entity exercising
24+
permissions granted by this License.
25+
26+
"Source" form shall mean the preferred form for making modifications,
27+
including but not limited to software source code, documentation source,
28+
and configuration files.
29+
30+
"Object" form shall mean any form resulting from mechanical transformation
31+
or translation of a Source form, including but not limited to compiled
32+
object code, generated documentation, and conversions to
33+
other media types.
34+
35+
"Work" shall mean the work of authorship, whether in Source or Object
36+
form, made available under the License, as indicated by a copyright notice
37+
that is included in or attached to the work (an example is provided in the
38+
Appendix below).
39+
40+
"Derivative Works" shall mean any work, whether in Source or Object form,
41+
that is based on (or derived from) the Work and for which the editorial
42+
revisions, annotations, elaborations, or other modifications represent,
43+
as a whole, an original work of authorship. For the purposes of this
44+
License, Derivative Works shall not include works that remain separable
45+
from, or merely link (or bind by name) to the interfaces of, the Work and
46+
Derivative Works thereof.
47+
48+
"Contribution" shall mean any work of authorship, including the original
49+
version of the Work and any modifications or additions to that Work or
50+
Derivative Works thereof, that is intentionally submitted to Licensor for
51+
inclusion in the Work by the copyright owner or by an individual or
52+
Legal Entity authorized to submit on behalf of the copyright owner.
53+
For the purposes of this definition, "submitted" means any form of
54+
electronic, verbal, or written communication sent to the Licensor or its
55+
representatives, including but not limited to communication on electronic
56+
mailing lists, source code control systems, and issue tracking systems
57+
that are managed by, or on behalf of, the Licensor for the purpose of
58+
discussing and improving the Work, but excluding communication that is
59+
conspicuously marked or otherwise designated in writing by the copyright
60+
owner as "Not a Contribution."
61+
62+
"Contributor" shall mean Licensor and any individual or Legal Entity on
63+
behalf of whom a Contribution has been received by Licensor and
64+
subsequently incorporated within the Work.
65+
66+
2. Grant of Copyright License.
67+
68+
Subject to the terms and conditions of this License, each Contributor
69+
hereby grants to You a perpetual, worldwide, non-exclusive, no-charge,
70+
royalty-free, irrevocable copyright license to reproduce, prepare
71+
Derivative Works of, publicly display, publicly perform, sublicense,
72+
and distribute the Work and such Derivative Works in
73+
Source or Object form.
74+
75+
3. Grant of Patent License.
76+
77+
Subject to the terms and conditions of this License, each Contributor
78+
hereby grants to You a perpetual, worldwide, non-exclusive, no-charge,
79+
royalty-free, irrevocable (except as stated in this section) patent
80+
license to make, have made, use, offer to sell, sell, import, and
81+
otherwise transfer the Work, where such license applies only to those
82+
patent claims licensable by such Contributor that are necessarily
83+
infringed by their Contribution(s) alone or by combination of their
84+
Contribution(s) with the Work to which such Contribution(s) was submitted.
85+
If You institute patent litigation against any entity (including a
86+
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
87+
Contribution incorporated within the Work constitutes direct or
88+
contributory patent infringement, then any patent licenses granted to
89+
You under this License for that Work shall terminate as of the date such
90+
litigation is filed.
91+
92+
4. Redistribution.
93+
94+
You may reproduce and distribute copies of the Work or Derivative Works
95+
thereof in any medium, with or without modifications, and in Source or
96+
Object form, provided that You meet the following conditions:
97+
98+
1. You must give any other recipients of the Work or Derivative Works a
99+
copy of this License; and
100+
101+
2. You must cause any modified files to carry prominent notices stating
102+
that You changed the files; and
103+
104+
3. You must retain, in the Source form of any Derivative Works that You
105+
distribute, all copyright, patent, trademark, and attribution notices from
106+
the Source form of the Work, excluding those notices that do not pertain
107+
to any part of the Derivative Works; and
108+
109+
4. If the Work includes a "NOTICE" text file as part of its distribution,
110+
then any Derivative Works that You distribute must include a readable copy
111+
of the attribution notices contained within such NOTICE file, excluding
112+
those notices that do not pertain to any part of the Derivative Works,
113+
in at least one of the following places: within a NOTICE text file
114+
distributed as part of the Derivative Works; within the Source form or
115+
documentation, if provided along with the Derivative Works; or, within a
116+
display generated by the Derivative Works, if and wherever such
117+
third-party notices normally appear. The contents of the NOTICE file are
118+
for informational purposes only and do not modify the License.
119+
You may add Your own attribution notices within Derivative Works that You
120+
distribute, alongside or as an addendum to the NOTICE text from the Work,
121+
provided that such additional attribution notices cannot be construed
122+
as modifying the License.
123+
124+
You may add Your own copyright statement to Your modifications and may
125+
provide additional or different license terms and conditions for use,
126+
reproduction, or distribution of Your modifications, or for any such
127+
Derivative Works as a whole, provided Your use, reproduction, and
128+
distribution of the Work otherwise complies with the conditions
129+
stated in this License.
130+
131+
5. Submission of Contributions.
132+
133+
Unless You explicitly state otherwise, any Contribution intentionally
134+
submitted for inclusion in the Work by You to the Licensor shall be under
135+
the terms and conditions of this License, without any additional
136+
terms or conditions. Notwithstanding the above, nothing herein shall
137+
supersede or modify the terms of any separate license agreement you may
138+
have executed with Licensor regarding such Contributions.
139+
140+
6. Trademarks.
141+
142+
This License does not grant permission to use the trade names, trademarks,
143+
service marks, or product names of the Licensor, except as required for
144+
reasonable and customary use in describing the origin of the Work and
145+
reproducing the content of the NOTICE file.
146+
147+
7. Disclaimer of Warranty.
148+
149+
Unless required by applicable law or agreed to in writing, Licensor
150+
provides the Work (and each Contributor provides its Contributions)
151+
on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
152+
either express or implied, including, without limitation, any warranties
153+
or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS
154+
FOR A PARTICULAR PURPOSE. You are solely responsible for determining the
155+
appropriateness of using or redistributing the Work and assume any risks
156+
associated with Your exercise of permissions under this License.
157+
158+
8. Limitation of Liability.
159+
160+
In no event and under no legal theory, whether in tort
161+
(including negligence), contract, or otherwise, unless required by
162+
applicable law (such as deliberate and grossly negligent acts) or agreed
163+
to in writing, shall any Contributor be liable to You for damages,
164+
including any direct, indirect, special, incidental, or consequential
165+
damages of any character arising as a result of this License or out of
166+
the use or inability to use the Work (including but not limited to damages
167+
for loss of goodwill, work stoppage, computer failure or malfunction,
168+
or any and all other commercial damages or losses), even if such
169+
Contributor has been advised of the possibility of such damages.
170+
171+
9. Accepting Warranty or Additional Liability.
172+
173+
While redistributing the Work or Derivative Works thereof, You may choose
174+
to offer, and charge a fee for, acceptance of support, warranty,
175+
indemnity, or other liability obligations and/or rights consistent with
176+
this License. However, in accepting such obligations, You may act only
177+
on Your own behalf and on Your sole responsibility, not on behalf of any
178+
other Contributor, and only if You agree to indemnify, defend, and hold
179+
each Contributor harmless for any liability incurred by, or claims
180+
asserted against, such Contributor by reason of your accepting any such
181+
warranty or additional liability.
182+
183+
END OF TERMS AND CONDITIONS
184+
185+
APPENDIX: How to apply the Apache License to your work
186+
187+
To apply the Apache License to your work, attach the following boilerplate
188+
notice, with the fields enclosed by brackets "[]" replaced with your own
189+
identifying information. (Don't include the brackets!) The text should be
190+
enclosed in the appropriate comment syntax for the file format. We also
191+
recommend that a file or class name and description of purpose be included
192+
on the same "printed page" as the copyright notice for easier
193+
identification within third-party archives.
194+
195+
Copyright 2018 Andrew N. Sayre
196+
197+
Licensed under the Apache License, Version 2.0 (the "License");
198+
you may not use this file except in compliance with the License.
199+
You may obtain a copy of the License at
200+
201+
http://www.apache.org/licenses/LICENSE-2.0
202+
203+
Unless required by applicable law or agreed to in writing, software
204+
distributed under the License is distributed on an "AS IS" BASIS,
205+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
206+
or implied. See the License for the specific language governing
207+
permissions and limitations under the License.

pysmartthings/capability.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
CAPABILITIES_TO_ATTRIBUTES = {
88
'accelerationSensor': ['acceleration'],
99
'activityLightingMode': ['lightingMode'],
10-
'airConditionerMode': ['airConditionerMode'],
10+
'airConditionerFanMode': ['fanMode', 'supportedAcFanModes'],
11+
'airConditionerMode': ['airConditionerMode', 'supportedAcModes'],
12+
'airFlowDirection': ['airFlowDirection'],
1113
'airQualitySensor': ['airQuality'],
1214
'alarm': ['alarm'],
1315
'audioMute': ['mute'],
@@ -107,7 +109,9 @@ class Capability:
107109

108110
acceleration_sensor = 'accelerationSensor'
109111
activity_lighting_mode = 'activityLightingMode'
112+
air_conditioner_fan_mode = 'airConditionerFanMode'
110113
air_conditioner_mode = 'airConditionerMode'
114+
air_flow_direction = 'airFlowDirection'
111115
air_quality_sensor = 'airQualitySensor'
112116
alarm = 'alarm'
113117
audio_mute = 'audioMute'
@@ -191,6 +195,7 @@ class Attribute:
191195

192196
acceleration = 'acceleration'
193197
air_conditioner_mode = 'airConditionerMode'
198+
air_flow_direction = 'airFlowDirection'
194199
air_quality = 'airQuality'
195200
alarm = 'alarm'
196201
battery = 'battery'
@@ -219,6 +224,7 @@ class Attribute:
219224
energy = 'energy'
220225
equivalent_carbon_dioxide_measurement = \
221226
'equivalentCarbonDioxideMeasurement'
227+
fan_mode = 'fanMode'
222228
fan_speed = 'fanSpeed'
223229
filter_status = 'filterStatus'
224230
fine_dust_level = 'fineDustLevel'
@@ -274,6 +280,8 @@ class Attribute:
274280
smoke = 'smoke'
275281
sound = 'sound'
276282
st = 'st'
283+
supported_ac_fan_modes = 'supportedAcFanModes'
284+
supported_ac_modes = 'supportedAcModes'
277285
supported_button_values = 'supportedButtonValues'
278286
supported_input_sources = 'supportedInputSources'
279287
supported_machine_states = 'supportedMachineStates'

pysmartthings/device.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@ class Command:
4242
override_drlc_action = 'overrideDrlcAction'
4343
preset_position = 'presetPosition'
4444
request_drlc_action = 'requestDrlcAction'
45+
set_air_flow_direction = 'setAirFlowDirection'
4546
set_air_conditioner_mode = 'setAirConditionerMode'
4647
set_color = 'setColor'
4748
set_color_temperature = 'setColorTemperature'
4849
set_cooling_setpoint = 'setCoolingSetpoint'
50+
set_fan_mode = 'setFanMode'
4951
set_fan_speed = 'setFanSpeed'
5052
set_heating_setpoint = 'setHeatingSetpoint'
5153
set_hue = 'setHue'
@@ -539,6 +541,32 @@ def air_conditioner_mode(self) -> Optional[str]:
539541
"""Get the air conditioner mode attribute."""
540542
return self._attributes[Attribute.air_conditioner_mode].value
541543

544+
@property
545+
def supported_ac_modes(self) -> Sequence[str]:
546+
"""Get the supported AC modes attribute."""
547+
value = self._attributes[Attribute.supported_ac_modes].value
548+
if isinstance(value, Sequence):
549+
return sorted(value)
550+
return []
551+
552+
@property
553+
def fan_mode(self) -> Optional[str]:
554+
"""Get the fan mode attribute."""
555+
return self._attributes[Attribute.fan_mode].value
556+
557+
@property
558+
def supported_ac_fan_modes(self) -> Sequence[str]:
559+
"""Get the supported AC fan modes attribute."""
560+
value = self._attributes[Attribute.supported_ac_fan_modes].value
561+
if isinstance(value, Sequence):
562+
return sorted(value)
563+
return []
564+
565+
@property
566+
def air_flow_direction(self) -> str:
567+
"""Get the airFlowDirection attribute."""
568+
return self._attributes[Attribute.air_flow_direction].value
569+
542570
@property
543571
def three_axis(self) -> Optional[Tuple[int, int, int]]:
544572
"""Get the three axis attribute."""
@@ -933,6 +961,28 @@ async def set_air_conditioner_mode(
933961
Attribute.air_conditioner_mode, mode)
934962
return result
935963

964+
async def set_fan_mode(self, mode: str, *, set_status: bool = False,
965+
component_id: str = 'main'):
966+
"""Call the setFanMode command."""
967+
result = await self.command(
968+
component_id, Capability.air_conditioner_fan_mode,
969+
Command.set_fan_mode, [mode])
970+
if result and set_status:
971+
self.status.update_attribute_value(Attribute.fan_mode, mode)
972+
return result
973+
974+
async def set_air_flow_direction(
975+
self, direction: str, *, set_status: bool = False,
976+
component_id: str = 'main'):
977+
"""Call the setAirFlowDirection command."""
978+
result = await self.command(
979+
component_id, Capability.air_flow_direction,
980+
Command.set_air_flow_direction, [direction])
981+
if result and set_status:
982+
self.status.update_attribute_value(
983+
Attribute.air_flow_direction, direction)
984+
return result
985+
936986
@property
937987
def status(self):
938988
"""Get the status entity of the device."""

script/generate_attributes.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env python3
2+
"""Generate capabilitiy constants."""
3+
import re
4+
import sys
5+
6+
sys.path.append(".")
7+
from pysmartthings.capability import ATTRIBUTES
8+
9+
10+
def main():
11+
"""Run the script."""
12+
attribs = [a for a in ATTRIBUTES]
13+
attribs.sort()
14+
for a in attribs:
15+
print("{} = '{}'".format(re.sub(r'([A-Z])', r'_\1', a).lower(), a))
16+
17+
18+
if __name__ == '__main__':
19+
sys.exit(main())

script/generate_capabilities.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env python3
2+
"""Generate capabilitiy constants."""
3+
import re
4+
import sys
5+
6+
sys.path.append(".")
7+
from pysmartthings.capability import CAPABILITIES
8+
9+
10+
def main():
11+
"""Run the script."""
12+
capabilities = CAPABILITIES.copy()
13+
capabilities.sort()
14+
for c in capabilities:
15+
print("{} = '{}'".format(re.sub(r'([A-Z])', r'_\1', c).lower(), c))
16+
17+
18+
if __name__ == '__main__':
19+
sys.exit(main())

0 commit comments

Comments
 (0)