python-swidget 1.0.1__tar.gz → 1.0.3__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-swidget
3
- Version: 1.0.1
3
+ Version: 1.0.3
4
4
  Summary: Python API for Swidget smart devices
5
5
  Home-page: https://github.com/swidget/python-swidget
6
6
  License: GPL-3.0-or-later
@@ -21,10 +21,13 @@ Requires-Dist: importlib-metadata
21
21
  Requires-Dist: m2r (>=0,<1) ; extra == "docs"
22
22
  Requires-Dist: mistune (<2.0.0) ; extra == "docs"
23
23
  Requires-Dist: pydantic (>=1,<2)
24
+ Requires-Dist: requests (==2.31.0)
24
25
  Requires-Dist: sphinx (>=4,<5) ; extra == "docs"
25
26
  Requires-Dist: sphinx_rtd_theme (>=0,<1) ; extra == "docs"
26
27
  Requires-Dist: sphinxcontrib-programoutput (>=0,<1) ; extra == "docs"
27
28
  Requires-Dist: ssdp (==1.1.1)
29
+ Requires-Dist: types-requests (==2.31.0.6)
30
+ Requires-Dist: urllib3 (==1.26.5)
28
31
  Project-URL: Repository, https://github.com/swidget/python-swidget
29
32
  Description-Content-Type: text/markdown
30
33
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-swidget"
3
- version = "1.0.1"
3
+ version = "1.0.3"
4
4
  description = "Python API for Swidget smart devices"
5
5
  license = "GPL-3.0-or-later"
6
6
  authors = ["Swidget"]
@@ -22,6 +22,9 @@ importlib-metadata = "*"
22
22
  asyncclick = ">=8"
23
23
  pydantic = "^1"
24
24
  ssdp = "1.1.1"
25
+ requests = "2.31.0"
26
+ types-requests = "2.31.0.6"
27
+ urllib3 = '1.26.5'
25
28
 
26
29
  # required only for docs
27
30
  sphinx = { version = "^4", optional = true }
@@ -1,8 +1,8 @@
1
1
  """python-swidget cli tool."""
2
2
  import logging
3
3
  import sys
4
+ from typing import Any, cast
4
5
  from pprint import pformat as pf
5
- from typing import cast
6
6
 
7
7
  import asyncclick as click
8
8
  from contextlib import asynccontextmanager
@@ -25,8 +25,6 @@ TYPE_TO_CLASS = {
25
25
  "pana_switch": SwidgetTimerSwitch
26
26
  }
27
27
 
28
- click.anyio_backend = "asyncio"
29
-
30
28
 
31
29
  pass_dev = click.make_pass_decorator(SwidgetDevice)
32
30
 
@@ -72,7 +70,7 @@ async def cli(ctx, host, password, debug, http_only, type):
72
70
  if ctx.invoked_subcommand == "discover" or ctx.invoked_subcommand == "wifi":
73
71
  return
74
72
  if host is None:
75
- click.echo("No host name given, trying discovery..")
73
+ click.echo("No hostname or IP given, trying discovery..")
76
74
  await ctx.invoke(discover)
77
75
  return
78
76
  if type is not None:
@@ -193,31 +191,25 @@ async def state(dev: SwidgetDevice):
193
191
  @click.argument("command")
194
192
  async def raw_command(dev: SwidgetDevice, assembly, component, function, command):
195
193
  """Run a raw command on the device."""
196
- import ast
197
-
198
- if parameters is not None:
199
- parameters = ast.literal_eval(parameters)
200
-
201
- res = await dev.send_command(assembly, component, function, command)
202
-
203
- click.echo(res)
204
- return res
194
+ await dev.send_command(assembly, component, function, command)
195
+ click.echo("Command sent")
205
196
 
206
197
 
207
198
  @cli.command()
208
199
  @click.argument("brightness", type=click.IntRange(0, 100), default=None, required=False)
209
200
  @pass_dev
210
- async def brightness(dev: SwidgetDimmer, brightness: int):
201
+ async def brightness(dev: SwidgetDevice, brightness: Any=None):
202
+ dimmer_dev = cast(SwidgetDimmer, dev)
211
203
  """Get or set brightness."""
212
- if not dev.is_dimmer:
204
+ if not dimmer_dev.is_dimmer:
213
205
  click.echo("This device does not support brightness.")
214
206
  return
215
207
 
216
208
  if brightness is None:
217
- click.echo(f"Brightness: {dev.brightness}")
209
+ click.echo(f"Brightness: {dimmer_dev.brightness}")
218
210
  else:
219
211
  click.echo(f"Setting brightness to {brightness}")
220
- return await dev.set_brightness(brightness)
212
+ return await dimmer_dev.set_brightness(brightness)
221
213
 
222
214
 
223
215
  @cli.command()
@@ -1,11 +1,10 @@
1
1
  import asyncio
2
- import json
3
2
  import logging
4
3
  import socket
5
- from typing import Awaitable, Callable, Dict, Optional, Type, cast
4
+ from typing import Any, Type
6
5
  from urllib.parse import urlparse
7
6
 
8
- import ssdp
7
+ import ssdp # type: ignore
9
8
 
10
9
  from swidget.swidgetdevice import DeviceType, SwidgetDevice
11
10
  from .swidgetdimmer import SwidgetDimmer
@@ -39,7 +38,7 @@ class SwidgetProtocol(ssdp.SimpleServiceDiscoveryProtocol):
39
38
  insert_type = headers["SERVER"].split(" ")[1].split("+")[1].split("/")[0]
40
39
  friendly_name = headers["SERVER"].split("/")[2].strip('"')
41
40
  devices[mac_address] = SwidgetDiscoveredDevice(mac_address, ip_address, friendly_name)
42
- _LOGGER.debug(f"Swidget device '{friendly_name}' at {ip_address}")
41
+ _LOGGER.debug(f"Swidget device '{friendly_name}' at {ip_address}. {device_type}/{insert_type}")
43
42
 
44
43
 
45
44
  async def discover_devices(timeout=RESPONSE_SEC):
@@ -65,7 +64,7 @@ async def discover_devices(timeout=RESPONSE_SEC):
65
64
  return devices
66
65
 
67
66
 
68
- async def discover_single(host: str, token_name: str, password: str, use_https: bool, use_websockets: bool) -> SwidgetDevice:
67
+ async def discover_single(host: str, token_name: str, password: str, use_https: bool, use_websockets: bool) -> Any:
69
68
  """Discover a single device by the given IP address.
70
69
 
71
70
  :param host: Hostname of device to query
@@ -88,16 +87,16 @@ async def discover_single(host: str, token_name: str, password: str, use_https:
88
87
  return dev
89
88
 
90
89
 
91
- def _get_device_class(device_type: str) -> Type[SwidgetDevice]:
90
+ def _get_device_class(device_type: DeviceType) -> Type[SwidgetDevice]:
92
91
  """Find SmartDevice subclass for device described by passed data."""
93
- if device_type == "outlet":
92
+ if device_type == DeviceType.Outlet:
94
93
  return SwidgetOutlet
95
- elif device_type == "switch":
94
+ elif device_type == DeviceType.Switch:
96
95
  return SwidgetSwitch
97
- elif device_type == "dimmer":
96
+ elif device_type == DeviceType.Dimmer:
98
97
  return SwidgetDimmer
99
- elif device_type == "pana_switch": # This is the timer switch
98
+ elif device_type == DeviceType.TimerSwitch: # This is the timer switch
100
99
  return SwidgetTimerSwitch
101
- elif device_type == "relay_switch":
100
+ elif device_type == DeviceType.RelaySwitch:
102
101
  return SwidgetSwitch
103
102
  raise SwidgetException("Unknown device type: %s" % device_type)
@@ -5,7 +5,7 @@ import time
5
5
  from aiohttp import ClientSession, TCPConnector
6
6
  import asyncio
7
7
  from enum import Enum
8
- from typing import Dict, List, Set
8
+ from typing import Any, Dict, List
9
9
 
10
10
  from .exceptions import SwidgetException
11
11
  from .websocket import SwidgetWebsocket
@@ -24,22 +24,21 @@ class DeviceType(Enum):
24
24
 
25
25
 
26
26
  class SwidgetDevice:
27
- def __init__(self, host, token_name, secret_key, use_https=True, use_websockets=True):
27
+ def __init__(self, host, token_name, secret_key, use_https=True, use_websockets=True) -> None:
28
28
  self.token_name = token_name
29
29
  self.ip_address = host
30
-
31
30
  self.use_https = use_https
32
31
  self.uri_scheme = 'https' if self.use_https is True else 'http'
33
32
  self.secret_key = secret_key
34
33
  self.use_websockets = use_websockets
35
34
  self.device_type = DeviceType.Unknown
36
35
  self._friendly_name = "Unknown Swidget Device"
37
- self.assemblies = {}
36
+ self.assemblies: Dict[Any, Any] = dict()
38
37
  headers = {self.token_name: self.secret_key,
39
38
  'Connection': 'keep-alive'}
40
39
  connector = TCPConnector(verify_ssl=False, force_close=True)
41
40
  self._session = ClientSession(headers=headers, connector=connector)
42
- self._last_update = None
41
+ self._last_update: int = 0
43
42
  if self.use_websockets:
44
43
  self._websocket = SwidgetWebsocket(
45
44
  host=self.ip_address,
@@ -48,18 +47,18 @@ class SwidgetDevice:
48
47
  callback=self.message_callback,
49
48
  session=self._session)
50
49
 
51
- def get_websocket(self):
50
+ def get_websocket(self) -> SwidgetWebsocket | None:
52
51
  if self.use_websockets:
53
52
  return self._websocket
54
53
  return None
55
54
 
56
- def set_countdown_timer(self, minutes):
55
+ def set_countdown_timer(self, minutes) -> Any:
57
56
  raise NotImplementedError()
58
57
 
59
- async def connect(self):
58
+ async def connect(self) -> None:
60
59
  await self._websocket.connect()
61
60
 
62
- async def start(self):
61
+ async def start(self) -> None:
63
62
  """Start the websocket."""
64
63
  _LOGGER.debug("SwidgetDevice.start()")
65
64
  if self.use_websockets:
@@ -68,17 +67,17 @@ class SwidgetDevice:
68
67
  _LOGGER.debug("Calling self.update() ")
69
68
  await self.update()
70
69
 
71
- async def stop(self):
70
+ async def stop(self) -> None:
72
71
  """Stop the websocket."""
73
72
  _LOGGER.debug("SwidgetDevice.stop()")
74
73
  if hasattr(self, '_websocket'):
75
74
  await self._websocket.close()
76
75
  await self._session.close()
77
76
 
78
- async def close(self):
77
+ async def close(self) -> None:
79
78
  await self.stop()
80
79
 
81
- async def message_callback(self, message):
80
+ async def message_callback(self, message) -> None:
82
81
  """Entrypoint for a websocket callback"""
83
82
  _LOGGER.debug("SwidgetDevice.message_callback() called")
84
83
  if message["request_id"] == "summary":
@@ -90,7 +89,7 @@ class SwidgetDevice:
90
89
  else:
91
90
  _LOGGER.error(f"Unknown message type from websocket. Type given was: {message["request_id"]}")
92
91
 
93
- async def get_summary(self):
92
+ async def get_summary(self) -> None:
94
93
  """Get a summary of the device over HTTP"""
95
94
  _LOGGER.debug("SwidgetDevice.get_summary() called")
96
95
  if self.use_websockets:
@@ -104,7 +103,7 @@ class SwidgetDevice:
104
103
  summary = await response.json()
105
104
  await self.process_summary(summary)
106
105
 
107
- async def process_summary(self, summary):
106
+ async def process_summary(self, summary) -> None:
108
107
  """ Process the data around the summary of the device"""
109
108
  _LOGGER.debug("SwidgetDevice.process_summary() called")
110
109
  _LOGGER.debug(f"Summary to process: {summary}")
@@ -115,12 +114,12 @@ class SwidgetDevice:
115
114
  "host": SwidgetAssembly(summary["host"]),
116
115
  "insert": SwidgetAssembly(summary["insert"]),
117
116
  }
118
- self.device_type = self.assemblies['host'].type
117
+ self.device_type = DeviceType(self.assemblies['host'].type)
119
118
  self.insert_type = self.assemblies['insert'].type
120
119
  self.id = self.assemblies['host'].id
121
120
  self._last_update = int(time.time())
122
121
 
123
- async def get_friendly_name(self):
122
+ async def get_friendly_name(self) -> None:
124
123
  _LOGGER.debug("SwidgetDevice.get_friendly_name() called")
125
124
  try:
126
125
  async with self._session.get(
@@ -131,12 +130,12 @@ class SwidgetDevice:
131
130
  name = {"name": f"Swidget {self.device_type} w/{self.insert_type} insert"}
132
131
  await self.process_friendly_name(name['name'])
133
132
 
134
- async def process_friendly_name(self, name):
133
+ async def process_friendly_name(self, name) -> None:
135
134
  _LOGGER.debug("SwidgetDevice.process_friendly_name() called")
136
135
  self._friendly_name = name
137
136
  self._last_update = int(time.time())
138
137
 
139
- async def get_state(self):
138
+ async def get_state(self) -> None:
140
139
  """ Get the state of the device over HTTP"""
141
140
  _LOGGER.debug("SwidgetDevice.get_state() called")
142
141
  if self.use_websockets:
@@ -150,7 +149,7 @@ class SwidgetDevice:
150
149
  state = await response.json()
151
150
  await self.process_state(state)
152
151
 
153
- async def process_state(self, state):
152
+ async def process_state(self, state) -> None:
154
153
  """ Process any information about the state of the device or insert"""
155
154
  # State is not always in the state (during callback)
156
155
  _LOGGER.debug("SwidgetDevice.process_state() called")
@@ -167,9 +166,9 @@ class SwidgetDevice:
167
166
  pass
168
167
  self._last_update = int(time.time())
169
168
 
170
- async def update(self):
169
+ async def update(self) -> None:
171
170
  _LOGGER.debug("SwidgetDevice.update() called")
172
- if self._last_update is None:
171
+ if self._last_update == 0:
173
172
  _LOGGER.debug("Performing the initial update to obtain sysinfo")
174
173
  await self.get_summary()
175
174
  await self.get_state()
@@ -182,25 +181,25 @@ class SwidgetDevice:
182
181
  await self.get_summary()
183
182
  await self.get_state()
184
183
 
185
- async def send_config(self, payload: dict):
184
+ async def send_config(self, payload: dict) -> None:
186
185
  _LOGGER.debug("SwidgetDevice.send_config() called")
187
186
  data = json.dumps({"type":"config","request_id":"send_config", "payload": payload})
188
187
  await self._websocket.send_str(data)
189
188
 
190
189
  async def send_command(
191
190
  self, assembly: str, component: str, function: str, command: dict
192
- ):
191
+ ) -> None:
193
192
  _LOGGER.debug("SwidgetDevice.send_command() called")
194
193
  """Send a command to the Swidget device either using a HTTP call or the existing websocket"""
195
194
  data = {assembly: {"components": {component: {function: command}}}}
196
195
  _LOGGER.debug(f"Command to send: {data}")
197
196
  if self.use_websockets:
198
197
  _LOGGER.debug("In websocket mode. Sending command over websocket")
199
- data = json.dumps({"type": "command",
198
+ command_data = json.dumps({"type": "command",
200
199
  "request_id": "command",
201
200
  "payload": data
202
201
  })
203
- await self._websocket.send_str(data)
202
+ await self._websocket.send_str(command_data)
204
203
  else:
205
204
  _LOGGER.debug("NOT in websocket mode, sending command over HTTP")
206
205
  async with self._session.post(
@@ -214,7 +213,7 @@ class SwidgetDevice:
214
213
  function_value = state[assembly]["components"][component][function]
215
214
  self.assemblies[assembly].components[component].functions[function] = function_value # fmt: skip
216
215
 
217
- async def ping(self):
216
+ async def ping(self) -> int | SwidgetException:
218
217
  """Ping the device to ensure it's devices
219
218
 
220
219
  :raises SwidgetException: Raise the exception if there we are unable to connect to the Swidget device
@@ -229,7 +228,7 @@ class SwidgetDevice:
229
228
  except:
230
229
  raise SwidgetException
231
230
 
232
- async def blink(self):
231
+ async def blink(self) -> Any:
233
232
  """Make the device LED blink
234
233
 
235
234
  :raises SwidgetException: Raise the exception if there we are unable to connect to the Swidget device
@@ -244,7 +243,7 @@ class SwidgetDevice:
244
243
  except:
245
244
  raise SwidgetException
246
245
 
247
- async def enable_debug_server(self):
246
+ async def enable_debug_server(self) -> Any:
248
247
  """Enable the Swidget local debug server
249
248
 
250
249
  :raises SwidgetException: Raise the exception if there we are unable to connect to the Swidget device
@@ -259,7 +258,7 @@ class SwidgetDevice:
259
258
  except:
260
259
  raise SwidgetException
261
260
 
262
- async def factory_reset(self):
261
+ async def factory_reset(self) -> Any:
263
262
  """Factory reset the Swidget device
264
263
 
265
264
  :raises SwidgetException: Raise the exception if there we are unable to connect to the Swidget device
@@ -274,7 +273,7 @@ class SwidgetDevice:
274
273
  except:
275
274
  raise SwidgetException
276
275
 
277
- async def check_for_updates(self):
276
+ async def check_for_updates(self) -> Any:
278
277
  """Tell the device to contact the Swidget servers to see if there is an available update
279
278
 
280
279
  :raises SwidgetException: Raise the exception if there we are unable to connect to the Swidget device
@@ -289,7 +288,7 @@ class SwidgetDevice:
289
288
  except:
290
289
  raise SwidgetException
291
290
 
292
- async def update_version(self, version):
291
+ async def update_version(self, version) -> Any:
293
292
  """Tell the device to download and apply an update
294
293
 
295
294
  :raises SwidgetException: Raise the exception if there we are unable to connect to the Swidget device
@@ -303,7 +302,7 @@ class SwidgetDevice:
303
302
  ssl=False,
304
303
  data=json.dumps(data)
305
304
  ) as response:
306
- return await response
305
+ return await response.json()
307
306
  except:
308
307
  raise SwidgetException
309
308
 
@@ -326,7 +325,7 @@ class SwidgetDevice:
326
325
  "rssi": self.rssi
327
326
  }
328
327
 
329
- async def get_child_consumption(self, plug_id=0):
328
+ async def get_child_consumption(self, plug_id=0) -> Any:
330
329
  """Get the power consumption of a plug in watts."""
331
330
  if plug_id == "all":
332
331
  return_dict = {}
@@ -338,7 +337,7 @@ class SwidgetDevice:
338
337
  return return_dict
339
338
  return self.assemblies['host'].components[str(plug_id)].functions['power']['current']
340
339
 
341
- async def total_consumption(self):
340
+ async def total_consumption(self) -> float:
342
341
  """Get the total power consumption in watts."""
343
342
  total_consumption = 0
344
343
  for id, properties in self.assemblies['host'].components.items():
@@ -346,7 +345,7 @@ class SwidgetDevice:
346
345
  return total_consumption
347
346
 
348
347
  @property
349
- async def realtime_values(self):
348
+ async def realtime_values(self) -> Dict:
350
349
  """Get a dict of realtime value attributes from the insert and host
351
350
 
352
351
  :return: A dictionary of insert sensor values and power consumption values
@@ -367,7 +366,7 @@ class SwidgetDevice:
367
366
  try:
368
367
  return list(self.assemblies['host'].components['0'].functions.keys())
369
368
  except KeyError:
370
- return set()
369
+ return list()
371
370
 
372
371
  @property
373
372
  def insert_features(self) -> List[str]:
@@ -375,9 +374,9 @@ class SwidgetDevice:
375
374
  try:
376
375
  return list(self.assemblies['insert'].components.keys())
377
376
  except KeyError:
378
- return set()
377
+ return list()
379
378
 
380
- def get_function_values(self, function: str):
379
+ def get_function_values(self, function: str) -> Dict:
381
380
  """Return the values of an insert function."""
382
381
  return_values = dict()
383
382
  for function, data in self.assemblies['insert'].components[function].functions.items():
@@ -389,7 +388,7 @@ class SwidgetDevice:
389
388
  return_values[function] = data['now']
390
389
  return return_values
391
390
 
392
- def get_sensor_value(self, function, sensor):
391
+ def get_sensor_value(self, function, sensor) -> float | str:
393
392
  """Return the value of a sensor given a function and sensor"""
394
393
  if sensor == "occupied":
395
394
  return self.assemblies['insert'].components[function].functions['occupied']['state']
@@ -399,22 +398,22 @@ class SwidgetDevice:
399
398
  @property
400
399
  def is_outlet(self) -> bool:
401
400
  """Return True if the device is an outlet."""
402
- return self.device_type == "outlet"
401
+ return self.device_type == DeviceType.Outlet
403
402
 
404
403
  @property
405
404
  def is_switch(self) -> bool:
406
405
  """Return True if the device is a switch"""
407
- return self.device_type == "switch" or self.device_type == "pana_switch" or self.device_type == "relay_switch"
406
+ return self.device_type == DeviceType.Switch or self.device_type == DeviceType.TimerSwitch or self.device_type == DeviceType.RelaySwitch
408
407
 
409
408
  @property
410
409
  def is_pana_switch(self) -> bool:
411
410
  """Return True if the device is a pana_switch"""
412
- return self.device_type == "pana_switch"
411
+ return self.device_type == DeviceType.TimerSwitch
413
412
 
414
413
  @property
415
414
  def is_dimmer(self) -> bool:
416
415
  """Return True if the device is a dimmer"""
417
- return self.device_type == "dimmer"
416
+ return self.device_type == DeviceType.Dimmer
418
417
 
419
418
  @property
420
419
  def is_dimmable(self) -> bool:
@@ -434,27 +433,27 @@ class SwidgetDevice:
434
433
  return True
435
434
  return False
436
435
 
437
- async def turn_on(self):
436
+ async def turn_on(self) -> None:
438
437
  """Turn the device on."""
439
438
  _LOGGER.debug("SwidgetDevice.turn_on() called")
440
439
  await self.send_command(
441
440
  assembly="host", component="0", function="toggle", command={"state": "on"}
442
441
  )
443
442
 
444
- async def turn_off(self):
443
+ async def turn_off(self) -> None:
445
444
  """Turn the device off."""
446
445
  _LOGGER.debug("SwidgetDevice.turn_off() called")
447
446
  await self.send_command(
448
447
  assembly="host", component="0", function="toggle", command={"state": "off"}
449
448
  )
450
449
 
451
- async def turn_on_usb_insert(self):
450
+ async def turn_on_usb_insert(self) -> None:
452
451
  """Turn the USB insert on."""
453
452
  await self.send_command(
454
453
  assembly="insert", component="usb", function="toggle", command={"state": "on"}
455
454
  )
456
455
 
457
- async def turn_off_usb_insert(self):
456
+ async def turn_off_usb_insert(self) -> None:
458
457
  """Turn the USB insert off."""
459
458
  await self.send_command(
460
459
  assembly="insert", component="usb", function="toggle", command={"state": "off"}
@@ -468,8 +467,8 @@ class SwidgetDevice:
468
467
  return True
469
468
  return False
470
469
 
471
- def __repr__(self):
472
- if self._last_update is None:
470
+ def __repr__(self) -> str:
471
+ if self._last_update == 0:
473
472
  return f"<{self.device_type} at {self.ip_address} - update() needed>"
474
473
  return f"<{self.device_type} model {self.model} at {self.ip_address}>"
475
474
 
@@ -28,14 +28,14 @@ class SwidgetDimmer(SwidgetDevice):
28
28
  except KeyError:
29
29
  return self.assemblies['host'].components["0"].functions["level"]["default"]
30
30
 
31
- async def set_brightness(self, brightness):
31
+ async def set_brightness(self, brightness) -> None:
32
32
  """Set the brightness of the device."""
33
33
  _LOGGER.debug("SwidgetDimmer.set_brightness() called")
34
34
  await self.send_command(
35
35
  assembly="host", component="0", function="level", command={"now": brightness}
36
36
  )
37
37
 
38
- async def set_default_brightness(self, brightness):
38
+ async def set_default_brightness(self, brightness) -> None:
39
39
  _LOGGER.debug("SwidgetDimmer.set_default_brightness() called")
40
40
  await self.send_command(
41
41
  assembly="host", component="0", function="level", command={"default": brightness}
@@ -8,8 +8,4 @@ class SwidgetSwitch(SwidgetDevice):
8
8
 
9
9
  def __init__(self, host, token_name: str, secret_key: str, use_https: bool, use_websockets: bool) -> None:
10
10
  super().__init__(host=host, token_name=token_name, secret_key=secret_key, use_https=use_https, use_websockets=use_websockets)
11
- self._device_type = DeviceType.Switch
12
-
13
- async def current_consumption(self) -> float:
14
- """Get the current power consumption in watts."""
15
- return sum([await plug.current_consumption() for plug in self.children])
11
+ self._device_type = DeviceType.Switch
@@ -1,4 +1,6 @@
1
1
  import logging
2
+ from typing import Any
3
+
2
4
  from swidget.swidgetdevice import (
3
5
  DeviceType,
4
6
  )
@@ -13,7 +15,7 @@ class SwidgetTimerSwitch(SwidgetSwitch):
13
15
  super().__init__(host=host, token_name=token_name, secret_key=secret_key, use_https=use_https, use_websockets=use_websockets)
14
16
  self._device_type = DeviceType.TimerSwitch
15
17
 
16
- async def set_countdown_timer(self, minutes):
18
+ async def set_countdown_timer(self, minutes) -> Any:
17
19
  """Set the countdown timer."""
18
20
  _LOGGER.debug("SwidgetTimerSwitch.set_brightness() called")
19
21
  await self.send_command(
@@ -33,7 +33,7 @@ class SwidgetWebsocket:
33
33
  session=None,
34
34
  use_security=True,
35
35
  ):
36
-
36
+ self.host = host
37
37
  self.session = session or aiohttp.ClientSession()
38
38
  self.use_security = use_security
39
39
  self.uri = self.get_uri(host, token_name, secret_key)
@@ -52,7 +52,7 @@ class SwidgetWebsocket:
52
52
  @property
53
53
  def websocket(self) -> ClientWebSocketResponse | None:
54
54
  """Return the web socket."""
55
- return self._ws
55
+ return self._client
56
56
 
57
57
  def get_uri(self, host, token_name, secret_key):
58
58
  """Generate the websocket URI"""
@@ -75,16 +75,18 @@ class SwidgetWebsocket:
75
75
  try:
76
76
  self._client = await self.session.ws_connect(url=self.uri, headers=self.headers, verify_ssl=self._verify_ssl, heartbeat=30)
77
77
  _LOGGER.debug("Websocket now connected")
78
- except (
79
- aiohttp.WSServerHandshakeError,
80
- aiohttp.ClientConnectionError,
81
- socket.gaierror,
82
- ) as exception:
83
- msg = (
84
- "Error occurred while communicating with WLED device"
85
- f" on WebSocket at {self.host}"
86
- )
87
- raise(msg)
78
+ except aiohttp.WSServerHandshakeError as handshake_error:
79
+ _LOGGER.error(f"Error occurred during websocket handshake: {handshake_error}")
80
+ raise
81
+ except aiohttp.ClientConnectionError as connection_error:
82
+ _LOGGER.error(f"Error connecting to the websocket server: {connection_error}")
83
+ raise
84
+ except socket.gaierror as gai_error:
85
+ _LOGGER.error(f"Error resolving host: {gai_error}")
86
+ raise
87
+ except Exception as e:
88
+ _LOGGER.error(f"An unexpected error occurred: {e}")
89
+ raise
88
90
  self._receiver_task = asyncio.ensure_future(self.listen())
89
91
 
90
92
  async def close(self) -> None:
File without changes