zcc-helper 3.8.dev1__tar.gz → 3.8.1.dev1__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.
Files changed (24) hide show
  1. {zcc_helper-3.8.dev1/zcc_helper.egg-info → zcc_helper-3.8.1.dev1}/PKG-INFO +1 -1
  2. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc/constants.py +1 -1
  3. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc/controller.py +38 -14
  4. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc/device.py +4 -2
  5. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc/protocol.py +1 -0
  6. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc/watchdog.py +10 -9
  7. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1/zcc_helper.egg-info}/PKG-INFO +1 -1
  8. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/LICENSE.txt +0 -0
  9. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/README.md +0 -0
  10. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/setup.cfg +0 -0
  11. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/setup.py +0 -0
  12. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/tests/test_device.py +0 -0
  13. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc/__init__.py +0 -0
  14. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc/__main__.py +0 -0
  15. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc/description.py +0 -0
  16. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc/discovery.py +0 -0
  17. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc/errors.py +0 -0
  18. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc/manufacture_info.py +0 -0
  19. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc/socket.py +0 -0
  20. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc/trace.py +0 -0
  21. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc.py +0 -0
  22. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc_helper.egg-info/SOURCES.txt +0 -0
  23. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc_helper.egg-info/dependency_links.txt +0 -0
  24. {zcc_helper-3.8.dev1 → zcc_helper-3.8.1.dev1}/zcc_helper.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zcc_helper
3
- Version: 3.8.dev1
3
+ Version: 3.8.1.dev1
4
4
  Summary: ZIMI ZCC helper module
5
5
  Author: Mark Hannon
6
6
  Author-email: mark.hannon@gmail.com
@@ -9,4 +9,4 @@ APP_ID = "ZvWqWJQB"
9
9
  APP_TOKEN = "3422ecbb-cf6a-404c-b3dc-2023dd213535"
10
10
 
11
11
  NAME = "zcc_helper"
12
- VERSION = "3.8dev1"
12
+ VERSION = "3.8.1dev1"
@@ -5,12 +5,18 @@
5
5
  from __future__ import annotations
6
6
 
7
7
  import asyncio
8
- import datetime
9
8
  import logging
10
9
  import socket
11
10
  import time
12
11
  import uuid
13
12
  from pprint import pformat
13
+
14
+ # Set to True to ignore missing device states during initial fetch
15
+ IGNORE_MISSING_STATES = True
16
+
17
+ # Set to True to ignore missing manufacture_info during initial fetch (e.g. for older firmware versions)
18
+ IGNORE_MISSING_MANUFACTURE_INFO = True
19
+
14
20
  from typing import Dict, List
15
21
 
16
22
  from zcc.constants import LEVEL_BY_VERBOSITY, NAME, VERSION
@@ -139,6 +145,11 @@ class ControlPoint:
139
145
  filter(lambda device: device.type == "garagedoor", self.devices.values())
140
146
  )
141
147
 
148
+ @property
149
+ def warnings(self) -> List[ControlPointDevice]:
150
+ """Return a list of devices with empty or missing states (incomplete data)."""
151
+ return [device for device in self.devices.values() if not device.states]
152
+
142
153
  async def connect(self, fast: bool = False) -> bool:
143
154
  """Connect to ZCC, build device table and subscribe to updates"""
144
155
  self.logger.info("Connecting to ZCC %s:%d", self.host, self.port)
@@ -264,7 +275,7 @@ class ControlPoint:
264
275
  self.disconnect()
265
276
 
266
277
  def describe(self) -> str:
267
- """Return a string representation of ZCC including devices"""
278
+ """Return a string representation of ZCC including devices and warnings."""
268
279
  header = "+" + "-" * 130 + "+"
269
280
  if self.host:
270
281
  description = header + "\n"
@@ -301,6 +312,12 @@ class ControlPoint:
301
312
  )
302
313
  )
303
314
  description += header + "\n"
315
+
316
+ # Add warnings section if there are devices with incomplete data
317
+ if self.warnings:
318
+ description += "| WARNING: One or more devices have incomplete data. Check for WARNINGS and upgrade firmware with Zimi app |\n"
319
+ description += "+" + "-" * 130 + "+\n"
320
+
304
321
  description_details = []
305
322
  for key in self.manufacture_infos:
306
323
  description_details.append(self.manufacture_infos[key].describe())
@@ -340,12 +357,18 @@ class ControlPoint:
340
357
  try:
341
358
  await asyncio.wait_for(
342
359
  self.manufacture_info_ready,
343
- timeout=ControlPointProtocol.DEVICE_GET_TIMEOUT,
360
+ timeout=ControlPointProtocol.DEVICE_INFO_TIMEOUT,
344
361
  )
345
362
  except asyncio.exceptions.TimeoutError as error:
346
- raise ControlPointError(
347
- "ZCC connection failed - didn't receive manufacture_info."
348
- ) from error
363
+ if IGNORE_MISSING_MANUFACTURE_INFO:
364
+ self.logger.warning(
365
+ "ZCC connection warning - timeout waiting for manufacture_info."
366
+ )
367
+ else:
368
+ raise ControlPointError(
369
+ "ZCC connection failed - didn't receive manufacture_info."
370
+ ) from error
371
+ # ) from error
349
372
 
350
373
  await asyncio.sleep(ControlPointProtocol.STEP_TIMEOUT)
351
374
 
@@ -391,9 +414,14 @@ class ControlPoint:
391
414
  self.states_ready, timeout=ControlPointProtocol.DEVICE_GET_TIMEOUT
392
415
  )
393
416
  except asyncio.exceptions.TimeoutError as error:
394
- raise ControlPointError(
395
- "ZCC connection failed - didn't receive any states."
396
- ) from error
417
+ if IGNORE_MISSING_STATES:
418
+ self.logger.info(
419
+ "ZCC connection warning - timeout waiting for device states."
420
+ )
421
+ else:
422
+ raise ControlPointError(
423
+ "ZCC connection failed - didn't receive any states."
424
+ ) from error
397
425
 
398
426
  await asyncio.sleep(ControlPointProtocol.STEP_TIMEOUT)
399
427
 
@@ -440,11 +468,7 @@ class ControlPoint:
440
468
  await self.re_connect()
441
469
  return
442
470
 
443
- self.logger.debug(
444
- "notify() received at %s:\n%s",
445
- datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
446
- response,
447
- )
471
+ self.logger.debug("notify() received:\n%s", response)
448
472
 
449
473
  if response.get(ControlPointProtocol.AUTH_APP_FAILED, None):
450
474
  self.logger.error("Authorisation failed\n%s", pformat(response))
@@ -64,6 +64,8 @@ class ControlPointDevice:
64
64
  @property
65
65
  def __states(self) -> str:
66
66
  """Gets a descriptive string of the device state"""
67
+ if self.type == "behaviourlink":
68
+ return ""
67
69
  description = ""
68
70
  try:
69
71
  key = list(self.states["controlState"].keys())[0]
@@ -76,9 +78,9 @@ class ControlPointDevice:
76
78
  if fan_speed:
77
79
  description += "/" + str(fan_speed)
78
80
  except IndexError:
79
- pass
81
+ description = "WARNING"
80
82
  except KeyError:
81
- pass
83
+ description = "WARNING"
82
84
  return description
83
85
 
84
86
  @property
@@ -17,6 +17,7 @@ class ControlPointProtocol:
17
17
  START_SESSION_SUCCESS = "start_session_success"
18
18
  START_SESSION_TIMEOUT = 30
19
19
  DEVICE_GET_TIMEOUT = 30
20
+ DEVICE_INFO_TIMEOUT = 120
20
21
  CONTROLPOINT_PROPERTIES = "controlpoint_properties"
21
22
  CONTROLPOINT_STATES = "controlpoint_states"
22
23
  CONTROLPOINT_ACTIONS = "controlpoint_actions"
@@ -1,44 +1,45 @@
1
- """ZCC Watchdog Timer Class"""
1
+ '''ZCC Watchdog Timer Class'''
2
2
 
3
3
  import asyncio
4
4
  import logging
5
5
 
6
6
 
7
7
  class ControlPointWatchdog:
8
- """A class to create a timer with callback."""
8
+ '''A class to create a timer with callback.'''
9
9
 
10
10
  def __init__(self, timeout: int, callback):
11
- self.logger = logging.getLogger("ControlPointWatchdog")
11
+
12
+ self.logger = logging.getLogger('ControlPointWatchdog')
12
13
 
13
14
  self._busy = False
14
15
  self._timeout = timeout
15
16
  self._callback = callback
16
17
  self._task = None
17
- self.logger.debug("Created watchdog timer for %d seconds", self._timeout)
18
+ self.logger.debug(
19
+ "Created watchdog timer for %d seconds", self._timeout)
18
20
 
19
21
  async def _job(self):
20
22
  await asyncio.sleep(self._timeout)
21
- self.logger.debug("Watchdog timer expired after %d seconds", self._timeout)
22
23
  self._busy = True
23
24
  await self._callback()
24
25
  self._busy = False
25
26
 
26
27
  def cancel(self):
27
- """Cancel the timer."""
28
+ '''Cancel the timer.'''
28
29
  if not self._busy:
29
30
  self._task.cancel()
30
31
 
31
32
  def pause(self):
32
- """Pause the timer"""
33
+ '''Pause the timer'''
33
34
  if self._task:
34
35
  self.cancel()
35
36
 
36
37
  def reset(self):
37
- """Reset the timer."""
38
+ '''Reset the timer.'''
38
39
  if self._task:
39
40
  self.cancel()
40
41
  self.start()
41
42
 
42
43
  def start(self):
43
- """Start the timer."""
44
+ '''Start the timer.'''
44
45
  self._task = asyncio.ensure_future(self._job())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zcc_helper
3
- Version: 3.8.dev1
3
+ Version: 3.8.1.dev1
4
4
  Summary: ZIMI ZCC helper module
5
5
  Author: Mark Hannon
6
6
  Author-email: mark.hannon@gmail.com
File without changes
File without changes
File without changes
File without changes