python-omnilogic-local 0.12.1__tar.gz → 0.20.2__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.
- python_omnilogic_local-0.20.2/PKG-INFO +372 -0
- python_omnilogic_local-0.20.2/README.md +355 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/__init__.py +22 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/_base.py +166 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/api/__init__.py +14 -0
- {python_omnilogic_local-0.12.1/pyomnilogic_local → python_omnilogic_local-0.20.2/pyomnilogic_local/api}/api.py +327 -101
- python_omnilogic_local-0.20.2/pyomnilogic_local/api/constants.py +35 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/api/exceptions.py +33 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/api/protocol.py +439 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/backyard.py +196 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/bow.py +331 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/chlorinator.py +430 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/chlorinator_equip.py +82 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/__init__.py +11 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/cli.py +45 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/debug/__init__.py +1 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/debug/commands.py +211 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/get/__init__.py +1 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/get/backyard.py +91 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/get/bows.py +104 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/get/chlorinators.py +75 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/get/commands.py +50 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/get/csads.py +69 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/get/filters.py +73 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/get/groups.py +68 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/get/heaters.py +116 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/get/lights.py +83 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/get/pumps.py +71 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/get/relays.py +79 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/get/schedules.py +65 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/get/sensors.py +72 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/get/valves.py +91 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/pcap_utils.py +164 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/cli/utils.py +106 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/collections.py +527 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/colorlogiclight.py +288 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/csad.py +328 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/csad_equip.py +77 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/decorators.py +58 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/filter.py +293 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/groups.py +114 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/heater.py +269 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/heater_equip.py +144 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/models/__init__.py +16 -0
- {python_omnilogic_local-0.12.1 → python_omnilogic_local-0.20.2}/pyomnilogic_local/models/const.py +2 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/models/exceptions.py +2 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/models/filter_diagnostics.py +67 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/models/leadmessage.py +43 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/models/mspconfig.py +467 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/models/telemetry.py +572 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/omnilogic.py +322 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/omnitypes.py +571 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/pump.py +275 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/relay.py +128 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/schedule.py +200 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/sensor.py +103 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/system.py +29 -0
- python_omnilogic_local-0.20.2/pyomnilogic_local/util.py +48 -0
- python_omnilogic_local-0.20.2/pyproject.toml +122 -0
- python_omnilogic_local-0.12.1/PKG-INFO +0 -64
- python_omnilogic_local-0.12.1/README.md +0 -39
- python_omnilogic_local-0.12.1/pyomnilogic_local/__init__.py +0 -0
- python_omnilogic_local-0.12.1/pyomnilogic_local/cli.py +0 -104
- python_omnilogic_local-0.12.1/pyomnilogic_local/exceptions.py +0 -10
- python_omnilogic_local-0.12.1/pyomnilogic_local/models/__init__.py +0 -0
- python_omnilogic_local-0.12.1/pyomnilogic_local/models/filter_diagnostics.py +0 -39
- python_omnilogic_local-0.12.1/pyomnilogic_local/models/leadmessage.py +0 -16
- python_omnilogic_local-0.12.1/pyomnilogic_local/models/mspconfig.py +0 -248
- python_omnilogic_local-0.12.1/pyomnilogic_local/models/telemetry.py +0 -254
- python_omnilogic_local-0.12.1/pyomnilogic_local/models/util.py +0 -47
- python_omnilogic_local-0.12.1/pyomnilogic_local/protocol.py +0 -223
- python_omnilogic_local-0.12.1/pyomnilogic_local/types.py +0 -337
- python_omnilogic_local-0.12.1/pyomnilogic_local/util.py +0 -16
- python_omnilogic_local-0.12.1/pyproject.toml +0 -199
- {python_omnilogic_local-0.12.1 → python_omnilogic_local-0.20.2}/LICENSE +0 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-omnilogic-local
|
|
3
|
+
Version: 0.20.2
|
|
4
|
+
Summary: A library for local control of Hayward OmniHub/OmniLogic pool controllers using their local API
|
|
5
|
+
Author: Chris Jowett, djtimca, garionphx
|
|
6
|
+
Author-email: Chris Jowett <421501+cryptk@users.noreply.github.com>
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: pydantic>=2.0.0,<3.0.0
|
|
9
|
+
Requires-Dist: click>=8.0.0,<9.0.0
|
|
10
|
+
Requires-Dist: xmltodict>=1.0.1,<2.0.0
|
|
11
|
+
Requires-Dist: uv~=0.9.8 ; extra == 'build'
|
|
12
|
+
Requires-Dist: scapy>=2.6.1,<3.0.0 ; extra == 'cli'
|
|
13
|
+
Requires-Python: >=3.13, <4.0.0
|
|
14
|
+
Provides-Extra: build
|
|
15
|
+
Provides-Extra: cli
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
<div align="center">
|
|
19
|
+
|
|
20
|
+
# Python OmniLogic Local
|
|
21
|
+
|
|
22
|
+
[](https://pypi.org/project/python-omnilogic-local/)
|
|
23
|
+
[](https://pypi.org/project/python-omnilogic-local/)
|
|
24
|
+
[](https://github.com/cryptk/python-omnilogic-local/actions)
|
|
25
|
+
[](LICENSE)
|
|
26
|
+
[](https://www.buymeacoffee.com/cryptk)
|
|
27
|
+
|
|
28
|
+
**A modern Python library for local control of Hayward OmniLogic and OmniHub pool controllers**
|
|
29
|
+
|
|
30
|
+
[Features](#features) • [Installation](#installation) • [Quick Start](#quick-start) • [Documentation](#documentation) • [CLI Tool](#cli-tool)
|
|
31
|
+
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Overview
|
|
37
|
+
|
|
38
|
+
Python OmniLogic Local provides complete local control over Hayward OmniLogic and OmniHub pool automation systems using their UDP-based XML protocol. Built with modern Python 3.12+, comprehensive type hints, and Pydantic validation, this library offers a async, type-safe interface for pool automation.
|
|
39
|
+
|
|
40
|
+
## Features
|
|
41
|
+
|
|
42
|
+
### Equipment Control
|
|
43
|
+
- **Heaters**: Temperature control, mode selection (heat/auto/off), solar support
|
|
44
|
+
- **Pumps & Filters**: Variable speed control, on/off operation, diagnostic information
|
|
45
|
+
- **ColorLogic Lights**: Multiple models supported (2.5, 4.0, UCL, SAM), brightness, speed, show selection
|
|
46
|
+
- **Relays**: Control auxiliary equipment like fountains, deck jets, blowers
|
|
47
|
+
- **Chlorinators**: Timed percent control, enable/disable operation
|
|
48
|
+
- **Groups**: Coordinated equipment control (turn multiple devices on/off together)
|
|
49
|
+
- **Schedules**: Enable/disable automated schedules
|
|
50
|
+
|
|
51
|
+
### Monitoring & State Management
|
|
52
|
+
- **Real-time Telemetry**: Water temperature, chemical readings, equipment state
|
|
53
|
+
- **Configuration Discovery**: Automatic detection of all equipment and capabilities
|
|
54
|
+
- **Sensor Data**: pH, ORP, TDS, salt levels, flow sensors
|
|
55
|
+
- **Filter Diagnostics**: Last speed, valve positions, priming states
|
|
56
|
+
- **Equipment Hierarchy**: Automatic parent-child relationship tracking
|
|
57
|
+
|
|
58
|
+
### Developer-Friendly Design
|
|
59
|
+
- **Type Safety**: Comprehensive type hints with strict mypy validation
|
|
60
|
+
- **Async/Await**: Non-blocking asyncio-based API
|
|
61
|
+
- **Pydantic Models**: Automatic validation and serialization
|
|
62
|
+
- **Smart State Management**: Automatic dirty tracking and efficient refreshing
|
|
63
|
+
- **Equipment Collections**: Dict-like and attribute access patterns
|
|
64
|
+
- **Generic Architecture**: Type-safe equipment hierarchy with generics
|
|
65
|
+
|
|
66
|
+
## Installation
|
|
67
|
+
|
|
68
|
+
**Requirements**: Python 3.12 or higher
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install python-omnilogic-local
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**With CLI tools** (includes packet capture utilities):
|
|
75
|
+
```bash
|
|
76
|
+
pip install python-omnilogic-local[cli]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Quick Start
|
|
80
|
+
|
|
81
|
+
### Basic Usage
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
import asyncio
|
|
85
|
+
from pyomnilogic_local import OmniLogic
|
|
86
|
+
|
|
87
|
+
async def main():
|
|
88
|
+
# Connect to your OmniLogic controller
|
|
89
|
+
omni = OmniLogic("192.168.1.100")
|
|
90
|
+
|
|
91
|
+
# Initial refresh to load configuration and state
|
|
92
|
+
await omni.refresh()
|
|
93
|
+
|
|
94
|
+
# Access equipment by name
|
|
95
|
+
pool = omni.backyard.bow["Pool"]
|
|
96
|
+
|
|
97
|
+
# Control heater
|
|
98
|
+
heater = pool.heater
|
|
99
|
+
print(f"Current temperature: {heater.current_temperature}°F")
|
|
100
|
+
print(f"Target temperature: {heater.current_set_point}°F")
|
|
101
|
+
|
|
102
|
+
await heater.set_temperature(85)
|
|
103
|
+
await heater.turn_on()
|
|
104
|
+
|
|
105
|
+
# Refresh to get updated state
|
|
106
|
+
await omni.refresh()
|
|
107
|
+
|
|
108
|
+
# Control lights
|
|
109
|
+
from pyomnilogic_local.omnitypes import ColorLogicBrightness, ColorLogicSpeed
|
|
110
|
+
|
|
111
|
+
light = pool.lights["Pool Light"]
|
|
112
|
+
await light.turn_on()
|
|
113
|
+
await light.set_show(
|
|
114
|
+
show=light.effects.TWILIGHT,
|
|
115
|
+
brightness=ColorLogicBrightness.ONE_HUNDRED_PERCENT,
|
|
116
|
+
speed=ColorLogicSpeed.ONE_TIMES
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
# Control pump speed
|
|
120
|
+
pump = pool.pumps["Pool Pump"]
|
|
121
|
+
await pump.set_speed(75) # Set to 75%
|
|
122
|
+
|
|
123
|
+
asyncio.run(main())
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Monitoring Equipment State
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
async def monitor_pool():
|
|
130
|
+
omni = OmniLogic("192.168.1.100")
|
|
131
|
+
await omni.refresh()
|
|
132
|
+
|
|
133
|
+
pool = omni.backyard.bow["Pool"]
|
|
134
|
+
|
|
135
|
+
# Check multiple equipment states
|
|
136
|
+
print(f"Water temperature: {pool.heater.current_temperature}°F")
|
|
137
|
+
print(f"Heater is {'on' if pool.heater.is_on else 'off'}")
|
|
138
|
+
print(f"Pump speed: {pool.pumps['Main Pump'].current_speed}%")
|
|
139
|
+
|
|
140
|
+
# Check all lights
|
|
141
|
+
for name, light in pool.lights.items():
|
|
142
|
+
if light.is_on:
|
|
143
|
+
print(f"{name}: {light.show.name} @ {light.brightness.name}")
|
|
144
|
+
else:
|
|
145
|
+
print(f"{name}: OFF")
|
|
146
|
+
|
|
147
|
+
# Access chemical sensors
|
|
148
|
+
if pool.sensors:
|
|
149
|
+
for name, sensor in pool.sensors.items():
|
|
150
|
+
print(f"{name}: {sensor.current_reading}")
|
|
151
|
+
|
|
152
|
+
asyncio.run(monitor_pool())
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Efficient State Updates
|
|
156
|
+
|
|
157
|
+
The library includes intelligent state management to minimize unnecessary API calls:
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
# Force immediate refresh
|
|
161
|
+
await omni.refresh(force=True)
|
|
162
|
+
|
|
163
|
+
# Refresh only if data is older than 30 seconds
|
|
164
|
+
await omni.refresh(if_older_than=30.0)
|
|
165
|
+
|
|
166
|
+
# Refresh only if equipment state changed (default after control commands)
|
|
167
|
+
await omni.refresh(if_dirty=True)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Documentation
|
|
171
|
+
|
|
172
|
+
### Equipment Hierarchy
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
OmniLogic
|
|
176
|
+
├── Backyard
|
|
177
|
+
│ ├── Bodies of Water (BOW)
|
|
178
|
+
│ │ ├── Heater (single virtual heater)
|
|
179
|
+
│ │ ├── Pumps
|
|
180
|
+
│ │ ├── Filters
|
|
181
|
+
│ │ ├── Chlorinator
|
|
182
|
+
│ │ ├── Lights (ColorLogic)
|
|
183
|
+
│ │ ├── Relays
|
|
184
|
+
│ │ ├── Sensors
|
|
185
|
+
│ │ └── CSAD (Chemical Sensing & Dispensing)
|
|
186
|
+
│ ├── Lights (ColorLogic)
|
|
187
|
+
│ ├── Relays
|
|
188
|
+
│ └── Sensors
|
|
189
|
+
├── Groups
|
|
190
|
+
└── Schedules
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Accessing Equipment
|
|
194
|
+
|
|
195
|
+
Equipment can be accessed using dictionary-style or attribute-style syntax:
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
# Dictionary access (by name)
|
|
199
|
+
pool = omni.backyard.bow["Pool"]
|
|
200
|
+
|
|
201
|
+
# Heater is a single object (not a collection)
|
|
202
|
+
heater = pool.heater
|
|
203
|
+
|
|
204
|
+
# Most equipment are collections
|
|
205
|
+
for pump_name, pump in pool.pumps.items():
|
|
206
|
+
print(f"Pump: {pump_name} - Speed: {pump.current_speed}%")
|
|
207
|
+
|
|
208
|
+
# Lights, relays, and sensors can be on both BOW and backyard levels
|
|
209
|
+
for light_name, light in pool.lights.items():
|
|
210
|
+
print(f"BOW Light: {light_name}")
|
|
211
|
+
|
|
212
|
+
for light_name, light in omni.backyard.lights.items():
|
|
213
|
+
print(f"Backyard Light: {light_name}")
|
|
214
|
+
|
|
215
|
+
# Groups and schedules are at the OmniLogic level
|
|
216
|
+
for group_name, group in omni.groups.items():
|
|
217
|
+
print(f"Group: {group_name}")
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Equipment Properties
|
|
221
|
+
|
|
222
|
+
All equipment exposes standard properties:
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
equipment.name # Equipment name
|
|
226
|
+
equipment.system_id # Unique system identifier
|
|
227
|
+
equipment.bow_id # Body of water ID (if applicable)
|
|
228
|
+
equipment.is_ready # Whether equipment can accept commands
|
|
229
|
+
equipment.mspconfig # Configuration data
|
|
230
|
+
equipment.telemetry # Real-time state data
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Control Methods
|
|
234
|
+
|
|
235
|
+
Control methods are async and automatically handle readiness checks:
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
from pyomnilogic_local.omnitypes import ColorLogicBrightness, ColorLogicSpeed
|
|
239
|
+
|
|
240
|
+
# All control methods are async
|
|
241
|
+
await heater.turn_on()
|
|
242
|
+
await heater.turn_off()
|
|
243
|
+
await heater.set_temperature(85)
|
|
244
|
+
|
|
245
|
+
# Light show control - brightness and speed are parameters to set_show()
|
|
246
|
+
await light.set_show(
|
|
247
|
+
show=light.effects.CARIBBEAN,
|
|
248
|
+
brightness=ColorLogicBrightness.EIGHTY_PERCENT,
|
|
249
|
+
speed=ColorLogicSpeed.TWO_TIMES
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
# Pump speed control
|
|
253
|
+
await pump.set_speed(75)
|
|
254
|
+
|
|
255
|
+
# State is automatically marked dirty after control commands
|
|
256
|
+
# Refresh to get updated telemetry
|
|
257
|
+
await omni.refresh()
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Exception Handling
|
|
261
|
+
|
|
262
|
+
The library provides specific exception types:
|
|
263
|
+
|
|
264
|
+
```python
|
|
265
|
+
from pyomnilogic_local import (
|
|
266
|
+
OmniLogicLocalError, # Base exception
|
|
267
|
+
OmniEquipmentNotReadyError, # Equipment in transitional state
|
|
268
|
+
OmniEquipmentNotInitializedError, # Missing required attributes
|
|
269
|
+
OmniConnectionError, # Network/communication errors
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
try:
|
|
273
|
+
await heater.set_temperature(120) # Too high
|
|
274
|
+
except OmniValidationException as e:
|
|
275
|
+
print(f"Invalid temperature: {e}")
|
|
276
|
+
|
|
277
|
+
try:
|
|
278
|
+
await light.turn_on()
|
|
279
|
+
except OmniEquipmentNotReadyError as e:
|
|
280
|
+
print(f"Light not ready: {e}")
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## CLI Tool
|
|
284
|
+
|
|
285
|
+
The library includes a command-line tool for monitoring and debugging:
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
# Get telemetry data
|
|
289
|
+
omnilogic --host 192.168.1.100 debug get-telemetry
|
|
290
|
+
|
|
291
|
+
# List all equipment
|
|
292
|
+
omnilogic get lights
|
|
293
|
+
omnilogic get pumps
|
|
294
|
+
omnilogic get heaters
|
|
295
|
+
|
|
296
|
+
# Get raw XML responses
|
|
297
|
+
omnilogic debug --raw get-mspconfig
|
|
298
|
+
|
|
299
|
+
# View filter diagnostics
|
|
300
|
+
omnilogic debug get-filter-diagnostics
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Installation with CLI tools**:
|
|
304
|
+
```bash
|
|
305
|
+
pip install python-omnilogic-local[cli]
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Supported Equipment
|
|
309
|
+
|
|
310
|
+
### Fully Supported
|
|
311
|
+
- Pool/Spa Heaters (gas, heat pump, solar, hybrid)
|
|
312
|
+
- Variable Speed Pumps & Filters
|
|
313
|
+
- ColorLogic Lights (2.5, 4.0, UCL, SAM models)
|
|
314
|
+
- Relays (water features, auxiliary equipment)
|
|
315
|
+
- Chlorinators (timed percent control)
|
|
316
|
+
- Sensors (temperature, pH, ORP, TDS, salt, flow)
|
|
317
|
+
- Groups (coordinated equipment control)
|
|
318
|
+
- Schedules (enable/disable)
|
|
319
|
+
- CSAD (Chemical Sensing & Dispensing) - monitoring
|
|
320
|
+
|
|
321
|
+
### Partial Support
|
|
322
|
+
- CSAD equipment control (monitoring only currently)
|
|
323
|
+
- Some advanced heater configurations
|
|
324
|
+
|
|
325
|
+
> [!NOTE]
|
|
326
|
+
> If your controller has equipment not listed here, please [open an issue](https://github.com/cryptk/python-omnilogic-local/issues) with details about your configuration.
|
|
327
|
+
|
|
328
|
+
## Development
|
|
329
|
+
|
|
330
|
+
This project uses modern Python tooling:
|
|
331
|
+
|
|
332
|
+
- **Python**: 3.12+ with type hints
|
|
333
|
+
- **Type Checking**: mypy strict mode
|
|
334
|
+
- **Validation**: Pydantic v2
|
|
335
|
+
- **Testing**: pytest with async support
|
|
336
|
+
- **Code Quality**: black, isort, pylint, ruff
|
|
337
|
+
- **Package Management**: uv (optional) or pip
|
|
338
|
+
|
|
339
|
+
### Running Tests
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
# Install development dependencies
|
|
343
|
+
pip install -e ".[dev]"
|
|
344
|
+
|
|
345
|
+
# Run tests
|
|
346
|
+
pytest
|
|
347
|
+
|
|
348
|
+
# Run with coverage
|
|
349
|
+
pytest --cov=pyomnilogic_local --cov-report=html
|
|
350
|
+
|
|
351
|
+
# Type checking
|
|
352
|
+
mypy pyomnilogic_local
|
|
353
|
+
|
|
354
|
+
# Linting
|
|
355
|
+
pylint pyomnilogic_local
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Credits
|
|
359
|
+
|
|
360
|
+
This library was made possible by the pioneering work of:
|
|
361
|
+
|
|
362
|
+
- [djtimca](https://github.com/djtimca/) - Original protocol research and implementation
|
|
363
|
+
- [John Sutherland](mailto:garionphx@gmail.com) - Protocol documentation and testing
|
|
364
|
+
|
|
365
|
+
## Related Projects
|
|
366
|
+
|
|
367
|
+
- [Home Assistant Integration](https://github.com/cryptk/haomnilogic-local) - Use this library with Home Assistant
|
|
368
|
+
|
|
369
|
+
## Disclaimer
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
This is an unofficial library and is not affiliated with, endorsed by, or connected to Hayward Industries, Inc. Use at your own risk. The developers are not responsible for any damage to equipment or property resulting from the use of this software.
|