python-swidget 1.0.3__tar.gz → 1.2.1__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.
- {python_swidget-1.0.3 → python_swidget-1.2.1}/PKG-INFO +1 -1
- {python_swidget-1.0.3 → python_swidget-1.2.1}/pyproject.toml +1 -1
- {python_swidget-1.0.3 → python_swidget-1.2.1}/swidget/cli.py +5 -5
- {python_swidget-1.0.3 → python_swidget-1.2.1}/swidget/swidgetdevice.py +98 -12
- {python_swidget-1.0.3 → python_swidget-1.2.1}/swidget/swidgetdimmer.py +6 -3
- {python_swidget-1.0.3 → python_swidget-1.2.1}/swidget/websocket.py +47 -5
- {python_swidget-1.0.3 → python_swidget-1.2.1}/README.md +0 -0
- {python_swidget-1.0.3 → python_swidget-1.2.1}/swidget/__init__.py +0 -0
- {python_swidget-1.0.3 → python_swidget-1.2.1}/swidget/discovery.py +0 -0
- {python_swidget-1.0.3 → python_swidget-1.2.1}/swidget/exceptions.py +0 -0
- {python_swidget-1.0.3 → python_swidget-1.2.1}/swidget/provision.py +0 -0
- {python_swidget-1.0.3 → python_swidget-1.2.1}/swidget/py.typed +0 -0
- {python_swidget-1.0.3 → python_swidget-1.2.1}/swidget/swidgetoutlet.py +0 -0
- {python_swidget-1.0.3 → python_swidget-1.2.1}/swidget/swidgetswitch.py +0 -0
- {python_swidget-1.0.3 → python_swidget-1.2.1}/swidget/swidgettimerswitch.py +0 -0
|
@@ -116,8 +116,8 @@ def join(ssid, network_password, secret_key, friendly_name):
|
|
|
116
116
|
confirmation = click.prompt(f"Are you connected to a wifi network that stars with the name 'Swidget-' (y/n)")
|
|
117
117
|
if confirmation == "y":
|
|
118
118
|
click.echo(f"Asking the device to connect to network {ssid}..")
|
|
119
|
-
# def provision_wifi(ssid, network_password, token_name, secret_key, friendly_name):
|
|
120
119
|
provision_wifi(friendly_name, ssid, network_password, secret_key)
|
|
120
|
+
click.echo(f"Disconnect from the `swidget` network and connect back your main WiFi network")
|
|
121
121
|
return True
|
|
122
122
|
else:
|
|
123
123
|
click.echo("Not provisioning wifi")
|
|
@@ -164,7 +164,7 @@ async def state(dev: SwidgetDevice):
|
|
|
164
164
|
click.echo(f"\tMAC (rssi): {dev.mac_address} ({dev.rssi})")
|
|
165
165
|
|
|
166
166
|
click.echo(click.style("\n\t== Current State ==", bold=True))
|
|
167
|
-
realtime_values =
|
|
167
|
+
realtime_values = dev.realtime_values
|
|
168
168
|
for info_name, info_data in realtime_values.items():
|
|
169
169
|
if isinstance(info_data, list):
|
|
170
170
|
click.echo(f"\t{info_name}:")
|
|
@@ -263,11 +263,11 @@ async def enable_debug_server(dev: SwidgetDevice):
|
|
|
263
263
|
async def check_for_updates(dev: SwidgetDevice):
|
|
264
264
|
click.echo("Contacting Swidget servers to fetch for updates...")
|
|
265
265
|
available_updates = await dev.check_for_updates()
|
|
266
|
-
if len(available_updates
|
|
266
|
+
if len(available_updates) == 0:
|
|
267
267
|
click.echo("No available updates")
|
|
268
268
|
else:
|
|
269
269
|
click.echo("The following versions are available to update to")
|
|
270
|
-
for version in available_updates
|
|
270
|
+
for version in available_updates:
|
|
271
271
|
click.echo(click.style(f"\t+ {version}", fg="green"))
|
|
272
272
|
|
|
273
273
|
|
|
@@ -278,7 +278,7 @@ async def upgrade(dev: SwidgetDevice, version: str):
|
|
|
278
278
|
if version is None:
|
|
279
279
|
click.echo("Contacting Swidget servers to fetch for latest version")
|
|
280
280
|
available_updates = await dev.check_for_updates()
|
|
281
|
-
if len(available_updates
|
|
281
|
+
if len(available_updates) == 0:
|
|
282
282
|
click.echo("No available updates")
|
|
283
283
|
else:
|
|
284
284
|
version = available_updates[-1]
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
3
|
import time
|
|
4
|
+
from types import TracebackType
|
|
4
5
|
|
|
5
6
|
from aiohttp import ClientSession, TCPConnector
|
|
6
|
-
import
|
|
7
|
+
from collections.abc import Callable
|
|
7
8
|
from enum import Enum
|
|
8
9
|
from typing import Any, Dict, List
|
|
9
10
|
|
|
@@ -23,6 +24,36 @@ class DeviceType(Enum):
|
|
|
23
24
|
Unknown = -1
|
|
24
25
|
|
|
25
26
|
|
|
27
|
+
class InsertType(Enum):
|
|
28
|
+
"""Insert type enum."""
|
|
29
|
+
USB = "USB"
|
|
30
|
+
THM = "TEMP HUMI MOTION"
|
|
31
|
+
TH = "TEMP HUMI"
|
|
32
|
+
AQ = "AIR QUALITY"
|
|
33
|
+
GL = "GUIDE LIGHT"
|
|
34
|
+
PO = "POWER OUT"
|
|
35
|
+
Unknown = -1
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class SelfDiagnosticErrorCodes(Enum):
|
|
39
|
+
"""Self-Diagnostic error codes"""
|
|
40
|
+
UNUSED = 0
|
|
41
|
+
AQ = 1
|
|
42
|
+
GUIDELIGHT = 2
|
|
43
|
+
LIGHT_SENSOR = 3
|
|
44
|
+
MOTION = 4
|
|
45
|
+
POWER_OUT = 5
|
|
46
|
+
PRESSURE = 6
|
|
47
|
+
TEMP = 7
|
|
48
|
+
USB = 8
|
|
49
|
+
VIBRATION = 9
|
|
50
|
+
VIDEO = 10
|
|
51
|
+
ADVANCED_GL = 11
|
|
52
|
+
HUMI = 12
|
|
53
|
+
CO2 = 13
|
|
54
|
+
PART_MATTER = 14
|
|
55
|
+
|
|
56
|
+
|
|
26
57
|
class SwidgetDevice:
|
|
27
58
|
def __init__(self, host, token_name, secret_key, use_https=True, use_websockets=True) -> None:
|
|
28
59
|
self.token_name = token_name
|
|
@@ -34,6 +65,7 @@ class SwidgetDevice:
|
|
|
34
65
|
self.device_type = DeviceType.Unknown
|
|
35
66
|
self._friendly_name = "Unknown Swidget Device"
|
|
36
67
|
self.assemblies: Dict[Any, Any] = dict()
|
|
68
|
+
self._subscribers: List[Any] = list()
|
|
37
69
|
headers = {self.token_name: self.secret_key,
|
|
38
70
|
'Connection': 'keep-alive'}
|
|
39
71
|
connector = TCPConnector(verify_ssl=False, force_close=True)
|
|
@@ -47,6 +79,10 @@ class SwidgetDevice:
|
|
|
47
79
|
callback=self.message_callback,
|
|
48
80
|
session=self._session)
|
|
49
81
|
|
|
82
|
+
@property
|
|
83
|
+
def connected(self) -> bool:
|
|
84
|
+
return self._websocket.connected
|
|
85
|
+
|
|
50
86
|
def get_websocket(self) -> SwidgetWebsocket | None:
|
|
51
87
|
if self.use_websockets:
|
|
52
88
|
return self._websocket
|
|
@@ -77,6 +113,23 @@ class SwidgetDevice:
|
|
|
77
113
|
async def close(self) -> None:
|
|
78
114
|
await self.stop()
|
|
79
115
|
|
|
116
|
+
async def disconnect(self) -> None:
|
|
117
|
+
await self.stop()
|
|
118
|
+
|
|
119
|
+
def add_event_callback(self, callback: Callable[[Dict, Any], None],) -> bool:
|
|
120
|
+
for c in self._subscribers:
|
|
121
|
+
if c == callback:
|
|
122
|
+
_LOGGER.warn(f"Callback has already been added, not adding the same callback function again")
|
|
123
|
+
return False
|
|
124
|
+
self._subscribers.append(callback)
|
|
125
|
+
return True
|
|
126
|
+
|
|
127
|
+
def remove_event_callback(self, callback: Callable[[Dict, Any], None],) -> bool:
|
|
128
|
+
if callback in self._subscribers:
|
|
129
|
+
self._subscribers.remove(callback)
|
|
130
|
+
return True
|
|
131
|
+
return False
|
|
132
|
+
|
|
80
133
|
async def message_callback(self, message) -> None:
|
|
81
134
|
"""Entrypoint for a websocket callback"""
|
|
82
135
|
_LOGGER.debug("SwidgetDevice.message_callback() called")
|
|
@@ -88,6 +141,12 @@ class SwidgetDevice:
|
|
|
88
141
|
await self.process_state(message)
|
|
89
142
|
else:
|
|
90
143
|
_LOGGER.error(f"Unknown message type from websocket. Type given was: {message["request_id"]}")
|
|
144
|
+
await self.signal_callbacks(message)
|
|
145
|
+
|
|
146
|
+
async def signal_callbacks(self, message):
|
|
147
|
+
_LOGGER.debug("SwidgetDevice.signal_callsbacks() called")
|
|
148
|
+
for callback in self._subscribers:
|
|
149
|
+
await callback(message)
|
|
91
150
|
|
|
92
151
|
async def get_summary(self) -> None:
|
|
93
152
|
"""Get a summary of the device over HTTP"""
|
|
@@ -213,7 +272,7 @@ class SwidgetDevice:
|
|
|
213
272
|
function_value = state[assembly]["components"][component][function]
|
|
214
273
|
self.assemblies[assembly].components[component].functions[function] = function_value # fmt: skip
|
|
215
274
|
|
|
216
|
-
async def ping(self) ->
|
|
275
|
+
async def ping(self) -> bool:
|
|
217
276
|
"""Ping the device to ensure it's devices
|
|
218
277
|
|
|
219
278
|
:raises SwidgetException: Raise the exception if there we are unable to connect to the Swidget device
|
|
@@ -224,9 +283,11 @@ class SwidgetDevice:
|
|
|
224
283
|
url=f"{self.uri_scheme}://{self.ip_address}/ping",
|
|
225
284
|
ssl=False
|
|
226
285
|
) as response:
|
|
227
|
-
|
|
286
|
+
if response.status == 200:
|
|
287
|
+
return True
|
|
288
|
+
return False
|
|
228
289
|
except:
|
|
229
|
-
|
|
290
|
+
return False
|
|
230
291
|
|
|
231
292
|
async def blink(self) -> Any:
|
|
232
293
|
"""Make the device LED blink
|
|
@@ -254,7 +315,9 @@ class SwidgetDevice:
|
|
|
254
315
|
url=f"{self.uri_scheme}://{self.ip_address}/debug?x-secret-key={self.secret_key}",
|
|
255
316
|
ssl=False
|
|
256
317
|
) as response:
|
|
257
|
-
|
|
318
|
+
if response.status == 200:
|
|
319
|
+
return True
|
|
320
|
+
return False
|
|
258
321
|
except:
|
|
259
322
|
raise SwidgetException
|
|
260
323
|
|
|
@@ -284,7 +347,8 @@ class SwidgetDevice:
|
|
|
284
347
|
url=f"{self.uri_scheme}://{self.ip_address}/api/v1/update",
|
|
285
348
|
ssl=False
|
|
286
349
|
) as response:
|
|
287
|
-
|
|
350
|
+
newer_versions = await response.json()
|
|
351
|
+
return sorted(newer_versions['updates'])
|
|
288
352
|
except:
|
|
289
353
|
raise SwidgetException
|
|
290
354
|
|
|
@@ -298,11 +362,14 @@ class SwidgetDevice:
|
|
|
298
362
|
"version": version
|
|
299
363
|
}
|
|
300
364
|
async with self._session.post(
|
|
301
|
-
url=f"{self.uri_scheme}://{self.ip_address}/api/v1/update",
|
|
365
|
+
url=f"{self.uri_scheme}://{self.ip_address}/api/v1/update/version",
|
|
302
366
|
ssl=False,
|
|
303
367
|
data=json.dumps(data)
|
|
304
368
|
) as response:
|
|
305
|
-
|
|
369
|
+
result = response.status
|
|
370
|
+
if result == 200:
|
|
371
|
+
return True
|
|
372
|
+
return False
|
|
306
373
|
except:
|
|
307
374
|
raise SwidgetException
|
|
308
375
|
|
|
@@ -325,7 +392,7 @@ class SwidgetDevice:
|
|
|
325
392
|
"rssi": self.rssi
|
|
326
393
|
}
|
|
327
394
|
|
|
328
|
-
|
|
395
|
+
def get_child_consumption(self, plug_id=0) -> Any:
|
|
329
396
|
"""Get the power consumption of a plug in watts."""
|
|
330
397
|
if plug_id == "all":
|
|
331
398
|
return_dict = {}
|
|
@@ -337,7 +404,7 @@ class SwidgetDevice:
|
|
|
337
404
|
return return_dict
|
|
338
405
|
return self.assemblies['host'].components[str(plug_id)].functions['power']['current']
|
|
339
406
|
|
|
340
|
-
|
|
407
|
+
def total_consumption(self) -> float:
|
|
341
408
|
"""Get the total power consumption in watts."""
|
|
342
409
|
total_consumption = 0
|
|
343
410
|
for id, properties in self.assemblies['host'].components.items():
|
|
@@ -345,7 +412,7 @@ class SwidgetDevice:
|
|
|
345
412
|
return total_consumption
|
|
346
413
|
|
|
347
414
|
@property
|
|
348
|
-
|
|
415
|
+
def realtime_values(self) -> Dict:
|
|
349
416
|
"""Get a dict of realtime value attributes from the insert and host
|
|
350
417
|
|
|
351
418
|
:return: A dictionary of insert sensor values and power consumption values
|
|
@@ -355,7 +422,7 @@ class SwidgetDevice:
|
|
|
355
422
|
for feature in self.insert_features:
|
|
356
423
|
return_dict.update(self.get_function_values(feature))
|
|
357
424
|
return_dict.update({'rssi': self.rssi})
|
|
358
|
-
power_values =
|
|
425
|
+
power_values =self.get_child_consumption("all")
|
|
359
426
|
if power_values:
|
|
360
427
|
return_dict.update(power_values)
|
|
361
428
|
return return_dict
|
|
@@ -428,6 +495,7 @@ class SwidgetDevice:
|
|
|
428
495
|
@property # type: ignore
|
|
429
496
|
def is_on(self) -> bool:
|
|
430
497
|
"""Return whether device is on."""
|
|
498
|
+
_LOGGER.debug("SwidgetDevice.is_on called")
|
|
431
499
|
dimmer_state = self.assemblies['host'].components["0"].functions['toggle']["state"]
|
|
432
500
|
if dimmer_state == "on":
|
|
433
501
|
return True
|
|
@@ -436,6 +504,7 @@ class SwidgetDevice:
|
|
|
436
504
|
async def turn_on(self) -> None:
|
|
437
505
|
"""Turn the device on."""
|
|
438
506
|
_LOGGER.debug("SwidgetDevice.turn_on() called")
|
|
507
|
+
self.assemblies['host'].components["0"].functions['toggle']["state"] = "on"
|
|
439
508
|
await self.send_command(
|
|
440
509
|
assembly="host", component="0", function="toggle", command={"state": "on"}
|
|
441
510
|
)
|
|
@@ -443,18 +512,23 @@ class SwidgetDevice:
|
|
|
443
512
|
async def turn_off(self) -> None:
|
|
444
513
|
"""Turn the device off."""
|
|
445
514
|
_LOGGER.debug("SwidgetDevice.turn_off() called")
|
|
515
|
+
self.assemblies['host'].components["0"].functions['toggle']["state"] = "off"
|
|
446
516
|
await self.send_command(
|
|
447
517
|
assembly="host", component="0", function="toggle", command={"state": "off"}
|
|
448
518
|
)
|
|
449
519
|
|
|
450
520
|
async def turn_on_usb_insert(self) -> None:
|
|
451
521
|
"""Turn the USB insert on."""
|
|
522
|
+
_LOGGER.debug("SwidgetDevice.turn_on_usb_insert() called")
|
|
523
|
+
self.assemblies['insert'].components["usb"].functions['toggle']["state"] = "on"
|
|
452
524
|
await self.send_command(
|
|
453
525
|
assembly="insert", component="usb", function="toggle", command={"state": "on"}
|
|
454
526
|
)
|
|
455
527
|
|
|
456
528
|
async def turn_off_usb_insert(self) -> None:
|
|
457
529
|
"""Turn the USB insert off."""
|
|
530
|
+
_LOGGER.debug("SwidgetDevice.turn_off_usb_insert() called")
|
|
531
|
+
self.assemblies['insert'].components["usb"].functions['toggle']["state"] = "off"
|
|
458
532
|
await self.send_command(
|
|
459
533
|
assembly="insert", component="usb", function="toggle", command={"state": "off"}
|
|
460
534
|
)
|
|
@@ -462,11 +536,23 @@ class SwidgetDevice:
|
|
|
462
536
|
@property # type: ignore
|
|
463
537
|
def usb_is_on(self) -> bool:
|
|
464
538
|
"""Return whether USB is on."""
|
|
539
|
+
_LOGGER.debug("SwidgetDevice.usb_is_on called")
|
|
465
540
|
usb_state = self.assemblies['insert'].components["usb"].functions['toggle']["state"]
|
|
466
541
|
if usb_state == "on":
|
|
467
542
|
return True
|
|
468
543
|
return False
|
|
469
544
|
|
|
545
|
+
async def __aenter__(self) -> "SwidgetDevice":
|
|
546
|
+
"""Initialize and connect the Swidget Websocket client."""
|
|
547
|
+
await self.connect()
|
|
548
|
+
return self
|
|
549
|
+
|
|
550
|
+
async def __aexit__(
|
|
551
|
+
self, exc_type: Exception, exc_value: str, traceback: TracebackType
|
|
552
|
+
) -> None:
|
|
553
|
+
"""Disconnect from the websocket."""
|
|
554
|
+
await self.disconnect()
|
|
555
|
+
|
|
470
556
|
def __repr__(self) -> str:
|
|
471
557
|
if self._last_update == 0:
|
|
472
558
|
return f"<{self.device_type} at {self.ip_address} - update() needed>"
|
|
@@ -13,7 +13,7 @@ class SwidgetDimmer(SwidgetDevice):
|
|
|
13
13
|
|
|
14
14
|
def __init__(self, host, token_name: str, secret_key: str, use_https: bool, use_websockets: bool) -> None:
|
|
15
15
|
super().__init__(host=host, token_name=token_name, secret_key=secret_key, use_https=use_https, use_websockets=use_websockets)
|
|
16
|
-
self._device_type =
|
|
16
|
+
self._device_type = DeviceType.Dimmer
|
|
17
17
|
|
|
18
18
|
@property # type: ignore
|
|
19
19
|
def brightness(self) -> int:
|
|
@@ -21,6 +21,7 @@ class SwidgetDimmer(SwidgetDevice):
|
|
|
21
21
|
|
|
22
22
|
Will return a range between 0 - 100.
|
|
23
23
|
"""
|
|
24
|
+
_LOGGER.debug("SwidgetDimmer.brightness called")
|
|
24
25
|
if not self.is_dimmable:
|
|
25
26
|
raise SwidgetException("Device is not dimmable.")
|
|
26
27
|
try:
|
|
@@ -30,13 +31,14 @@ class SwidgetDimmer(SwidgetDevice):
|
|
|
30
31
|
|
|
31
32
|
async def set_brightness(self, brightness) -> None:
|
|
32
33
|
"""Set the brightness of the device."""
|
|
33
|
-
_LOGGER.debug("SwidgetDimmer.set_brightness() called")
|
|
34
|
+
_LOGGER.debug("SwidgetDimmer.set_brightness() called with brightness: {brightness}")
|
|
35
|
+
self.assemblies['host'].components["0"].functions["level"]["now"] = brightness
|
|
34
36
|
await self.send_command(
|
|
35
37
|
assembly="host", component="0", function="level", command={"now": brightness}
|
|
36
38
|
)
|
|
37
39
|
|
|
38
40
|
async def set_default_brightness(self, brightness) -> None:
|
|
39
|
-
_LOGGER.debug("SwidgetDimmer.set_default_brightness() called")
|
|
41
|
+
_LOGGER.debug("SwidgetDimmer.set_default_brightness() called with brightness: {brightness}")
|
|
40
42
|
await self.send_command(
|
|
41
43
|
assembly="host", component="0", function="level", command={"default": brightness}
|
|
42
44
|
)
|
|
@@ -44,4 +46,5 @@ class SwidgetDimmer(SwidgetDevice):
|
|
|
44
46
|
@property # type: ignore
|
|
45
47
|
def is_dimmable(self) -> bool:
|
|
46
48
|
"""Whether the switch supports brightness changes."""
|
|
49
|
+
_LOGGER.debug("SwidgetDimmer.is_dimmable() called")
|
|
47
50
|
return True
|
|
@@ -3,6 +3,7 @@ import aiohttp
|
|
|
3
3
|
from aiohttp import ClientWebSocketResponse, WSMsgType
|
|
4
4
|
import logging
|
|
5
5
|
import socket
|
|
6
|
+
from typing import Any
|
|
6
7
|
|
|
7
8
|
_LOGGER = logging.getLogger(__name__)
|
|
8
9
|
|
|
@@ -69,10 +70,14 @@ class SwidgetWebsocket:
|
|
|
69
70
|
_LOGGER.debug("Websocket already connected")
|
|
70
71
|
return
|
|
71
72
|
|
|
73
|
+
if self._client is not None:
|
|
74
|
+
raise ConnectionError("Already connected")
|
|
75
|
+
|
|
72
76
|
if not self.session:
|
|
73
|
-
raise
|
|
77
|
+
raise ConnectionError("No aiohttp session available")
|
|
74
78
|
|
|
75
79
|
try:
|
|
80
|
+
_LOGGER.debug("Trying to connect")
|
|
76
81
|
self._client = await self.session.ws_connect(url=self.uri, headers=self.headers, verify_ssl=self._verify_ssl, heartbeat=30)
|
|
77
82
|
_LOGGER.debug("Websocket now connected")
|
|
78
83
|
except aiohttp.WSServerHandshakeError as handshake_error:
|
|
@@ -91,13 +96,18 @@ class SwidgetWebsocket:
|
|
|
91
96
|
|
|
92
97
|
async def close(self) -> None:
|
|
93
98
|
_LOGGER.debug("websocket.close() called")
|
|
94
|
-
if
|
|
95
|
-
|
|
96
|
-
|
|
99
|
+
if self._client is not None and not self._client.closed:
|
|
100
|
+
await self._client.close()
|
|
101
|
+
self._client = None
|
|
102
|
+
|
|
103
|
+
async def disconnect(self) -> None:
|
|
104
|
+
await self.close()
|
|
97
105
|
|
|
98
106
|
async def send_str(self, message):
|
|
99
107
|
"""Send a message through the websocket."""
|
|
100
108
|
_LOGGER.debug("websocket.send_str() called")
|
|
109
|
+
if not self.connected:
|
|
110
|
+
raise ConnectionError
|
|
101
111
|
message = str(message)
|
|
102
112
|
_LOGGER.debug(f"Sending messsage over websocket: {message}")
|
|
103
113
|
await self._client.send_str(f'{message}')
|
|
@@ -115,6 +125,7 @@ class SwidgetWebsocket:
|
|
|
115
125
|
|
|
116
126
|
if message.type == aiohttp.WSMsgType.TEXT:
|
|
117
127
|
message_data = message.json()
|
|
128
|
+
_LOGGER.debug(f"Received from websocket: {message_data}")
|
|
118
129
|
await self.callback(message_data)
|
|
119
130
|
|
|
120
131
|
if message.type in (
|
|
@@ -122,4 +133,35 @@ class SwidgetWebsocket:
|
|
|
122
133
|
aiohttp.WSMsgType.CLOSED,
|
|
123
134
|
aiohttp.WSMsgType.CLOSING,
|
|
124
135
|
):
|
|
125
|
-
_LOGGER.
|
|
136
|
+
_LOGGER.error("Connection to the Swidget WebSocket on has been closed")
|
|
137
|
+
|
|
138
|
+
async def receive_message_or_raise(self) -> Any:
|
|
139
|
+
"""Receive ONE (raw) message or raise."""
|
|
140
|
+
assert self._client
|
|
141
|
+
ws_msg = await self._client.receive()
|
|
142
|
+
|
|
143
|
+
if ws_msg.type in (WSMsgType.CLOSE, WSMsgType.CLOSED, WSMsgType.CLOSING):
|
|
144
|
+
raise ConnectionError("Connection was closed.")
|
|
145
|
+
|
|
146
|
+
if ws_msg.type == WSMsgType.ERROR:
|
|
147
|
+
raise ConnectionError
|
|
148
|
+
|
|
149
|
+
if ws_msg.type != WSMsgType.TEXT:
|
|
150
|
+
raise ValueError(
|
|
151
|
+
f"Received non-Text message: {ws_msg.type}: {ws_msg.data}"
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
try:
|
|
155
|
+
msg = ws_msg.json()
|
|
156
|
+
except TypeError as err:
|
|
157
|
+
raise TypeError(f"Received unsupported JSON: {err}") from err
|
|
158
|
+
except ValueError as err:
|
|
159
|
+
raise ValueError("Received invalid JSON.") from err
|
|
160
|
+
|
|
161
|
+
_LOGGER.debug(f"Received message:\n{msg}\n")
|
|
162
|
+
return msg
|
|
163
|
+
|
|
164
|
+
def __repr__(self) -> str:
|
|
165
|
+
"""Return the representation."""
|
|
166
|
+
prefix = "" if self.connected else "not "
|
|
167
|
+
return f"{type(self).__name__}(ws_server_url={self.host}, {prefix}connected)"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|