python-swidget 1.4.4__tar.gz → 1.4.6__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.4.4 → python_swidget-1.4.6}/PKG-INFO +1 -1
- {python_swidget-1.4.4 → python_swidget-1.4.6}/pyproject.toml +1 -1
- {python_swidget-1.4.4 → python_swidget-1.4.6}/swidget/swidgetdevice.py +14 -4
- {python_swidget-1.4.4 → python_swidget-1.4.6}/swidget/websocket.py +15 -4
- {python_swidget-1.4.4 → python_swidget-1.4.6}/README.md +0 -0
- {python_swidget-1.4.4 → python_swidget-1.4.6}/swidget/__init__.py +0 -0
- {python_swidget-1.4.4 → python_swidget-1.4.6}/swidget/cli.py +0 -0
- {python_swidget-1.4.4 → python_swidget-1.4.6}/swidget/discovery.py +0 -0
- {python_swidget-1.4.4 → python_swidget-1.4.6}/swidget/exceptions.py +0 -0
- {python_swidget-1.4.4 → python_swidget-1.4.6}/swidget/provision.py +0 -0
- {python_swidget-1.4.4 → python_swidget-1.4.6}/swidget/py.typed +0 -0
- {python_swidget-1.4.4 → python_swidget-1.4.6}/swidget/swidgetdimmer.py +0 -0
- {python_swidget-1.4.4 → python_swidget-1.4.6}/swidget/swidgetoutlet.py +0 -0
- {python_swidget-1.4.4 → python_swidget-1.4.6}/swidget/swidgetswitch.py +0 -0
- {python_swidget-1.4.4 → python_swidget-1.4.6}/swidget/swidgettimerswitch.py +0 -0
|
@@ -249,7 +249,9 @@ class SwidgetDevice:
|
|
|
249
249
|
raise ValueError(f"Unsupported HTTP method: {http_method}")
|
|
250
250
|
|
|
251
251
|
url = f"{self.uri_scheme}://{self.ip_address}/api/v1/{endpoint}"
|
|
252
|
-
_LOGGER.debug(
|
|
252
|
+
_LOGGER.debug(
|
|
253
|
+
f"HTTP {http_method} {url} params={params} body={json_payload}"
|
|
254
|
+
)
|
|
253
255
|
|
|
254
256
|
try:
|
|
255
257
|
async with self._session.request(
|
|
@@ -261,14 +263,22 @@ class SwidgetDevice:
|
|
|
261
263
|
) as response:
|
|
262
264
|
if response.status == 200:
|
|
263
265
|
if response.content_length == 0:
|
|
266
|
+
_LOGGER.debug(
|
|
267
|
+
f"HTTP {response.status} {url} (empty body)"
|
|
268
|
+
)
|
|
264
269
|
return {}
|
|
265
|
-
|
|
270
|
+
body = await response.json()
|
|
271
|
+
_LOGGER.debug(f"HTTP {response.status} {url} body={body}")
|
|
272
|
+
return body
|
|
266
273
|
elif response.status == 403:
|
|
267
274
|
_LOGGER.error(
|
|
268
275
|
f"Authentication failed for {http_method} '{endpoint}'"
|
|
269
276
|
)
|
|
270
277
|
raise SwidgetAuthenticationException
|
|
271
278
|
else:
|
|
279
|
+
_LOGGER.debug(
|
|
280
|
+
f"HTTP {response.status} {url} (non-success)"
|
|
281
|
+
)
|
|
272
282
|
response.raise_for_status()
|
|
273
283
|
return {}
|
|
274
284
|
except ClientConnectorError as e:
|
|
@@ -722,8 +732,8 @@ class SwidgetDevice:
|
|
|
722
732
|
|
|
723
733
|
@property
|
|
724
734
|
def is_outlet(self) -> bool:
|
|
725
|
-
"""Return True if the device is an outlet."""
|
|
726
|
-
return self.device_type
|
|
735
|
+
"""Return True if the device is an outlet (any variant)."""
|
|
736
|
+
return self.device_type in (DeviceType.Outlet, DeviceType.Outlet20A)
|
|
727
737
|
|
|
728
738
|
@property
|
|
729
739
|
def is_switch(self) -> bool:
|
|
@@ -107,7 +107,7 @@ class SwidgetWebsocket:
|
|
|
107
107
|
|
|
108
108
|
async def send_str(self, message: str) -> None:
|
|
109
109
|
"""Send a string message through the websocket with retry attempts."""
|
|
110
|
-
_LOGGER.debug("websocket.send_str
|
|
110
|
+
_LOGGER.debug(f"[{self.host}] websocket.send_str: {message}")
|
|
111
111
|
max_send_retries = 3
|
|
112
112
|
for attempt in range(max_send_retries):
|
|
113
113
|
try:
|
|
@@ -139,13 +139,24 @@ class SwidgetWebsocket:
|
|
|
139
139
|
_LOGGER.debug(f"[{self.host}] Received message: {message_data}")
|
|
140
140
|
return message_data
|
|
141
141
|
elif message.type in (WSMsgType.CLOSED, WSMsgType.CLOSING):
|
|
142
|
-
|
|
142
|
+
# message.data carries the close code (int) when present;
|
|
143
|
+
# message.extra carries the reason string. close_code on
|
|
144
|
+
# the client also reflects the final negotiated code.
|
|
145
|
+
_LOGGER.error(
|
|
146
|
+
f"[{self.host}] Websocket closed "
|
|
147
|
+
f"(type={message.type.name}, "
|
|
148
|
+
f"code={message.data!r}, "
|
|
149
|
+
f"reason={message.extra!r}, "
|
|
150
|
+
f"client.close_code={getattr(self._client, 'close_code', None)!r})"
|
|
151
|
+
)
|
|
143
152
|
self._client = None
|
|
144
153
|
elif message.type == WSMsgType.ERROR:
|
|
145
|
-
_LOGGER.error(
|
|
154
|
+
_LOGGER.error(
|
|
155
|
+
f"[{self.host}] Websocket error: {message.data!r}"
|
|
156
|
+
)
|
|
146
157
|
self._client = None
|
|
147
158
|
except Exception as e:
|
|
148
|
-
_LOGGER.error(f"Error receiving message: {e}")
|
|
159
|
+
_LOGGER.error(f"Error receiving message: {e}", exc_info=True)
|
|
149
160
|
return None
|
|
150
161
|
|
|
151
162
|
async def close(self) -> None:
|
|
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
|
|
File without changes
|
|
File without changes
|