zcc-helper 3.8.1.dev1__tar.gz → 3.9.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 (27) hide show
  1. {zcc_helper-3.8.1.dev1/zcc_helper.egg-info → zcc_helper-3.9.dev1}/PKG-INFO +1 -1
  2. zcc_helper-3.9.dev1/tests/test_controller.py +171 -0
  3. zcc_helper-3.9.dev1/tests/test_manufacture_info.py +35 -0
  4. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/zcc/constants.py +1 -1
  5. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/zcc/controller.py +145 -9
  6. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/zcc/device.py +10 -3
  7. zcc_helper-3.9.dev1/zcc/manufacture_info.py +88 -0
  8. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1/zcc_helper.egg-info}/PKG-INFO +1 -1
  9. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/zcc_helper.egg-info/SOURCES.txt +2 -0
  10. zcc_helper-3.8.1.dev1/zcc/manufacture_info.py +0 -45
  11. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/LICENSE.txt +0 -0
  12. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/README.md +0 -0
  13. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/setup.cfg +0 -0
  14. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/setup.py +0 -0
  15. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/tests/test_device.py +0 -0
  16. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/zcc/__init__.py +0 -0
  17. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/zcc/__main__.py +0 -0
  18. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/zcc/description.py +0 -0
  19. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/zcc/discovery.py +0 -0
  20. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/zcc/errors.py +0 -0
  21. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/zcc/protocol.py +0 -0
  22. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/zcc/socket.py +0 -0
  23. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/zcc/trace.py +0 -0
  24. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/zcc/watchdog.py +0 -0
  25. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/zcc.py +0 -0
  26. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.dev1}/zcc_helper.egg-info/dependency_links.txt +0 -0
  27. {zcc_helper-3.8.1.dev1 → zcc_helper-3.9.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.1.dev1
3
+ Version: 3.9.dev1
4
4
  Summary: ZIMI ZCC helper module
5
5
  Author: Mark Hannon
6
6
  Author-email: mark.hannon@gmail.com
@@ -0,0 +1,171 @@
1
+ import asyncio
2
+ import unittest
3
+
4
+ from zcc.controller import ControlPoint
5
+ from zcc.description import ControlPointDescription
6
+ from zcc.device import ControlPointDevice
7
+ from zcc.manufacture_info import ControlPointManufactureInfo
8
+
9
+
10
+ class ControllerFirmwareTest(unittest.TestCase):
11
+
12
+ def setUp(self):
13
+ self.loop = asyncio.new_event_loop()
14
+ asyncio.set_event_loop(self.loop)
15
+ description = ControlPointDescription(host="127.0.0.1", port=12121)
16
+ self.controller = ControlPoint(description)
17
+
18
+ def tearDown(self):
19
+ self.controller.disconnect()
20
+ self.loop.close()
21
+
22
+ def test_flags_devices_behind_same_model_and_hwversion(self):
23
+ older = self._add_device(
24
+ "old_1",
25
+ ControlPointManufactureInfo(
26
+ identifier="old",
27
+ model="2GV Switch",
28
+ hwVersion="4",
29
+ firmwareVersion="1.20.50",
30
+ ),
31
+ )
32
+ self._add_device(
33
+ "new_1",
34
+ ControlPointManufactureInfo(
35
+ identifier="new",
36
+ model="2GV Switch",
37
+ hwVersion="4",
38
+ firmwareVersion="3.3.4.2",
39
+ ),
40
+ )
41
+
42
+ self.controller._ControlPoint__update_obsolete_firmware()
43
+
44
+ self.assertEqual(
45
+ self.controller.obsolete_firmware,
46
+ {"old_1": "1.20.50 < 3.3.4.2"},
47
+ )
48
+ self.assertEqual(self.controller.obsolete_firmware_devices, [older])
49
+ self.assertEqual(self.controller.obsolete_devices, [older])
50
+
51
+ def test_separates_peer_groups_by_hwversion(self):
52
+ self._add_device(
53
+ "older_1",
54
+ ControlPointManufactureInfo(
55
+ identifier="older",
56
+ model="2GV Switch",
57
+ hwVersion="4",
58
+ firmwareVersion="1.20.50",
59
+ ),
60
+ )
61
+ self._add_device(
62
+ "different_hw_1",
63
+ ControlPointManufactureInfo(
64
+ identifier="different_hw",
65
+ model="2GV Switch",
66
+ hwVersion="5",
67
+ firmwareVersion="9.9.9",
68
+ ),
69
+ )
70
+
71
+ self.controller._ControlPoint__update_obsolete_firmware()
72
+
73
+ self.assertEqual(self.controller.obsolete_firmware, {})
74
+
75
+ def test_flags_missing_manufacture_info(self):
76
+ device = ControlPointDevice(self.controller, "missing_1")
77
+ self.controller.devices[device.identifier] = device
78
+
79
+ self.controller._ControlPoint__update_obsolete_firmware()
80
+
81
+ self.assertEqual(
82
+ self.controller.obsolete_firmware,
83
+ {"missing_1": "missing manufacture_info"},
84
+ )
85
+
86
+ def test_flags_missing_firmware_version(self):
87
+ self._add_device(
88
+ "missing_fw_1",
89
+ ControlPointManufactureInfo(
90
+ identifier="missing_fw",
91
+ model="2GV Switch",
92
+ hwVersion="4",
93
+ firmwareVersion=None,
94
+ ),
95
+ )
96
+
97
+ self.controller._ControlPoint__update_obsolete_firmware()
98
+
99
+ self.assertEqual(
100
+ self.controller.obsolete_firmware,
101
+ {"missing_fw_1": "missing firmwareVersion"},
102
+ )
103
+
104
+ def test_describe_reports_obsolete_firmware_warning(self):
105
+ old_device = self._add_device(
106
+ "old_1",
107
+ ControlPointManufactureInfo(
108
+ identifier="old",
109
+ model="2GV Switch",
110
+ hwVersion="4",
111
+ firmwareVersion="1.20.50",
112
+ ),
113
+ )
114
+ old_device.properties = {"name": "Entry Switch", "roomName": "Hall"}
115
+ self._add_device(
116
+ "new_1",
117
+ ControlPointManufactureInfo(
118
+ identifier="new",
119
+ model="2GV Switch",
120
+ hwVersion="4",
121
+ firmwareVersion="3.3.4.2",
122
+ ),
123
+ )
124
+
125
+ self.controller._ControlPoint__update_obsolete_firmware()
126
+
127
+ description = self.controller.describe()
128
+
129
+ self.assertIn("obsolete firmware", description)
130
+ self.assertIn("fw=1.20.50, fw<3.3.4.2", description)
131
+
132
+ def test_tracks_missing_states_and_reports_inline_marker(self):
133
+ missing_device = self._add_device(
134
+ "missing_1",
135
+ ControlPointManufactureInfo(
136
+ identifier="missing",
137
+ model="2GV Switch",
138
+ hwVersion="4",
139
+ firmwareVersion="3.3.4.2",
140
+ ),
141
+ )
142
+ missing_device.properties = {
143
+ "name": "Entry Dimmer",
144
+ "roomName": "Hall",
145
+ }
146
+
147
+ self.controller._ControlPoint__update_missing_states()
148
+
149
+ self.assertEqual(
150
+ self.controller.missing_states,
151
+ {"missing_1": "missing states"},
152
+ )
153
+ self.assertEqual(self.controller.warnings, [missing_device])
154
+
155
+ description = self.controller.describe()
156
+
157
+ self.assertIn("incomplete data", description)
158
+ self.assertIn("{ MISSING }", description)
159
+
160
+ def _add_device(self, identifier, manufacture_info):
161
+ device = ControlPointDevice(self.controller, identifier)
162
+ device.manufacture_info = manufacture_info
163
+ self.controller.devices[identifier] = device
164
+ self.controller.manufacture_infos[manufacture_info.identifier] = (
165
+ manufacture_info
166
+ )
167
+ return device
168
+
169
+
170
+ if __name__ == '__main__':
171
+ unittest.main()
@@ -0,0 +1,35 @@
1
+ import unittest
2
+
3
+ from zcc.manufacture_info import (
4
+ ControlPointManufactureInfo,
5
+ compare_firmware_versions,
6
+ normalise_firmware_version,
7
+ )
8
+
9
+
10
+ class ManufactureInfoTest(unittest.TestCase):
11
+
12
+ def test_normalise_firmware_version(self):
13
+ self.assertEqual(normalise_firmware_version("2.10.4.2"), (2, 10, 4, 2))
14
+ self.assertIsNone(normalise_firmware_version("invalid"))
15
+
16
+ def test_compare_firmware_versions(self):
17
+ self.assertEqual(compare_firmware_versions("2.10.4.2", "2.14.4.2"), -1)
18
+ self.assertEqual(compare_firmware_versions("1.2", "1.2.0"), 0)
19
+ self.assertEqual(compare_firmware_versions("3.0", "2.9.9"), 1)
20
+
21
+ def test_cohort_key_requires_model_and_hwversion(self):
22
+ manufacture_info = ControlPointManufactureInfo(
23
+ identifier="device",
24
+ model="2GV Switch",
25
+ hwVersion="4",
26
+ firmwareVersion="3.3.4.2",
27
+ )
28
+ self.assertEqual(manufacture_info.cohort_key, ("2GV Switch", "4"))
29
+
30
+ manufacture_info.hwVersion = None
31
+ self.assertIsNone(manufacture_info.cohort_key)
32
+
33
+
34
+ if __name__ == '__main__':
35
+ unittest.main()
@@ -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.8.1dev1"
12
+ VERSION = "3.9dev1"
@@ -23,7 +23,11 @@ from zcc.constants import LEVEL_BY_VERBOSITY, NAME, VERSION
23
23
  from zcc.description import ControlPointDescription
24
24
  from zcc.device import ControlPointDevice
25
25
  from zcc.errors import ControlPointError
26
- from zcc.manufacture_info import ControlPointManufactureInfo
26
+ from zcc.manufacture_info import (
27
+ ControlPointManufactureInfo,
28
+ compare_firmware_versions,
29
+ normalise_firmware_version,
30
+ )
27
31
  from zcc.protocol import ControlPointProtocol
28
32
  from zcc.socket import ControlPointSocket
29
33
  from zcc.watchdog import ControlPointWatchdog
@@ -69,6 +73,9 @@ class ControlPoint:
69
73
 
70
74
  self.devices: Dict[ControlPointDevice] = {}
71
75
  self.manufacture_infos: Dict[ControlPointManufactureInfo] = {}
76
+ self.missing_states: Dict[str, str] = {}
77
+ self.obsolete_firmware: Dict[str, str] = {}
78
+ self.obsolete_firmware_baselines: Dict[tuple[str, str], str] = {}
72
79
 
73
80
  self.actions_received = 0
74
81
  self.manufacture_info_received = 0
@@ -148,7 +155,34 @@ class ControlPoint:
148
155
  @property
149
156
  def warnings(self) -> List[ControlPointDevice]:
150
157
  """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]
158
+
159
+ return [
160
+ self.devices[identifier]
161
+ for identifier in self.missing_states
162
+ if identifier in self.devices
163
+ ]
164
+
165
+ @property
166
+ def missing_state_devices(self) -> List[ControlPointDevice]:
167
+ """Backward-compatible alias for devices flagged with missing states."""
168
+
169
+ return self.warnings
170
+
171
+ @property
172
+ def obsolete_firmware_devices(self) -> List[ControlPointDevice]:
173
+ """Return a list of devices flagged with obsolete firmware."""
174
+
175
+ return [
176
+ self.devices[identifier]
177
+ for identifier in self.obsolete_firmware
178
+ if identifier in self.devices
179
+ ]
180
+
181
+ @property
182
+ def obsolete_devices(self) -> List[ControlPointDevice]:
183
+ """Backward-compatible alias for devices flagged with obsolete firmware."""
184
+
185
+ return self.obsolete_firmware_devices
152
186
 
153
187
  async def connect(self, fast: bool = False) -> bool:
154
188
  """Connect to ZCC, build device table and subscribe to updates"""
@@ -314,13 +348,18 @@ class ControlPoint:
314
348
  description += header + "\n"
315
349
 
316
350
  # 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"
351
+ if self.missing_states:
352
+ description += "| WARNING: One or more devices have missing states. Check for state None below and upgrade firmware with Zimi app |\n"
353
+ description += "+" + "-" * 130 + "+\n"
354
+ if self.obsolete_firmware:
355
+ description += "| WARNING: One or more devices have obsolete firmware. Check for fw<new_version below and upgrade firmware with Zimi app |\n"
319
356
  description += "+" + "-" * 130 + "+\n"
320
357
 
321
358
  description_details = []
322
359
  for key in self.manufacture_infos:
323
- description_details.append(self.manufacture_infos[key].describe())
360
+ description_details.append(
361
+ self.__describe_manufacture_info(self.manufacture_infos[key])
362
+ )
324
363
  for key in self.devices:
325
364
  description_details.append(self.devices[key].describe())
326
365
  description_details.sort()
@@ -427,10 +466,12 @@ class ControlPoint:
427
466
 
428
467
  for key in self.devices.keys():
429
468
  identifier_msb = self.devices[key].identifier.split("_")[0]
430
- if self.manufacture_infos[identifier_msb]:
431
- self.devices[key].manufacture_info = self.manufacture_infos[
432
- identifier_msb
433
- ]
469
+ manufacture_info = self.manufacture_infos.get(identifier_msb)
470
+ if manufacture_info:
471
+ self.devices[key].manufacture_info = manufacture_info
472
+
473
+ self.__update_missing_states()
474
+ self.__update_obsolete_firmware()
434
475
 
435
476
  async def __get_states(self):
436
477
  """Get latest state data from controller and reset watchdog."""
@@ -673,6 +714,8 @@ class ControlPoint:
673
714
  )
674
715
  self.devices[identifier].notify_observers()
675
716
 
717
+ self.__update_missing_states()
718
+
676
719
  if (
677
720
  self.actions_received >= self.num_control_points
678
721
  and not self.actions_ready.done()
@@ -720,6 +763,99 @@ class ControlPoint:
720
763
  ):
721
764
  self.manufacture_info_ready.set_result(True)
722
765
 
766
+ def __update_obsolete_firmware(self):
767
+ """Flag devices that are behind their peer firmware cohort."""
768
+
769
+ self.obsolete_firmware = {}
770
+ self.obsolete_firmware_baselines = {}
771
+
772
+ for manufacture_info in self.manufacture_infos.values():
773
+ cohort_key = manufacture_info.cohort_key
774
+ if cohort_key is None:
775
+ continue
776
+ if normalise_firmware_version(manufacture_info.firmwareVersion) is None:
777
+ continue
778
+
779
+ latest_firmware = self.obsolete_firmware_baselines.get(cohort_key)
780
+ if latest_firmware is None:
781
+ self.obsolete_firmware_baselines[cohort_key] = (
782
+ manufacture_info.firmwareVersion
783
+ )
784
+ continue
785
+
786
+ if (
787
+ compare_firmware_versions(
788
+ manufacture_info.firmwareVersion, latest_firmware
789
+ )
790
+ == 1
791
+ ):
792
+ self.obsolete_firmware_baselines[cohort_key] = (
793
+ manufacture_info.firmwareVersion
794
+ )
795
+
796
+ for identifier, device in self.devices.items():
797
+ reason = self.__get_obsolete_firmware_reason(device)
798
+ if reason:
799
+ self.obsolete_firmware[identifier] = reason
800
+ self.logger.warning(
801
+ "Flagging obsolete firmware for %s: %s", identifier, reason
802
+ )
803
+
804
+ def __get_obsolete_firmware_reason(
805
+ self, device: ControlPointDevice
806
+ ) -> str | None:
807
+ """Return the reason a device is flagged as obsolete."""
808
+
809
+ manufacture_info = getattr(device, "manufacture_info", None)
810
+ if manufacture_info is None:
811
+ return "missing manufacture_info"
812
+ if not manufacture_info.model:
813
+ return "missing model"
814
+ if not manufacture_info.hwVersion:
815
+ return "missing hwVersion"
816
+ if not manufacture_info.firmwareVersion:
817
+ return "missing firmwareVersion"
818
+ if normalise_firmware_version(manufacture_info.firmwareVersion) is None:
819
+ return "invalid firmwareVersion"
820
+
821
+ baseline = self.obsolete_firmware_baselines.get(manufacture_info.cohort_key)
822
+ if baseline is None:
823
+ return "unable to compare firmwareVersion"
824
+
825
+ comparison = compare_firmware_versions(
826
+ manufacture_info.firmwareVersion, baseline
827
+ )
828
+ if comparison is None:
829
+ return "invalid firmwareVersion"
830
+ if comparison < 0:
831
+ return f"{manufacture_info.firmwareVersion} < {baseline}"
832
+
833
+ return None
834
+
835
+ def __describe_manufacture_info(
836
+ self, manufacture_info: ControlPointManufactureInfo
837
+ ) -> str:
838
+ """Render manufacture info, annotating obsolete firmware entries."""
839
+
840
+ description = manufacture_info.describe().rstrip("\n")
841
+ newer_firmware = self.obsolete_firmware_baselines.get(manufacture_info.cohort_key)
842
+ if newer_firmware and any(
843
+ device.identifier.split("_")[0] == manufacture_info.identifier
844
+ for device in self.obsolete_firmware_devices
845
+ ):
846
+ description = description.replace(
847
+ " )", f", fw<{newer_firmware} )"
848
+ )
849
+ return description + "\n"
850
+
851
+ def __update_missing_states(self):
852
+ """Track devices that do not yet have usable state payloads."""
853
+
854
+ self.missing_states = {}
855
+ for identifier, device in self.devices.items():
856
+ if not device.states:
857
+ self.missing_states[identifier] = "missing states"
858
+
723
859
  def __update_properties(self, properties):
724
860
  """Updates zcc gateway properties"""
725
861
 
@@ -78,9 +78,9 @@ class ControlPointDevice:
78
78
  if fan_speed:
79
79
  description += "/" + str(fan_speed)
80
80
  except IndexError:
81
- description = "WARNING"
81
+ description = "None"
82
82
  except KeyError:
83
- description = "WARNING"
83
+ description = "None"
84
84
  return description
85
85
 
86
86
  @property
@@ -115,12 +115,19 @@ class ControlPointDevice:
115
115
 
116
116
  def describe(self) -> str:
117
117
  """Returns a description of a device"""
118
+ actions = self.__actions
119
+ if self.controller and self.identifier in self.controller.missing_states:
120
+ if actions.endswith("}"):
121
+ actions = actions[:-1] + " MISSING }"
122
+ else:
123
+ actions = "{ MISSING }"
124
+
118
125
  return "%-40s %-38.38s %-8.8s %-8s %s\n" % (
119
126
  self.identifier,
120
127
  self.location,
121
128
  self.type,
122
129
  self.__states,
123
- self.__actions,
130
+ actions,
124
131
  )
125
132
 
126
133
  @property
@@ -0,0 +1,88 @@
1
+ """ControlPointManufactureInfo Class."""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Tuple
5
+
6
+
7
+ def normalise_firmware_version(version: str) -> Tuple[int, ...] | None:
8
+ """Convert a dotted firmware version string to a comparable tuple."""
9
+
10
+ if not version:
11
+ return None
12
+
13
+ try:
14
+ return tuple(int(part) for part in version.split("."))
15
+ except (AttributeError, TypeError, ValueError):
16
+ return None
17
+
18
+
19
+ def compare_firmware_versions(current: str, other: str) -> int | None:
20
+ """Compare two dotted firmware versions."""
21
+
22
+ current_version = normalise_firmware_version(current)
23
+ other_version = normalise_firmware_version(other)
24
+
25
+ if current_version is None or other_version is None:
26
+ return None
27
+
28
+ max_length = max(len(current_version), len(other_version))
29
+ current_version += (0,) * (max_length - len(current_version))
30
+ other_version += (0,) * (max_length - len(other_version))
31
+
32
+ if current_version < other_version:
33
+ return -1
34
+ if current_version > other_version:
35
+ return 1
36
+
37
+ return 0
38
+
39
+
40
+ @dataclass
41
+ class ControlPointManufactureInfo:
42
+ """Data class to store ControlPoint manufacture_info."""
43
+
44
+ identifier: str = None
45
+ manufacturer: str = None
46
+ model: str = None
47
+ hwVersion: str = None
48
+ firmwareVersion: str = None
49
+
50
+ @property
51
+ def cohort_key(self) -> Tuple[str, str] | None:
52
+ """Return the comparison cohort for peer firmware checks."""
53
+
54
+ if not self.model or not self.hwVersion:
55
+ return None
56
+
57
+ return (self.model, self.hwVersion)
58
+
59
+ def describe(self) -> str:
60
+ """Returns a description of a device"""
61
+ return "%-40s %-40.40s %-8.8s %s\n" % (
62
+ self.identifier,
63
+ f"{self.model} ({self.name})",
64
+ "device",
65
+ f"( hw={self.hwVersion}, fw={self.firmwareVersion} )",
66
+ )
67
+
68
+ @property
69
+ def name(self) -> str:
70
+ """Returns simplified name of the device."""
71
+
72
+ if not self.model:
73
+ return "N/A"
74
+
75
+ if "Blind" in self.model:
76
+ return "Cover"
77
+ if "Fan" in self.model:
78
+ return "Fan"
79
+ if "Garage" in self.model:
80
+ return "Garage"
81
+ if "Door" in self.model:
82
+ return "Cover"
83
+ if "GPO" in self.model:
84
+ return "Outlet"
85
+ if "Switch" in self.model:
86
+ return "Switch"
87
+
88
+ return self.model
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zcc_helper
3
- Version: 3.8.1.dev1
3
+ Version: 3.9.dev1
4
4
  Summary: ZIMI ZCC helper module
5
5
  Author: Mark Hannon
6
6
  Author-email: mark.hannon@gmail.com
@@ -2,7 +2,9 @@ LICENSE.txt
2
2
  README.md
3
3
  setup.py
4
4
  zcc.py
5
+ tests/test_controller.py
5
6
  tests/test_device.py
7
+ tests/test_manufacture_info.py
6
8
  zcc/__init__.py
7
9
  zcc/__main__.py
8
10
  zcc/constants.py
@@ -1,45 +0,0 @@
1
- """ControlPointManufactureInfo Class."""
2
-
3
- from dataclasses import dataclass
4
-
5
-
6
- @dataclass
7
- class ControlPointManufactureInfo:
8
- """Data class to store ControlPoint manufacture_info."""
9
-
10
- identifier: str = None
11
- manufacturer: str = None
12
- model: str = None
13
- hwVersion: str = None
14
- firmwareVersion: str = None
15
-
16
- def describe(self) -> str:
17
- """Returns a description of a device"""
18
- return "%-40s %-40.40s %-8.8s %s\n" % (
19
- self.identifier,
20
- f"{self.model} ({self.name})",
21
- "device",
22
- f"( hw={self.hwVersion}, fw={self.firmwareVersion} )",
23
- )
24
-
25
- @property
26
- def name(self) -> str:
27
- """Returns simplified name of the device."""
28
-
29
- if not self.model:
30
- return "N/A"
31
-
32
- if "Blind" in self.model:
33
- return "Cover"
34
- if "Fan" in self.model:
35
- return "Fan"
36
- if "Garage" in self.model:
37
- return "Garage"
38
- if "Door" in self.model:
39
- return "Cover"
40
- if "GPO" in self.model:
41
- return "Outlet"
42
- if "Switch" in self.model:
43
- return "Switch"
44
-
45
- return self.model
File without changes
File without changes
File without changes
File without changes