pywemo 1.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pywemo/README.md +69 -0
- pywemo/__init__.py +33 -0
- pywemo/color.py +79 -0
- pywemo/discovery.py +194 -0
- pywemo/exceptions.py +94 -0
- pywemo/ouimeaux_device/LICENSE +12 -0
- pywemo/ouimeaux_device/__init__.py +679 -0
- pywemo/ouimeaux_device/api/__init__.py +1 -0
- pywemo/ouimeaux_device/api/attributes.py +131 -0
- pywemo/ouimeaux_device/api/db_orm.py +197 -0
- pywemo/ouimeaux_device/api/long_press.py +168 -0
- pywemo/ouimeaux_device/api/rules_db.py +467 -0
- pywemo/ouimeaux_device/api/service.py +363 -0
- pywemo/ouimeaux_device/api/wemo_services.py +25 -0
- pywemo/ouimeaux_device/api/wemo_services.pyi +241 -0
- pywemo/ouimeaux_device/api/xsd/__init__.py +1 -0
- pywemo/ouimeaux_device/api/xsd/device.py +3888 -0
- pywemo/ouimeaux_device/api/xsd/device.xsd +95 -0
- pywemo/ouimeaux_device/api/xsd/service.py +3872 -0
- pywemo/ouimeaux_device/api/xsd/service.xsd +93 -0
- pywemo/ouimeaux_device/api/xsd_types.py +222 -0
- pywemo/ouimeaux_device/bridge.py +506 -0
- pywemo/ouimeaux_device/coffeemaker.py +92 -0
- pywemo/ouimeaux_device/crockpot.py +157 -0
- pywemo/ouimeaux_device/dimmer.py +70 -0
- pywemo/ouimeaux_device/humidifier.py +223 -0
- pywemo/ouimeaux_device/insight.py +191 -0
- pywemo/ouimeaux_device/lightswitch.py +11 -0
- pywemo/ouimeaux_device/maker.py +54 -0
- pywemo/ouimeaux_device/motion.py +6 -0
- pywemo/ouimeaux_device/outdoor_plug.py +6 -0
- pywemo/ouimeaux_device/switch.py +32 -0
- pywemo/py.typed +0 -0
- pywemo/ssdp.py +372 -0
- pywemo/subscribe.py +782 -0
- pywemo/util.py +139 -0
- pywemo-1.4.0.dist-info/LICENSE +54 -0
- pywemo-1.4.0.dist-info/METADATA +192 -0
- pywemo-1.4.0.dist-info/RECORD +40 -0
- pywemo-1.4.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
"""Representation of Services and Actions for WeMo devices."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import logging
|
|
5
|
+
from collections import defaultdict
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Iterable
|
|
8
|
+
from urllib.parse import urljoin, urlparse
|
|
9
|
+
|
|
10
|
+
import urllib3
|
|
11
|
+
from lxml import etree as et
|
|
12
|
+
|
|
13
|
+
from pywemo.exceptions import (
|
|
14
|
+
ActionException,
|
|
15
|
+
HTTPException,
|
|
16
|
+
HTTPNotOkException,
|
|
17
|
+
InvalidSchemaError,
|
|
18
|
+
MissingServiceError,
|
|
19
|
+
SOAPFault,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
from .wemo_services import WeMoAllActionsMixin
|
|
23
|
+
from .xsd_types import ActionProperties, ServiceDescription, ServiceProperties
|
|
24
|
+
|
|
25
|
+
if TYPE_CHECKING:
|
|
26
|
+
from .. import Device
|
|
27
|
+
|
|
28
|
+
LOG = logging.getLogger(__name__)
|
|
29
|
+
REQUESTS_TIMEOUT = 10
|
|
30
|
+
|
|
31
|
+
REQUEST_TEMPLATE = """
|
|
32
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
33
|
+
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
|
34
|
+
<s:Body>
|
|
35
|
+
<u:{action} xmlns:u="{service}">
|
|
36
|
+
{args}
|
|
37
|
+
</u:{action}>
|
|
38
|
+
</s:Body>
|
|
39
|
+
</s:Envelope>
|
|
40
|
+
""" # noqa: E501
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class Session:
|
|
44
|
+
"""HTTP session with device.
|
|
45
|
+
|
|
46
|
+
The Session provides timeouts and retries by default. The default
|
|
47
|
+
parameters were chosen to provide for 3 attempts within 10 seconds, and
|
|
48
|
+
further attempts beyond that to reestablish a link with the device without
|
|
49
|
+
needing to attempt rediscovery. Retries continue for the duration that it
|
|
50
|
+
would take the device to reboot, at which point reconnect_with_device
|
|
51
|
+
should be able to find the device again by probing.
|
|
52
|
+
|
|
53
|
+
It is important to not be too agressive with retries. The WeMo devices only
|
|
54
|
+
have a small number of threads for servicing requests. If the timeout is
|
|
55
|
+
too short or the retries are too frequent, it is easy to overwhelm the
|
|
56
|
+
device with too many requests. This can result in a device that crashes
|
|
57
|
+
and is unavailable until it reboots.
|
|
58
|
+
|
|
59
|
+
The `urllib3` library is used as it provides better timeout/retry support
|
|
60
|
+
than the `requests` library. Specifically, the `urllib3` library will
|
|
61
|
+
retry in the case where the response body is not returned within timeout
|
|
62
|
+
seconds. The `requests` library does not support retries of fetching the
|
|
63
|
+
response body and will raise an exception if fetching the response body
|
|
64
|
+
takes longer than the timeout.
|
|
65
|
+
|
|
66
|
+
Since much of pywemo is built atop the requests library, a `content`
|
|
67
|
+
field on HTTPResponse is populated from the `data` field.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
retries: int | urllib3.Retry | None = urllib3.Retry(
|
|
71
|
+
total=6, backoff_factor=1.5, allowed_methods=["GET", "POST"]
|
|
72
|
+
)
|
|
73
|
+
"""Retry strategy for requests that fail."""
|
|
74
|
+
|
|
75
|
+
timeout = 3.0
|
|
76
|
+
"""Seconds that a request can be idle before retrying."""
|
|
77
|
+
|
|
78
|
+
def __init__(
|
|
79
|
+
self,
|
|
80
|
+
url: str,
|
|
81
|
+
retries: int | urllib3.Retry | None = None,
|
|
82
|
+
timeout: float | None = None,
|
|
83
|
+
) -> None:
|
|
84
|
+
"""Create a session with the specified default parameters."""
|
|
85
|
+
self.url = url
|
|
86
|
+
if retries is not None:
|
|
87
|
+
self.retries = retries
|
|
88
|
+
if timeout is not None:
|
|
89
|
+
self.timeout = timeout
|
|
90
|
+
|
|
91
|
+
def request(
|
|
92
|
+
self,
|
|
93
|
+
method: str,
|
|
94
|
+
url: str,
|
|
95
|
+
retries: int | urllib3.Retry | None = None,
|
|
96
|
+
timeout: float | None = None,
|
|
97
|
+
**kwargs: Any,
|
|
98
|
+
) -> urllib3.HTTPResponse:
|
|
99
|
+
"""Send request and gather response.
|
|
100
|
+
|
|
101
|
+
A non-200 response code will result in a HTTPException
|
|
102
|
+
exception.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
method: HTTP method/verb to use for request (ex: 'GET' or 'POST').
|
|
106
|
+
url: URL to to connect to.
|
|
107
|
+
retries: Number of retries, or urllib3.Retry instance.
|
|
108
|
+
timeout: Timeout in seconds for each request attempt.
|
|
109
|
+
kwargs: Additional arguments for urllib3 pool.request(**kwargs).
|
|
110
|
+
|
|
111
|
+
Raises:
|
|
112
|
+
HTTPNotOkException: when the response code is not 200.
|
|
113
|
+
HTTPException: for any urllib3 exception.
|
|
114
|
+
"""
|
|
115
|
+
if retries is None:
|
|
116
|
+
retries = self.retries
|
|
117
|
+
if timeout is None:
|
|
118
|
+
timeout = self.timeout
|
|
119
|
+
|
|
120
|
+
# Create and destroy the pool each time. WeMo devices do not support
|
|
121
|
+
# http keep-alive. Forcing the pool to be destroyed ensures that the
|
|
122
|
+
# http connection is also closed. This avoids tying up TCP sessions
|
|
123
|
+
# on the device.
|
|
124
|
+
with urllib3.PoolManager(retries=retries, timeout=timeout) as pool:
|
|
125
|
+
response: urllib3.HTTPResponse
|
|
126
|
+
try:
|
|
127
|
+
response = pool.request(method=method, url=url, **kwargs)
|
|
128
|
+
if response.status != 200:
|
|
129
|
+
raise HTTPNotOkException(
|
|
130
|
+
f"Received status {response.status} for {url}"
|
|
131
|
+
)
|
|
132
|
+
except urllib3.exceptions.HTTPError as err:
|
|
133
|
+
raise HTTPException(err) from err
|
|
134
|
+
# For `requests` compatibility.
|
|
135
|
+
response.content = response.data # type: ignore
|
|
136
|
+
return response
|
|
137
|
+
|
|
138
|
+
def get(self, url: str, **kwargs: Any) -> urllib3.HTTPResponse:
|
|
139
|
+
"""HTTP GET request."""
|
|
140
|
+
return self.request("GET", url, **kwargs)
|
|
141
|
+
|
|
142
|
+
def post(self, url: str, **kwargs: Any) -> urllib3.HTTPResponse:
|
|
143
|
+
"""HTTP POST request."""
|
|
144
|
+
return self.request("POST", url, **kwargs)
|
|
145
|
+
|
|
146
|
+
def urljoin(self, path: str) -> str:
|
|
147
|
+
"""Build an absolute URL from a path."""
|
|
148
|
+
return urljoin(self._url, path)
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def url(self) -> str:
|
|
152
|
+
"""Return the current URL for the session."""
|
|
153
|
+
return self._url
|
|
154
|
+
|
|
155
|
+
@url.setter
|
|
156
|
+
def url(self, url: str) -> str:
|
|
157
|
+
"""Update the URL for the session."""
|
|
158
|
+
parsed_url = urlparse(url)
|
|
159
|
+
self._url = parsed_url.geturl()
|
|
160
|
+
self._port = parsed_url.port or 80
|
|
161
|
+
self._host = parsed_url.hostname or ""
|
|
162
|
+
return url
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def port(self) -> int:
|
|
166
|
+
"""TCP port associated with this session."""
|
|
167
|
+
return self._port
|
|
168
|
+
|
|
169
|
+
@property
|
|
170
|
+
def host(self) -> str:
|
|
171
|
+
"""Hostname associated with this session."""
|
|
172
|
+
return self._host
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class Action:
|
|
176
|
+
"""Representation of an Action for a WeMo device."""
|
|
177
|
+
|
|
178
|
+
soap_action_timeout_override = {
|
|
179
|
+
"urn:Belkin:service:bridge:1#AddDevice": 30,
|
|
180
|
+
"urn:Belkin:service:bridge:1#OpenNetwork": 30,
|
|
181
|
+
"urn:Belkin:service:WiFiSetup:1#GetApList": 10,
|
|
182
|
+
}
|
|
183
|
+
"""A few actions take longer than the default timeout. Override the default
|
|
184
|
+
timeout value for those actions."""
|
|
185
|
+
|
|
186
|
+
max_rediscovery_attempts = 3
|
|
187
|
+
|
|
188
|
+
def __init__(
|
|
189
|
+
self, service: Service, action_config: ActionProperties
|
|
190
|
+
) -> None:
|
|
191
|
+
"""Create an instance of an Action."""
|
|
192
|
+
self.name = action_config.name
|
|
193
|
+
self.service = service
|
|
194
|
+
self.soap_action = f"{service.serviceType}#{self.name}"
|
|
195
|
+
self.headers = {
|
|
196
|
+
"Content-Type": "text/xml",
|
|
197
|
+
"SOAPACTION": f'"{self.soap_action}"',
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
self.args = [
|
|
201
|
+
arg.name
|
|
202
|
+
for arg in action_config.arguments
|
|
203
|
+
if arg.direction.lower() != "out"
|
|
204
|
+
]
|
|
205
|
+
self.returns = [
|
|
206
|
+
arg.name
|
|
207
|
+
for arg in action_config.arguments
|
|
208
|
+
if arg.direction.lower() == "out"
|
|
209
|
+
]
|
|
210
|
+
|
|
211
|
+
def __call__(
|
|
212
|
+
self, *, pywemo_timeout: float | None = None, **kwargs: Any
|
|
213
|
+
) -> dict[str, str]:
|
|
214
|
+
"""Representations a method or function call."""
|
|
215
|
+
arglist = "\n".join(
|
|
216
|
+
f"<{arg}>{value}</{arg}>" for arg, value in kwargs.items()
|
|
217
|
+
)
|
|
218
|
+
body = REQUEST_TEMPLATE.format(
|
|
219
|
+
action=self.name, service=self.service.serviceType, args=arglist
|
|
220
|
+
).strip()
|
|
221
|
+
timeout = pywemo_timeout or self.soap_action_timeout_override.get(
|
|
222
|
+
self.soap_action
|
|
223
|
+
)
|
|
224
|
+
last_exception = None
|
|
225
|
+
|
|
226
|
+
for attempt in range(self.max_rediscovery_attempts):
|
|
227
|
+
session = self.service.device.session
|
|
228
|
+
try:
|
|
229
|
+
response = session.post(
|
|
230
|
+
self.service.controlURL,
|
|
231
|
+
headers=self.headers,
|
|
232
|
+
body=body,
|
|
233
|
+
timeout=timeout,
|
|
234
|
+
)
|
|
235
|
+
except HTTPException as err:
|
|
236
|
+
LOG.warning(
|
|
237
|
+
"Error communicating with %s at %s:%i, %r retry %i",
|
|
238
|
+
self.service.device.name,
|
|
239
|
+
session.host,
|
|
240
|
+
session.port,
|
|
241
|
+
err,
|
|
242
|
+
attempt,
|
|
243
|
+
)
|
|
244
|
+
last_exception = err
|
|
245
|
+
else:
|
|
246
|
+
envelope = et.fromstring(
|
|
247
|
+
response.data, parser=et.XMLParser(resolve_entities=False)
|
|
248
|
+
)
|
|
249
|
+
body_element = list(envelope)[0]
|
|
250
|
+
response_element = list(body_element)[0]
|
|
251
|
+
if (
|
|
252
|
+
response_element.tag
|
|
253
|
+
== "{http://schemas.xmlsoap.org/soap/envelope/}Fault"
|
|
254
|
+
):
|
|
255
|
+
raise SOAPFault(
|
|
256
|
+
f"Error calling {self.soap_action}",
|
|
257
|
+
fault_element=response_element,
|
|
258
|
+
)
|
|
259
|
+
return {
|
|
260
|
+
response_item.tag: response_item.text or ""
|
|
261
|
+
for response_item in response_element
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
self.service.device.reconnect_with_device()
|
|
265
|
+
|
|
266
|
+
msg = (
|
|
267
|
+
f"Error communicating with {self.service.device.name} after "
|
|
268
|
+
f"{self.max_rediscovery_attempts} attempts. Giving up."
|
|
269
|
+
)
|
|
270
|
+
LOG.error(msg)
|
|
271
|
+
raise ActionException(msg) from last_exception
|
|
272
|
+
|
|
273
|
+
def __repr__(self) -> str:
|
|
274
|
+
"""Return a string representation of the Action."""
|
|
275
|
+
return f"<Action {self.name}({', '.join(self.args)})>"
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
class Service(WeMoAllActionsMixin):
|
|
279
|
+
"""Representation of a service for a WeMo device."""
|
|
280
|
+
|
|
281
|
+
def __init__(self, device: "Device", service: ServiceProperties) -> None:
|
|
282
|
+
"""Create an instance of a Service."""
|
|
283
|
+
self.device = device
|
|
284
|
+
self._config = service
|
|
285
|
+
self.name = self.serviceType.split(":")[-2]
|
|
286
|
+
self.actions = {}
|
|
287
|
+
|
|
288
|
+
url = device.session.urljoin(service.description_url)
|
|
289
|
+
xml = device.session.get(url).data
|
|
290
|
+
|
|
291
|
+
try:
|
|
292
|
+
scpd = ServiceDescription.from_xml(xml)
|
|
293
|
+
except InvalidSchemaError:
|
|
294
|
+
LOG.debug("Received invalid schema from %s: %r", url, xml)
|
|
295
|
+
raise
|
|
296
|
+
|
|
297
|
+
for action in scpd.actions:
|
|
298
|
+
act = Action(self, action)
|
|
299
|
+
self.actions[act.name] = act
|
|
300
|
+
setattr(self, act.name, act)
|
|
301
|
+
|
|
302
|
+
@property
|
|
303
|
+
def controlURL(self) -> str: # pylint: disable=invalid-name
|
|
304
|
+
"""Get the controlURL for interacting with this Service."""
|
|
305
|
+
return self.device.session.urljoin(self._config.control_url)
|
|
306
|
+
|
|
307
|
+
@property
|
|
308
|
+
def eventSubURL(self) -> str: # pylint: disable=invalid-name
|
|
309
|
+
"""Get the eventSubURL for interacting with this Service."""
|
|
310
|
+
return self.device.session.urljoin(self._config.event_subscription_url)
|
|
311
|
+
|
|
312
|
+
@property
|
|
313
|
+
def serviceType(self) -> str: # pylint: disable=invalid-name
|
|
314
|
+
"""Get the type of this Service."""
|
|
315
|
+
return self._config.service_type
|
|
316
|
+
|
|
317
|
+
def __repr__(self) -> str:
|
|
318
|
+
"""Return a string representation of the Service."""
|
|
319
|
+
return f"<Service {self.name}({', '.join(self.actions)})>"
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
@dataclass(frozen=True)
|
|
323
|
+
class RequiredService:
|
|
324
|
+
"""Specifies the service name and actions that are required for a class."""
|
|
325
|
+
|
|
326
|
+
name: str
|
|
327
|
+
actions: list[str]
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
class RequiredServicesMixin: # pylint: disable=too-few-public-methods
|
|
331
|
+
"""Provide and check for required services."""
|
|
332
|
+
|
|
333
|
+
@property
|
|
334
|
+
def _required_services(self) -> list[RequiredService]:
|
|
335
|
+
return []
|
|
336
|
+
|
|
337
|
+
def _check_required_services(self, services: Iterable[Service]) -> None:
|
|
338
|
+
"""Validate that all required services are found."""
|
|
339
|
+
all_services: dict[str, set[str]] = defaultdict(set)
|
|
340
|
+
for supported_service in services:
|
|
341
|
+
all_services[supported_service.name].update(
|
|
342
|
+
supported_service.actions
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
missing_actions: dict[str, set[str]] = defaultdict(set)
|
|
346
|
+
|
|
347
|
+
for service in self._required_services:
|
|
348
|
+
if service.name not in all_services:
|
|
349
|
+
missing_actions[service.name].update(service.actions)
|
|
350
|
+
continue
|
|
351
|
+
service_actions = all_services[service.name]
|
|
352
|
+
for action in service.actions:
|
|
353
|
+
if action not in service_actions:
|
|
354
|
+
missing_actions[service.name].add(action)
|
|
355
|
+
|
|
356
|
+
if missing_actions:
|
|
357
|
+
error_str = ", ".join(
|
|
358
|
+
f"{service}({', '.join(methods)})"
|
|
359
|
+
for service, methods in missing_actions.items()
|
|
360
|
+
)
|
|
361
|
+
raise MissingServiceError(
|
|
362
|
+
f"Missing required services/methods: {error_str}"
|
|
363
|
+
)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Base classes for automatically generated WeMo service types.
|
|
2
|
+
|
|
3
|
+
These classes do nothing at run-time.
|
|
4
|
+
|
|
5
|
+
mypy, however, uses the wemo_services.pyi stub typing file to find basic type
|
|
6
|
+
information for the services and actions supported by WeMo devices. This type
|
|
7
|
+
information is generated by scripts/generate_wemo_service.py.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class WeMoServiceTypesMixin: # pylint: disable=too-few-public-methods
|
|
12
|
+
"""Mixin for the Device base class.
|
|
13
|
+
|
|
14
|
+
Provides type information for the service properties that are dynamically
|
|
15
|
+
set at run-time via `setattr(self, service_name, Service(...))`.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class WeMoAllActionsMixin: # pylint: disable=too-few-public-methods
|
|
20
|
+
"""Mixin for the Service base class.
|
|
21
|
+
|
|
22
|
+
Provides type information for every known service action method. These
|
|
23
|
+
methods are set as properties of the Service instance at run-time via
|
|
24
|
+
`setattr(self, action_name, Action(...))`.
|
|
25
|
+
"""
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"""WeMo service types.
|
|
2
|
+
|
|
3
|
+
Do not hand edit. This file is automatically generated. Any manual changes
|
|
4
|
+
will be erased the next time it is re-generated.
|
|
5
|
+
|
|
6
|
+
To regenerate this file, run:
|
|
7
|
+
scripts/generate_wemo_services.py > \
|
|
8
|
+
pywemo/ouimeaux_device/api/wemo_services.pyi
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from typing import Callable
|
|
12
|
+
|
|
13
|
+
UPnPMethod = Callable[..., dict[str, str]]
|
|
14
|
+
|
|
15
|
+
class Service_WiFiSetup:
|
|
16
|
+
CloseSetup: UPnPMethod
|
|
17
|
+
ConnectHomeNetwork: UPnPMethod
|
|
18
|
+
GetApList: UPnPMethod
|
|
19
|
+
GetNetworkList: UPnPMethod
|
|
20
|
+
GetNetworkStatus: UPnPMethod
|
|
21
|
+
StopPair: UPnPMethod
|
|
22
|
+
|
|
23
|
+
class Service_basicevent:
|
|
24
|
+
Calibrate: UPnPMethod
|
|
25
|
+
ChangeDeviceIcon: UPnPMethod
|
|
26
|
+
ChangeFriendlyName: UPnPMethod
|
|
27
|
+
CheckResetButtonState: UPnPMethod
|
|
28
|
+
ConfigureDimmingRange: UPnPMethod
|
|
29
|
+
ConfigureHushMode: UPnPMethod
|
|
30
|
+
ConfigureNightMode: UPnPMethod
|
|
31
|
+
ControlCloudUpload: UPnPMethod
|
|
32
|
+
GetBinaryState: UPnPMethod
|
|
33
|
+
GetCrockpotState: UPnPMethod
|
|
34
|
+
GetDeviceIcon: UPnPMethod
|
|
35
|
+
GetDeviceId: UPnPMethod
|
|
36
|
+
GetEnforceSecurity: UPnPMethod
|
|
37
|
+
GetFriendlyName: UPnPMethod
|
|
38
|
+
GetGPIO: UPnPMethod
|
|
39
|
+
GetHKSetupInfo: UPnPMethod
|
|
40
|
+
GetHomeId: UPnPMethod
|
|
41
|
+
GetHomeInfo: UPnPMethod
|
|
42
|
+
GetIconURL: UPnPMethod
|
|
43
|
+
GetIconVersion: UPnPMethod
|
|
44
|
+
GetInsightHomeSettings: UPnPMethod
|
|
45
|
+
GetJardenStatus: UPnPMethod
|
|
46
|
+
GetLogFileURL: UPnPMethod
|
|
47
|
+
GetMacAddr: UPnPMethod
|
|
48
|
+
GetNightLightStatus: UPnPMethod
|
|
49
|
+
GetNightModeConfiguration: UPnPMethod
|
|
50
|
+
GetPluginUDN: UPnPMethod
|
|
51
|
+
GetRuleOverrideStatus: UPnPMethod
|
|
52
|
+
GetSerialNo: UPnPMethod
|
|
53
|
+
GetServerEnvironment: UPnPMethod
|
|
54
|
+
GetSetupDoneStatus: UPnPMethod
|
|
55
|
+
GetSignalStrength: UPnPMethod
|
|
56
|
+
GetSimulatedRuleData: UPnPMethod
|
|
57
|
+
GetSmartDevInfo: UPnPMethod
|
|
58
|
+
GetWatchdogFile: UPnPMethod
|
|
59
|
+
NotifyManualToggle: UPnPMethod
|
|
60
|
+
ReSetup: UPnPMethod
|
|
61
|
+
SetAwayRuleTask: UPnPMethod
|
|
62
|
+
SetBinaryState: UPnPMethod
|
|
63
|
+
SetBulbType: UPnPMethod
|
|
64
|
+
SetCrockpotState: UPnPMethod
|
|
65
|
+
SetDeviceId: UPnPMethod
|
|
66
|
+
SetEnforceSecurity: UPnPMethod
|
|
67
|
+
SetGPIO: UPnPMethod
|
|
68
|
+
SetHomeId: UPnPMethod
|
|
69
|
+
SetInsightHomeSettings: UPnPMethod
|
|
70
|
+
SetJardenStatus: UPnPMethod
|
|
71
|
+
SetLogLevelOption: UPnPMethod
|
|
72
|
+
SetMultiState: UPnPMethod
|
|
73
|
+
SetNightLightStatus: UPnPMethod
|
|
74
|
+
SetServerEnvironment: UPnPMethod
|
|
75
|
+
SetSetupDoneStatus: UPnPMethod
|
|
76
|
+
SetSmartDevInfo: UPnPMethod
|
|
77
|
+
ShareHWInfo: UPnPMethod
|
|
78
|
+
SimulateLongPress: UPnPMethod
|
|
79
|
+
SimulateOverTemp: UPnPMethod
|
|
80
|
+
StartIperf: UPnPMethod
|
|
81
|
+
StopIperf: UPnPMethod
|
|
82
|
+
TestLEDs: UPnPMethod
|
|
83
|
+
UpdateInsightHomeSettings: UPnPMethod
|
|
84
|
+
getHKSetupState: UPnPMethod
|
|
85
|
+
identifyDevice: UPnPMethod
|
|
86
|
+
removeHomekitData: UPnPMethod
|
|
87
|
+
setAutoFWUpdate: UPnPMethod
|
|
88
|
+
setDummyMode: UPnPMethod
|
|
89
|
+
setHKSetupState: UPnPMethod
|
|
90
|
+
|
|
91
|
+
class Service_bridge:
|
|
92
|
+
AddDevice: UPnPMethod
|
|
93
|
+
AddDeviceName: UPnPMethod
|
|
94
|
+
CloseNetwork: UPnPMethod
|
|
95
|
+
CreateGroup: UPnPMethod
|
|
96
|
+
DeleteDataStores: UPnPMethod
|
|
97
|
+
DeleteGroup: UPnPMethod
|
|
98
|
+
GetCapabilityProfileIDList: UPnPMethod
|
|
99
|
+
GetCapabilityProfileList: UPnPMethod
|
|
100
|
+
GetDataStores: UPnPMethod
|
|
101
|
+
GetDeviceCapabilities: UPnPMethod
|
|
102
|
+
GetDeviceStatus: UPnPMethod
|
|
103
|
+
GetEndDevices: UPnPMethod
|
|
104
|
+
GetEndDevicesWithStatus: UPnPMethod
|
|
105
|
+
GetGroups: UPnPMethod
|
|
106
|
+
IdentifyDevice: UPnPMethod
|
|
107
|
+
OpenNetwork: UPnPMethod
|
|
108
|
+
QAControl: UPnPMethod
|
|
109
|
+
RemoveDevice: UPnPMethod
|
|
110
|
+
ScanZigbeeJoin: UPnPMethod
|
|
111
|
+
SetDataStores: UPnPMethod
|
|
112
|
+
SetDeviceName: UPnPMethod
|
|
113
|
+
SetDeviceNames: UPnPMethod
|
|
114
|
+
SetDeviceStatus: UPnPMethod
|
|
115
|
+
SetZigbeeMode: UPnPMethod
|
|
116
|
+
UpgradeSubDeviceFirmware: UPnPMethod
|
|
117
|
+
|
|
118
|
+
class Service_crockpotevent:
|
|
119
|
+
GetCrockpotState: UPnPMethod
|
|
120
|
+
GetJardenStatus: UPnPMethod
|
|
121
|
+
SetCrockpotState: UPnPMethod
|
|
122
|
+
SetJardenStatus: UPnPMethod
|
|
123
|
+
|
|
124
|
+
class Service_deviceevent:
|
|
125
|
+
GetAttributeList: UPnPMethod
|
|
126
|
+
GetAttributes: UPnPMethod
|
|
127
|
+
GetBlobStorage: UPnPMethod
|
|
128
|
+
SetAttributes: UPnPMethod
|
|
129
|
+
SetBlobStorage: UPnPMethod
|
|
130
|
+
|
|
131
|
+
class Service_deviceinfo:
|
|
132
|
+
CloseInstaAP: UPnPMethod
|
|
133
|
+
GetAutoFwUpdateVar: UPnPMethod
|
|
134
|
+
GetConfigureState: UPnPMethod
|
|
135
|
+
GetDeviceInformation: UPnPMethod
|
|
136
|
+
GetInformation: UPnPMethod
|
|
137
|
+
GetRouterInformation: UPnPMethod
|
|
138
|
+
InstaConnectHomeNetwork: UPnPMethod
|
|
139
|
+
InstaRemoteAccess: UPnPMethod
|
|
140
|
+
OpenInstaAP: UPnPMethod
|
|
141
|
+
SetAutoFwUpdateVar: UPnPMethod
|
|
142
|
+
UpdateBridgeList: UPnPMethod
|
|
143
|
+
|
|
144
|
+
class Service_firmwareupdate:
|
|
145
|
+
GetFirmwareVersion: UPnPMethod
|
|
146
|
+
UpdateFirmware: UPnPMethod
|
|
147
|
+
|
|
148
|
+
class Service_insight:
|
|
149
|
+
GetDataExportInfo: UPnPMethod
|
|
150
|
+
GetInSBYSince: UPnPMethod
|
|
151
|
+
GetInsightInfo: UPnPMethod
|
|
152
|
+
GetInsightParams: UPnPMethod
|
|
153
|
+
GetONFor: UPnPMethod
|
|
154
|
+
GetPower: UPnPMethod
|
|
155
|
+
GetPowerThreshold: UPnPMethod
|
|
156
|
+
GetTodayKWH: UPnPMethod
|
|
157
|
+
GetTodayONTime: UPnPMethod
|
|
158
|
+
GetTodaySBYTime: UPnPMethod
|
|
159
|
+
ResetPowerThreshold: UPnPMethod
|
|
160
|
+
ScheduleDataExport: UPnPMethod
|
|
161
|
+
SetAutoPowerThreshold: UPnPMethod
|
|
162
|
+
SetPowerThreshold: UPnPMethod
|
|
163
|
+
|
|
164
|
+
class Service_jardenevent:
|
|
165
|
+
GetCrockpotState: UPnPMethod
|
|
166
|
+
GetJardenStatus: UPnPMethod
|
|
167
|
+
SetCrockpotState: UPnPMethod
|
|
168
|
+
SetJardenStatus: UPnPMethod
|
|
169
|
+
|
|
170
|
+
class Service_manufacture:
|
|
171
|
+
GetManufactureData: UPnPMethod
|
|
172
|
+
|
|
173
|
+
class Service_metainfo:
|
|
174
|
+
GetExtMetaInfo: UPnPMethod
|
|
175
|
+
GetMetaInfo: UPnPMethod
|
|
176
|
+
|
|
177
|
+
class Service_remoteaccess:
|
|
178
|
+
RemoteAccess: UPnPMethod
|
|
179
|
+
|
|
180
|
+
class Service_rules:
|
|
181
|
+
DeleteRuleID: UPnPMethod
|
|
182
|
+
DeleteWeeklyCalendar: UPnPMethod
|
|
183
|
+
EditWeeklycalendar: UPnPMethod
|
|
184
|
+
FetchRules: UPnPMethod
|
|
185
|
+
GetRules: UPnPMethod
|
|
186
|
+
GetRulesDBPath: UPnPMethod
|
|
187
|
+
GetRulesDBVersion: UPnPMethod
|
|
188
|
+
GetTemplates: UPnPMethod
|
|
189
|
+
SetRuleID: UPnPMethod
|
|
190
|
+
SetRules: UPnPMethod
|
|
191
|
+
SetRulesDBVersion: UPnPMethod
|
|
192
|
+
SetTemplates: UPnPMethod
|
|
193
|
+
SimulatedRuleData: UPnPMethod
|
|
194
|
+
StoreRules: UPnPMethod
|
|
195
|
+
UpdateWeeklyCalendar: UPnPMethod
|
|
196
|
+
|
|
197
|
+
class Service_smartsetup:
|
|
198
|
+
GetRegistrationData: UPnPMethod
|
|
199
|
+
GetRegistrationStatus: UPnPMethod
|
|
200
|
+
PairAndRegister: UPnPMethod
|
|
201
|
+
|
|
202
|
+
class Service_timesync:
|
|
203
|
+
GetDeviceTime: UPnPMethod
|
|
204
|
+
GetTime: UPnPMethod
|
|
205
|
+
TimeSync: UPnPMethod
|
|
206
|
+
|
|
207
|
+
class WeMoServiceTypesMixin:
|
|
208
|
+
WiFiSetup: Service_WiFiSetup
|
|
209
|
+
basicevent: Service_basicevent
|
|
210
|
+
bridge: Service_bridge
|
|
211
|
+
crockpotevent: Service_crockpotevent
|
|
212
|
+
deviceevent: Service_deviceevent
|
|
213
|
+
deviceinfo: Service_deviceinfo
|
|
214
|
+
firmwareupdate: Service_firmwareupdate
|
|
215
|
+
insight: Service_insight
|
|
216
|
+
jardenevent: Service_jardenevent
|
|
217
|
+
manufacture: Service_manufacture
|
|
218
|
+
metainfo: Service_metainfo
|
|
219
|
+
remoteaccess: Service_remoteaccess
|
|
220
|
+
rules: Service_rules
|
|
221
|
+
smartsetup: Service_smartsetup
|
|
222
|
+
timesync: Service_timesync
|
|
223
|
+
|
|
224
|
+
class WeMoAllActionsMixin(
|
|
225
|
+
Service_WiFiSetup,
|
|
226
|
+
Service_basicevent,
|
|
227
|
+
Service_bridge,
|
|
228
|
+
Service_crockpotevent,
|
|
229
|
+
Service_deviceevent,
|
|
230
|
+
Service_deviceinfo,
|
|
231
|
+
Service_firmwareupdate,
|
|
232
|
+
Service_insight,
|
|
233
|
+
Service_jardenevent,
|
|
234
|
+
Service_manufacture,
|
|
235
|
+
Service_metainfo,
|
|
236
|
+
Service_remoteaccess,
|
|
237
|
+
Service_rules,
|
|
238
|
+
Service_smartsetup,
|
|
239
|
+
Service_timesync,
|
|
240
|
+
):
|
|
241
|
+
pass
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""device.py and service.py are generated by generateDS."""
|