proconip 2.3.0__tar.gz → 2.3.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,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.3.1](https://github.com/ylabonte/proconip-pypi/compare/v2.3.0...v2.3.1) (2026-10-12)
4
+
5
+
6
+ ### Documentation
7
+
8
+ * confirm electrolysis bit polarity and document manual-dosage units/limits ([#102](https://github.com/ylabonte/proconip-pypi/issues/102)) ([cb44a11](https://github.com/ylabonte/proconip-pypi/commit/cb44a11336fc73bc9715f9ec12ecffeec8b8d16f))
9
+
3
10
  ## [2.3.0](https://github.com/ylabonte/proconip-pypi/compare/v2.2.1...v2.3.0) (2026-10-12)
4
11
 
5
12
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: proconip
3
- Version: 2.3.0
3
+ Version: 2.3.1
4
4
  Summary: Async Python library for interacting with the ProCon.IP pool controller.
5
5
  Project-URL: Homepage, https://github.com/ylabonte/proconip-pypi
6
6
  Project-URL: Documentation, https://ylabonte.github.io/proconip-pypi/
@@ -165,6 +165,10 @@ asyncio.run(relay_switching_example())
165
165
 
166
166
  Manual dosage depends on the same factors as if started from the web interface
167
167
  of the pool control itself.
168
+ Durations are always in seconds. The controller's web interface allows up to
169
+ 59:59 (3599 s) for liquid dosing and up to 23:59 hours (86340 s, whole minutes)
170
+ for chlorine when a salt electrolysis cell is configured; the library passes
171
+ the value through unchecked.
168
172
 
169
173
  ```python
170
174
  import asyncio
@@ -176,7 +180,7 @@ async def manual_dosage_example():
176
180
  client_session = aiohttp.ClientSession()
177
181
  config = ConfigObject("http://192.168.2.3", "admin", "admin")
178
182
  dosage_control = DosageControl(client_session, config)
179
- await dosage_control.async_chlorine_dosage(3600) # start for 1 hour
183
+ await dosage_control.async_chlorine_dosage(600) # start for 10 minutes
180
184
  await dosage_control.async_ph_minus_dosage(60) # start for 1 minute
181
185
  await client_session.close()
182
186
 
@@ -137,6 +137,10 @@ asyncio.run(relay_switching_example())
137
137
 
138
138
  Manual dosage depends on the same factors as if started from the web interface
139
139
  of the pool control itself.
140
+ Durations are always in seconds. The controller's web interface allows up to
141
+ 59:59 (3599 s) for liquid dosing and up to 23:59 hours (86340 s, whole minutes)
142
+ for chlorine when a salt electrolysis cell is configured; the library passes
143
+ the value through unchecked.
140
144
 
141
145
  ```python
142
146
  import asyncio
@@ -148,7 +152,7 @@ async def manual_dosage_example():
148
152
  client_session = aiohttp.ClientSession()
149
153
  config = ConfigObject("http://192.168.2.3", "admin", "admin")
150
154
  dosage_control = DosageControl(client_session, config)
151
- await dosage_control.async_chlorine_dosage(3600) # start for 1 hour
155
+ await dosage_control.async_chlorine_dosage(600) # start for 10 minutes
152
156
  await dosage_control.async_ph_minus_dosage(60) # start for 1 minute
153
157
  await client_session.close()
154
158
 
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '2.3.0'
22
- __version_tuple__ = version_tuple = (2, 3, 0)
21
+ __version__ = version = '2.3.1'
22
+ __version_tuple__ = version_tuple = (2, 3, 1)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -595,18 +595,37 @@ async def async_start_dosage(
595
595
  """Trigger a manual, time-limited dosage on the controller.
596
596
 
597
597
  Manual dosage is the safe alternative to switching a dosage relay on
598
- directly: the controller still applies the same interlocks it uses for the
599
- web UI (canister level, dosage enabled in config, redox/pH thresholds, …).
600
- If those checks fail, the controller silently no-ops while still returning
601
- HTTP 200 — there is no "dosage refused" error in the protocol.
598
+ directly: it goes through the controller's own dosage logic, which the
599
+ TRM ties to preconditions such as the dosage channel being enabled and
600
+ the assigned filter pump running (a running dosage also stops when the
601
+ filter pump switches off). The TRM's daily maximum dosing amount may also
602
+ stop it: once the channel's daily amount is reached, the controller does
603
+ not dose any further. The protocol has no "dosage refused" response,
604
+ so a successful HTTP exchange does not prove that dosing started; check
605
+ the dosage relay state in `/GetState.csv` if you need to know.
606
+
607
+ The duration is always sent in seconds, as the controller's web UI does
608
+ (``/Command.htm?MAN_DOSAGE=<target>,<seconds>``). That UI limits the
609
+ input to ``mm:ss`` up to 59:59 (3599 s) for liquid dosing (chlorine,
610
+ pH-, pH+) and to ``hh:mm`` up to 23:59 (86340 s, whole minutes) for
611
+ chlorine when a salt electrolysis cell is configured (see
612
+ `GetStateData.is_electrolysis_enabled`). This function passes the value
613
+ through unchecked; how the controller treats values outside those
614
+ limits is not documented.
615
+
616
+ The web UI also stores the duration as the channel's default before it
617
+ sends the command: it rewrites ``MDOSTIME`` in the channel's ``.ini``
618
+ (``usr/rdxcntrl.ini``, ``usr/phcntrl.ini`` or ``usr/phpcntrl.ini``) via
619
+ ``/usrcfg.cgi`` and pre-fills that value next time. This function sends
620
+ only the command and leaves that default untouched.
602
621
 
603
622
  Args:
604
623
  client_session: An open `aiohttp.ClientSession`.
605
624
  config: Controller configuration.
606
625
  dosage_target: Which dosing pump to engage (chlorine, pH-, or pH+).
607
- dosage_duration: Run time in **seconds**. Allowed range depends on the
608
- controller's own dosage configuration; values that exceed the
609
- configured maximum are typically clamped silently by the device.
626
+ dosage_duration: Run time in **seconds**, in both liquid and
627
+ electrolysis mode. The web UI allows 0–3599 s for liquid dosing
628
+ and 0–86340 s (whole minutes) for chlorine electrolysis.
610
629
  timeout: Per-request timeout in seconds.
611
630
 
612
631
  Returns:
@@ -662,10 +681,12 @@ class DosageControl:
662
681
  async def async_chlorine_dosage(
663
682
  self, dosage_duration: int, timeout: float | None = None
664
683
  ) -> str:
665
- """Run the chlorine dosage pump for ``dosage_duration`` seconds.
684
+ """Run the chlorine dosage pump (or electrolysis cell) for ``dosage_duration`` seconds.
666
685
 
667
686
  Args:
668
- dosage_duration: Run time in seconds.
687
+ dosage_duration: Run time in seconds. The controller's web UI
688
+ allows up to 3599 s for liquid chlorine and up to 86340 s
689
+ (whole minutes) for a salt electrolysis cell.
669
690
  timeout: Override for this call only. If ``None``, the timeout
670
691
  bound in `__init__` is used.
671
692
 
@@ -687,7 +708,8 @@ class DosageControl:
687
708
  """Run the pH- dosage pump for ``dosage_duration`` seconds.
688
709
 
689
710
  Args:
690
- dosage_duration: Run time in seconds.
711
+ dosage_duration: Run time in seconds. The controller's web UI
712
+ allows up to 3599 s (59:59).
691
713
  timeout: Override for this call only. If ``None``, the timeout
692
714
  bound in `__init__` is used.
693
715
 
@@ -707,7 +729,8 @@ class DosageControl:
707
729
  """Run the pH+ dosage pump for ``dosage_duration`` seconds.
708
730
 
709
731
  Args:
710
- dosage_duration: Run time in seconds.
732
+ dosage_duration: Run time in seconds. The controller's web UI
733
+ allows up to 3599 s (59:59).
711
734
  timeout: Override for this call only. If ``None``, the timeout
712
735
  bound in `__init__` is used.
713
736
 
@@ -632,14 +632,13 @@ class GetStateData:
632
632
  production. Use `is_electrolysis_object` to tell those two objects
633
633
  apart from real canister readings.
634
634
 
635
- Polarity evidence: the TRM labels bit 4 "Cl liquid || Elektrolysis",
636
- naming both options without saying which value is which. A live
637
- firmware 1.7.6 controller configured for liquid chlorine
638
- (``rdxcntrl.ini`` ``DTYPE=0``, chlorine dosing on) reports
639
- DOSAGE_CNTRL 257 (bits 0 and 8, bit 4 clear), as does the real capture
640
- in the test fixtures. So bit 4 is the chlorine device-type selector,
641
- and set = electrolysis is inferred, not observed; a real electrolysis
642
- capture is still pending.
635
+ Polarity: the TRM labels bit 4 "Cl liquid || Elektrolysis" without
636
+ saying which value is which. The controller's own web UI settles it
637
+ (``topleft.htm``, firmware 1.7.6): it decodes
638
+ ``rdx_canister_salt = (dos_cntr >> 4) & 0x01`` and shows
639
+ ``"Flüssig NaClO"`` for 0 and ``"Salz Elektrolyse"`` for 1. A live
640
+ liquid-chlorine controller (``rdxcntrl.ini`` ``DTYPE=0``) reports
641
+ DOSAGE_CNTRL 257 with bit 4 clear, consistent with that.
643
642
  """
644
643
  return self._dosage_control & 16 == 16
645
644
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes