Skip to content

Repository files navigation

Python OmniLogic Local

PyPI VersionPython VersionTestsLicenseBuy Me A Coffee

A modern Python library for local control of Hayward OmniLogic and OmniHub pool controllers

FeaturesInstallationQuick StartDocumentationCLI Tool


Overview

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.14+, comprehensive type hints, and Pydantic validation, this library offers a async, type-safe interface for pool automation.

Features

Equipment Control

  • Heaters: Temperature control, mode selection (heat/auto/off), solar support
  • Pumps & Filters: Variable speed control, on/off operation, diagnostic information
  • ColorLogic Lights: Multiple models supported (2.5, 4.0, UCL, SAM), brightness, speed, show selection
  • Relays: Control auxiliary equipment like fountains, deck jets, blowers
  • Chlorinators: Timed percent control, enable/disable operation
  • Groups: Coordinated equipment control (turn multiple devices on/off together)
  • Schedules: Enable/disable automated schedules

Monitoring & State Management

  • Real-time Telemetry: Water temperature, chemical readings, equipment state
  • Configuration Discovery: Automatic detection of all equipment and capabilities
  • Sensor Data: pH, ORP, TDS, salt levels, flow sensors
  • Filter Diagnostics: Last speed, valve positions, priming states
  • Equipment Hierarchy: Automatic parent-child relationship tracking

Developer-Friendly Design

  • Type Safety: Comprehensive type hints with strict mypy validation
  • Async/Await: Non-blocking asyncio-based API
  • Pydantic Models: Automatic validation and serialization
  • Smart State Management: Automatic dirty tracking and efficient refreshing
  • Equipment Collections: Dict-like and attribute access patterns
  • Generic Architecture: Type-safe equipment hierarchy with generics

Installation

Requirements: Python 3.14 or higher

pip install python-omnilogic-local

With CLI tools (includes packet capture utilities):

pip install python-omnilogic-local[cli]

Quick Start

Basic Usage

importasynciofrompyomnilogic_localimportOmniLogic, OmniLogicConfigasyncdefmain():
# Connect to your OmniLogic controllerconfig=OmniLogicConfig(
host="192.168.1.100"
)
omni=OmniLogic(config)
# Initial refresh to load configuration and stateawaitomni.refresh()
# Access equipment by namepool=omni.backyard.bow["Pool"]
# Control heaterheater=pool.heaterprint(f"Current temperature: {heater.current_temperature}°F")
print(f"Target temperature: {heater.current_set_point}°F")
awaitheater.set_temperature(85)
awaitheater.turn_on()
# Refresh to get updated stateawaitomni.refresh()
# Control lightsfrompyomnilogic_local.omnitypesimportColorLogicBrightness, ColorLogicSpeedlight=pool.lights["Pool Light"]
awaitlight.turn_on()
awaitlight.set_show(
show=light.effects.TWILIGHT,
brightness=ColorLogicBrightness.ONE_HUNDRED_PERCENT,
speed=ColorLogicSpeed.ONE_TIMES
)
# Control pump speedpump=pool.pumps["Pool Pump"]
awaitpump.set_speed(75) # Set to 75%asyncio.run(main())

Monitoring Equipment State

asyncdefmonitor_pool():
config=OmniLogicConfig(
host="192.168.1.100"
)
omni=OmniLogic(config)
awaitomni.refresh()
pool=omni.backyard.bow["Pool"]
# Check multiple equipment statesprint(f"Water temperature: {pool.heater.current_temperature}°F")
print(f"Heater is {'on'ifpool.heater.is_onelse'off'}")
print(f"Pump speed: {pool.pumps['Main Pump'].current_speed}%")
# Check all lightsforname, lightinpool.lights.items():
iflight.is_on:
print(f"{name}: {light.show.name} @ {light.brightness.name}")
else:
print(f"{name}: OFF")
# Access chemical sensorsifpool.sensors:
forname, sensorinpool.sensors.items():
print(f"{name}: {sensor.current_reading}")
asyncio.run(monitor_pool())

Efficient State Updates

The library includes intelligent state management to minimize unnecessary API calls:

# Force immediate refresh of Telemetryawaitomni.refresh(force_telemetry=True)
# Force immediate refresh of MSP Configawaitomni.refresh(force_mspconfig=True)
# Refresh only if data is older than 30 secondsawaitomni.refresh(if_older_than=30.0)
# Refresh only if equipment state changed (default after control commands)awaitomni.refresh(if_dirty=True)

Documentation

Equipment Hierarchy

OmniLogic
├── Backyard
│ ├── Bodies of Water (BOW)
│ │ ├── Heater (single virtual heater)
│ │ ├── Pumps
│ │ ├── Filters
│ │ ├── Chlorinator
│ │ ├── Lights (ColorLogic)
│ │ ├── Relays
│ │ ├── Sensors
│ │ └── CSAD (Chemical Sensing & Dispensing)
│ ├── Lights (ColorLogic)
│ ├── Relays
│ └── Sensors
├── Groups
└── Schedules

Accessing Equipment

Equipment can be accessed using dictionary-style or attribute-style syntax:

# Dictionary access (by name)pool=omni.backyard.bow["Pool"]
# Heater is a single object (not a collection)heater=pool.heater# Most equipment are collectionsforpump_name, pumpinpool.pumps.items():
print(f"Pump: {pump_name} - Speed: {pump.current_speed}%")
# Lights, relays, and sensors can be on both BOW and backyard levelsforlight_name, lightinpool.lights.items():
print(f"BOW Light: {light_name}")
forlight_name, lightinomni.backyard.lights.items():
print(f"Backyard Light: {light_name}")
# Groups and schedules are at the OmniLogic levelforgroup_name, groupinomni.groups.items():
print(f"Group: {group_name}")

Equipment Properties

All equipment exposes standard properties:

equipment.name# Equipment nameequipment.system_id# Unique system identifierequipment.bow_id# Body of water ID (if applicable)equipment.is_ready# Whether equipment can accept commandsequipment.mspconfig# Configuration dataequipment.telemetry# Real-time state data

Control Methods

Control methods are async and automatically handle readiness checks:

frompyomnilogic_local.omnitypesimportColorLogicBrightness, ColorLogicSpeed# All control methods are asyncawaitheater.turn_on()
awaitheater.turn_off()
awaitheater.set_temperature(85)
# Light show control - brightness and speed are parameters to set_show()awaitlight.set_show(
show=light.effects.CARIBBEAN,
brightness=ColorLogicBrightness.EIGHTY_PERCENT,
speed=ColorLogicSpeed.TWO_TIMES
)
# Pump speed controlawaitpump.set_speed(75)
# State is automatically marked dirty after control commands# Refresh to get updated telemetryawaitomni.refresh()

Exception Handling

The library provides specific exception types:

frompyomnilogic_localimport (
OmniLogicLocalError, # Base exceptionOmniEquipmentNotReadyError, # Equipment in transitional stateOmniEquipmentNotInitializedError, # Missing required attributesOmniConnectionError, # Network/communication errors
)
try:
awaitheater.set_temperature(120) # Too highexceptOmniValidationExceptionase:
print(f"Invalid temperature: {e}")
try:
awaitlight.turn_on()
exceptOmniEquipmentNotReadyErrorase:
print(f"Light not ready: {e}")

CLI Tool

The library includes a command-line tool for monitoring and debugging:

# Get telemetry data
omnilogic --host 192.168.1.100 debug get-telemetry
# List all equipment
omnilogic get lights
omnilogic get pumps
omnilogic get heaters
# Get raw XML responses
omnilogic debug --raw get-mspconfig
# View filter diagnostics
omnilogic debug get-filter-diagnostics

Installation with CLI tools:

pip install python-omnilogic-local[cli]

Supported Equipment

Fully Supported

  • Pool/Spa Heaters (gas, heat pump, solar, hybrid)
  • Variable Speed Pumps & Filters
  • ColorLogic Lights (2.5, 4.0, UCL, SAM models)
  • Relays (water features, auxiliary equipment)
  • Chlorinators (timed percent control)
  • Sensors (temperature, pH, ORP, TDS, salt, flow)
  • Groups (coordinated equipment control)
  • Schedules (enable/disable)
  • CSAD (Chemical Sensing & Dispensing) - monitoring

Partial Support

  • CSAD equipment control (monitoring only currently)
  • Some advanced heater configurations

Note

If your controller has equipment not listed here, please open an issue with details about your configuration.

Development

This project uses modern Python tooling:

  • Python: 3.14+ with type hints
  • Type Checking: mypy strict mode
  • Validation: Pydantic v2
  • Testing: pytest with async support
  • Code Quality: black, isort, pylint, ruff
  • Package Management: uv (optional) or pip

Running Tests

# Install development dependencies
pip install -e ".[dev]"# Run tests
pytest
# Run with coverage
pytest --cov=pyomnilogic_local --cov-report=html
# Type checking
mypy pyomnilogic_local
# Linting
pylint pyomnilogic_local

Credits

This library was made possible by the pioneering work of:

Related Projects

Disclaimer

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.

About

Python Omnilogic Library for local access

Resources

Stars

10 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages