pycomap 2.1.0__tar.gz → 2.1.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pycomap
3
- Version: 2.1.0
3
+ Version: 2.1.1
4
4
  Summary: Async Python client for ComAp controllers: LAN discovery and the native ECDH/AES-encrypted control protocol
5
5
  Author: Igor Panteleyev
6
6
  Author-email: Igor Panteleyev <panteleev.igor69@gmail.com>
@@ -50,7 +50,7 @@ async with Controller(
50
50
  await ctrl.set_setpoint("Summer Time Mode", "Winter") # STRING_LIST by label
51
51
  ```
52
52
 
53
- See the [API docs](https://igor-panteleev.github.io/pycomap/) for full reference. `just docs-serve` to browse locally.
53
+ See the [API docs](https://igor-panteleev.github.io/pycomap/) for full reference, built with [Zensical](https://zensical.org/). `just docs-serve` to browse locally.
54
54
 
55
55
  ## Development
56
56
 
@@ -23,7 +23,7 @@ async with Controller(
23
23
  await ctrl.set_setpoint("Summer Time Mode", "Winter") # STRING_LIST by label
24
24
  ```
25
25
 
26
- See the [API docs](https://igor-panteleev.github.io/pycomap/) for full reference. `just docs-serve` to browse locally.
26
+ See the [API docs](https://igor-panteleev.github.io/pycomap/) for full reference, built with [Zensical](https://zensical.org/). `just docs-serve` to browse locally.
27
27
 
28
28
  ## Development
29
29
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pycomap"
3
- version = "2.1.0"
3
+ version = "2.1.1"
4
4
  description = "Async Python client for ComAp controllers: LAN discovery and the native ECDH/AES-encrypted control protocol"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -38,10 +38,11 @@ build-backend = "uv_build"
38
38
 
39
39
  [dependency-groups]
40
40
  dev = [
41
+ "configargparse>=1.7.5",
41
42
  "ifaddr>=0.2.0",
42
- "mkdocs>=1.6,<2",
43
- "mkdocs-material>=9.5",
44
- "mkdocstrings[python]>=0.25",
43
+ "python-dotenv>=1.2.2",
44
+ "zensical>=0.0.50",
45
+ "mkdocstrings-python>=1.0",
45
46
  "pre-commit>=4.6.0",
46
47
  "pytest>=8",
47
48
  "pytest-asyncio>=0.24",
@@ -319,6 +319,51 @@ class Controller[TransportT: Transport]:
319
319
  except KeyError:
320
320
  raise KeyError(f"no setpoint named {name_or_number!r}") from None
321
321
 
322
+ def _string_list_options(
323
+ self, desc: ValueDescription | SetpointDescription
324
+ ) -> list[tuple[int, str]]:
325
+ """Shared ``STRING_LIST`` option lookup for
326
+ [value_options][pycomap.Controller.value_options] and
327
+ [setpoint_options][pycomap.Controller.setpoint_options].
328
+
329
+ Options are stored in ``CommonNames`` at indices ``[low_limit .. high_limit]``.
330
+ """
331
+ if desc.data_type is not DataType.STRING_LIST:
332
+ raise ComApProtocolError(
333
+ f"{desc.name!r} is DataType.{desc.data_type.name}, not STRING_LIST"
334
+ )
335
+ return [
336
+ (wire_value, self._common_names[desc.low_limit + wire_value])
337
+ for wire_value in range(desc.high_limit - desc.low_limit + 1)
338
+ if desc.low_limit + wire_value < len(self._common_names)
339
+ ]
340
+
341
+ def value_options(self, name_or_number: str | int) -> list[tuple[int, str]]:
342
+ """Return the available options for a ``STRING_LIST`` value.
343
+
344
+ Options are stored in ``CommonNames`` at indices ``[low_limit .. high_limit]``.
345
+ The wire value (0-based) is what the controller sends on the wire and what
346
+ [value_label][pycomap.Controller.value_label] expects; the label is the string
347
+ shown on the front panel and in InteliConfig. Note that
348
+ [read_values][pycomap.Controller.read_values] resolves ``STRING_LIST`` values to
349
+ their label automatically — this method is for enumerating all possible options
350
+ up front (e.g. to build a legend or validate against known states).
351
+
352
+ Args:
353
+ name_or_number: Value name or comm object number.
354
+
355
+ Returns:
356
+ ``[(wire_value, label), ...]`` ordered by wire value.
357
+
358
+ Raises:
359
+ ComApProtocolError: If the value is not ``STRING_LIST`` type.
360
+
361
+ Examples:
362
+ >>> ctrl.value_options("Engine State")
363
+ [(0, 'Ready'), (1, 'Prestart'), (2, 'Cranking'), ...]
364
+ """
365
+ return self._string_list_options(self.value_info(name_or_number))
366
+
322
367
  def setpoint_options(self, name_or_number: str | int) -> list[tuple[int, str]]:
323
368
  """Return the available options for a ``STRING_LIST`` setpoint.
324
369
 
@@ -340,16 +385,7 @@ class Controller[TransportT: Transport]:
340
385
  >>> ctrl.setpoint_options("Summer Time Mode")
341
386
  [(0, 'Disabled'), (1, 'Winter'), (2, 'Summer'), (3, 'Winter-S'), (4, 'Summer-S')]
342
387
  """
343
- desc = self.setpoint_info(name_or_number)
344
- if desc.data_type is not DataType.STRING_LIST:
345
- raise ComApProtocolError(
346
- f"setpoint {desc.name!r} is DataType.{desc.data_type.name}, not STRING_LIST"
347
- )
348
- return [
349
- (wire_value, self._common_names[desc.low_limit + wire_value])
350
- for wire_value in range(desc.high_limit - desc.low_limit + 1)
351
- if desc.low_limit + wire_value < len(self._common_names)
352
- ]
388
+ return self._string_list_options(self.setpoint_info(name_or_number))
353
389
 
354
390
  def value_label(self, name_or_number: str | int, wire_value: int) -> str:
355
391
  """Return the display label for a ``STRING_LIST`` value's wire integer.
File without changes
File without changes
File without changes
File without changes