python-izone 1.3.9__tar.gz → 1.3.11__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 (62) hide show
  1. {python_izone-1.3.9 → python_izone-1.3.11}/PKG-INFO +3 -3
  2. python_izone-1.3.11/docs/release-notes/v1.3.10.md +15 -0
  3. python_izone-1.3.11/docs/release-notes/v1.3.11.md +21 -0
  4. python_izone-1.3.11/docs/v2-confirmation.md +71 -0
  5. {python_izone-1.3.9 → python_izone-1.3.11}/pizone/controller.py +342 -35
  6. {python_izone-1.3.9 → python_izone-1.3.11}/pizone/discovery.py +71 -40
  7. python_izone-1.3.11/pizone/types.py +26 -0
  8. python_izone-1.3.11/pizone/v2.py +585 -0
  9. {python_izone-1.3.9 → python_izone-1.3.11}/pizone/version.py +2 -2
  10. {python_izone-1.3.9 → python_izone-1.3.11}/pizone/zone.py +11 -1
  11. {python_izone-1.3.9 → python_izone-1.3.11}/pyproject.toml +1 -1
  12. {python_izone-1.3.9 → python_izone-1.3.11}/scripts/izone_v1_probe.py +11 -10
  13. {python_izone-1.3.9 → python_izone-1.3.11}/tests/conftest.py +36 -0
  14. {python_izone-1.3.9 → python_izone-1.3.11}/tests/http_fakes.py +16 -2
  15. python_izone-1.3.11/tests/test_control_zone.py +66 -0
  16. {python_izone-1.3.9 → python_izone-1.3.11}/tests/test_controller.py +288 -2
  17. {python_izone-1.3.9 → python_izone-1.3.11}/tests/test_discovery_api.py +84 -2
  18. python_izone-1.3.11/tests/test_discovery_close_timeout.py +63 -0
  19. {python_izone-1.3.9 → python_izone-1.3.11}/tests/test_fullstack.py +47 -1
  20. python_izone-1.3.11/tests/test_v2.py +238 -0
  21. python_izone-1.3.11/tests/test_v2_confirmation.py +312 -0
  22. python_izone-1.3.11/tests/test_v2_fan_capability.py +26 -0
  23. python_izone-1.3.11/tests/test_v2_vendor_enums.py +51 -0
  24. python_izone-1.3.11/tests/test_v2_zone_validation.py +125 -0
  25. {python_izone-1.3.9 → python_izone-1.3.11}/tests/test_zone.py +144 -1
  26. python_izone-1.3.11/tests/v2_fixtures.py +145 -0
  27. {python_izone-1.3.9 → python_izone-1.3.11}/uv.lock +44 -44
  28. python_izone-1.3.9/pizone/types.py +0 -11
  29. {python_izone-1.3.9 → python_izone-1.3.11}/.gitattributes +0 -0
  30. {python_izone-1.3.9 → python_izone-1.3.11}/.github/workflows/main.yml +0 -0
  31. {python_izone-1.3.9 → python_izone-1.3.11}/.gitignore +0 -0
  32. {python_izone-1.3.9 → python_izone-1.3.11}/.pre-commit-config.yaml +0 -0
  33. {python_izone-1.3.9 → python_izone-1.3.11}/.python-version +0 -0
  34. {python_izone-1.3.9 → python_izone-1.3.11}/.vscode/.ropeproject/config.py +0 -0
  35. {python_izone-1.3.9 → python_izone-1.3.11}/.vscode/extensions.json +0 -0
  36. {python_izone-1.3.9 → python_izone-1.3.11}/.vscode/launch.json +0 -0
  37. {python_izone-1.3.9 → python_izone-1.3.11}/.vscode/settings.json +0 -0
  38. {python_izone-1.3.9 → python_izone-1.3.11}/README.md +0 -0
  39. {python_izone-1.3.9 → python_izone-1.3.11}/api_docs/AC-DOC-1401-11_iZoneEthernetInterface.pdf +0 -0
  40. {python_izone-1.3.9 → python_izone-1.3.11}/api_docs/iPower_JSON_datastrings_Out.h +0 -0
  41. {python_izone-1.3.9 → python_izone-1.3.11}/api_docs/iZone_JSON_datastrings.h +0 -0
  42. {python_izone-1.3.9 → python_izone-1.3.11}/docs/release-notes/v1.3.4.md +0 -0
  43. {python_izone-1.3.9 → python_izone-1.3.11}/docs/release-notes/v1.3.5.md +0 -0
  44. {python_izone-1.3.9 → python_izone-1.3.11}/docs/release-notes/v1.3.6.md +0 -0
  45. {python_izone-1.3.9 → python_izone-1.3.11}/docs/release-notes/v1.3.7.md +0 -0
  46. {python_izone-1.3.9 → python_izone-1.3.11}/docs/release-notes/v1.3.8.md +0 -0
  47. {python_izone-1.3.9 → python_izone-1.3.11}/docs/release-notes/v1.3.9.md +0 -0
  48. {python_izone-1.3.9 → python_izone-1.3.11}/licence.txt +0 -0
  49. {python_izone-1.3.9 → python_izone-1.3.11}/pizone/__init__.py +0 -0
  50. {python_izone-1.3.9 → python_izone-1.3.11}/pizone/const.py +0 -0
  51. {python_izone-1.3.9 → python_izone-1.3.11}/pizone/exceptions.py +0 -0
  52. {python_izone-1.3.9 → python_izone-1.3.11}/pizone/power.py +0 -0
  53. {python_izone-1.3.9 → python_izone-1.3.11}/pizone/py.typed +0 -0
  54. {python_izone-1.3.9 → python_izone-1.3.11}/scripts/check +0 -0
  55. {python_izone-1.3.9 → python_izone-1.3.11}/scripts/coverage +0 -0
  56. {python_izone-1.3.9 → python_izone-1.3.11}/tests/__init__.py +0 -0
  57. {python_izone-1.3.9 → python_izone-1.3.11}/tests/power_data.py +0 -0
  58. {python_izone-1.3.9 → python_izone-1.3.11}/tests/resources.py +0 -0
  59. {python_izone-1.3.9 → python_izone-1.3.11}/tests/test_discovery.py +0 -0
  60. {python_izone-1.3.9 → python_izone-1.3.11}/tests/test_dump_state.py +0 -0
  61. {python_izone-1.3.9 → python_izone-1.3.11}/tests/test_http.py +0 -0
  62. {python_izone-1.3.9 → python_izone-1.3.11}/tests/test_power.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: python-izone
3
- Version: 1.3.9
3
+ Version: 1.3.11
4
4
  Summary: A python interface to the iZone airconditioner controller
5
5
  Project-URL: Homepage, https://github.com/Swamp-Ig/pizone
6
6
  Author-email: Penny Wood <pypl@ninjateaparty.com>
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.14
15
15
  Classifier: Topic :: Home Automation
16
16
  Classifier: Topic :: System :: Hardware
17
17
  Requires-Python: >=3.14
18
- Requires-Dist: aiohttp>=3.14.1
18
+ Requires-Dist: aiohttp>=3.14.3
19
19
  Requires-Dist: ifaddr>=0.2.0
20
20
  Provides-Extra: test
21
21
  Requires-Dist: pytest-aio; extra == 'test'
@@ -0,0 +1,15 @@
1
+ # Release notes — v1.3.10
2
+
3
+ **Compare range:** https://github.com/Swamp-Ig/pizone/compare/v1.3.9...v1.3.10
4
+
5
+ ## Since v1.3.9
6
+
7
+ ### Control setpoint (new)
8
+
9
+ - `Controller.control_setpoint_owner` — the controller, the matching zone, or `None` for who owns the unit target. RAS mode, master with CtrlZone past the configured zone count, or a missing AUTO CTS selects the controller. CONST/OPCL `Temp:0` does not.
10
+ - `Controller.control_setpoint` — that owner's setpoint (°C)
11
+
12
+ ### Fixes / hardening
13
+
14
+ - Drop the `Connection: close` / `force_close` HTTP keepalive workaround (core#176536)
15
+ - Require `aiohttp>=3.14.3` for CVE-2026-69244
@@ -0,0 +1,21 @@
1
+ # Release notes — v1.3.11
2
+
3
+ **Compare range:** https://github.com/Swamp-Ig/pizone/compare/v1.3.10...v1.3.11
4
+
5
+ ## Since v1.3.10
6
+
7
+ ### API v2 (new)
8
+
9
+ - Prefer the bridge's V2 API for reads when it returns useful data, and send writes through `iZoneCommandV2`. V2 data is normalized into the same V1-shaped caches, so the public API is unchanged (#35)
10
+ - Confirm V2 zone mode changes by reading them back, within fixed time limits, and yield between polling reads so queued commands are not held up by a full zone sweep. See [V2 zone mode confirmation](../v2-confirmation.md)
11
+ - Keep the zone setpoint when selecting AUTO mode over V2
12
+ - Validate V2 zone snapshots, and keep a zero airflow value instead of dropping it
13
+ - Correct the V2 sensor and fan enums against the vendor header
14
+ - Free Air: try the V2 `iSaveOn` command first and fall back to the V1 `FreeAir` endpoint if the bridge rejects it, remembering the result per controller
15
+ - Free Air status is now read from `iSaveEnable`/`iSaveOn`. Before, V2 bridges always reported it as off
16
+
17
+ ### Fixes / hardening
18
+
19
+ - Allow controllers with no zones (unit-only systems). A negative zone count is still treated as a fault (#33, #34)
20
+ - Put a time limit on closing the discovery UDP transport. If the socket is not released within 1 s, abort it instead of hanging shutdown (Windows Proactor) (#41, #42)
21
+ - Document that setting a sleep timer can turn the unit on with some bridges
@@ -0,0 +1,71 @@
1
+ # V2 zone mode confirmation
2
+
3
+ This proposal changes only the native V2 path, not the legacy polling pathway
4
+ or V1 writes. It does not promise faster mechanical damper movement.
5
+
6
+ ## Contract
7
+
8
+ - Mode selection returns after the existing command transport acknowledges it.
9
+ - A controller-owned worker first attempts readback after 250 ms, subject to
10
+ the existing serialized transport and a shared two-second read-start limit.
11
+ - Multiple selections of one zone replace the earlier pending expectation.
12
+ Commands remain ordered and are not dropped or resent by confirmation.
13
+ - A fresh contradictory mode is masked for at most six seconds after ACK.
14
+ Afterwards the observed mode is published, while tracking continues for at
15
+ most 30 seconds. Other fields, including temperatures, remain observed data.
16
+ - Normal polling can satisfy a pending confirmation. It no longer holds the
17
+ command lock across the entire system/zone sweep; requests are still serial.
18
+ - A confirmation deadline includes time waiting for the lock and doing I/O.
19
+ Expiry logs an unconfirmed selection but does not by itself mark the bridge
20
+ offline. A real ConnectionError retains the existing disconnected/scan path.
21
+ - Controller close or discovery shutdown cancels owned confirmation work.
22
+
23
+ Explicit setpoint, fan, system-power and airflow commands retain their existing
24
+ confirmation behaviour. The existing AUTO-mode-only contribution is needed for
25
+ AUTO to take this fast path; otherwise the parent branch encodes AUTO as a
26
+ setpoint write. These changes should be reviewed together before release.
27
+
28
+ ## Type=7 bulk-read assessment
29
+
30
+ The official [API header v1.41](https://developer.izone.com.au/downloads/iZone_JSON_datastrings.h)
31
+ documents request Type=7 as system status. A separate local adapter on one
32
+ V2-only bridge has successfully read `iZoneStatusV2.Zones` with that request.
33
+ This is a documented endpoint with single-installation read evidence, not a
34
+ guarantee of support across all firmware. The native branch currently has
35
+ Type=1/2 fixtures. Type=7 carries dynamic zone fields but does not replace
36
+ the full Type=2 metadata, such as zone names and types.
37
+
38
+ This PR therefore does not silently switch polling to Type=7. A later bulk-read
39
+ implementation should have all of the following acceptance cases:
40
+
41
+ 1. Explicit capability detection, with bounded Type=2 fallback for unsupported
42
+ or incomplete responses; no parallel request storm.
43
+ 2. Expected bridge identity, unique zone indices and complete zone coverage.
44
+ 3. No merging of a partial failed bulk response with an unrelated fallback read.
45
+ 4. Defined refresh/invalidation of names, types and any other cached metadata,
46
+ including changed zone counts, endpoint replacement and controller reload.
47
+ 5. Tests for rapid commands, stale in-flight snapshots and bounded confirmation
48
+ that preserve the newest acknowledged selection.
49
+ 6. Hardware validation on both a V2-only and a dual-stack bridge, plus unchanged
50
+ V1 regressions. A complete native-branch hardware test remains outstanding.
51
+
52
+ The lower-risk immediate improvement is command interleaving between Type=2
53
+ reads plus bounded read-only confirmation. It needs no new firmware assumption.
54
+
55
+ ## Documentation boundaries
56
+
57
+ The [zone reference](https://developer.izone.com.au/docs/reference/zone/)
58
+ defines mode selection separately from setpoint updates, supporting the
59
+ mode-only AUTO contribution. Neither this page nor the Postman examples
60
+ specifies a guaranteed acknowledgement or mechanical damper latency. The
61
+ confirmation timings above remain measured/tested implementation choices.
62
+
63
+ The [cloud event service](https://developer.izone.com.au/docs/getting-started/cloud/event/)
64
+ is a separate vendor-arranged service, not a documented local WebSocket API
65
+ that this library can enable for instant zone updates. Existing local UDP
66
+ change notifications should not be confused with cloud event subscriptions.
67
+
68
+ The [discovery guide](https://developer.izone.com.au/docs/getting-started/local/discovery/)
69
+ says V2 devices retain V1 support, but issue #35 and the tested V2-only bridge
70
+ contradict that assumption. Keep usable-response probing and actual V2 writes;
71
+ an HTTP 200 response with an empty V1 body is not proof of V1 compatibility.