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.
Files changed (40) hide show
  1. pywemo/README.md +69 -0
  2. pywemo/__init__.py +33 -0
  3. pywemo/color.py +79 -0
  4. pywemo/discovery.py +194 -0
  5. pywemo/exceptions.py +94 -0
  6. pywemo/ouimeaux_device/LICENSE +12 -0
  7. pywemo/ouimeaux_device/__init__.py +679 -0
  8. pywemo/ouimeaux_device/api/__init__.py +1 -0
  9. pywemo/ouimeaux_device/api/attributes.py +131 -0
  10. pywemo/ouimeaux_device/api/db_orm.py +197 -0
  11. pywemo/ouimeaux_device/api/long_press.py +168 -0
  12. pywemo/ouimeaux_device/api/rules_db.py +467 -0
  13. pywemo/ouimeaux_device/api/service.py +363 -0
  14. pywemo/ouimeaux_device/api/wemo_services.py +25 -0
  15. pywemo/ouimeaux_device/api/wemo_services.pyi +241 -0
  16. pywemo/ouimeaux_device/api/xsd/__init__.py +1 -0
  17. pywemo/ouimeaux_device/api/xsd/device.py +3888 -0
  18. pywemo/ouimeaux_device/api/xsd/device.xsd +95 -0
  19. pywemo/ouimeaux_device/api/xsd/service.py +3872 -0
  20. pywemo/ouimeaux_device/api/xsd/service.xsd +93 -0
  21. pywemo/ouimeaux_device/api/xsd_types.py +222 -0
  22. pywemo/ouimeaux_device/bridge.py +506 -0
  23. pywemo/ouimeaux_device/coffeemaker.py +92 -0
  24. pywemo/ouimeaux_device/crockpot.py +157 -0
  25. pywemo/ouimeaux_device/dimmer.py +70 -0
  26. pywemo/ouimeaux_device/humidifier.py +223 -0
  27. pywemo/ouimeaux_device/insight.py +191 -0
  28. pywemo/ouimeaux_device/lightswitch.py +11 -0
  29. pywemo/ouimeaux_device/maker.py +54 -0
  30. pywemo/ouimeaux_device/motion.py +6 -0
  31. pywemo/ouimeaux_device/outdoor_plug.py +6 -0
  32. pywemo/ouimeaux_device/switch.py +32 -0
  33. pywemo/py.typed +0 -0
  34. pywemo/ssdp.py +372 -0
  35. pywemo/subscribe.py +782 -0
  36. pywemo/util.py +139 -0
  37. pywemo-1.4.0.dist-info/LICENSE +54 -0
  38. pywemo-1.4.0.dist-info/METADATA +192 -0
  39. pywemo-1.4.0.dist-info/RECORD +40 -0
  40. 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."""