Skip to main content

Async Python library for interacting with the ProCon.IP pool controller.

Project description

Python package for the ProCon.IP Pool Controller

Lint Test CodeQL Documentation PyPI Package release

PyPI Python Versions

Overview


ProCon.IP Python Library

Introduction

The name of this library refers to the ProCon.IP pool controller. It is a port of my procon-ip TypeScript library (available as NPM Package). As the TypeScript library was a byproduct of my ioBroker adapter for the pool controller unit, this library is primarily intended for the implementation of a Home Assistant integration.

The library is fully typed (PEP 561). An IDE with auto-completion will give you most of what you need; for the full reference see the documentation site:

Feel free to ask questions via GitHub Issues so others can benefit from the answers too. Thanks!

Requirements

  • Python ≥ 3.13
  • aiohttp >= 3.10, < 4
  • yarl >= 1.9, < 2

These dependency ranges are compatible with Home Assistant Core 2026.5 pins (aiohttp==3.13.5, yarl==1.23.0).

v2.0.0 breaking changes — see CHANGELOG.md for details:

  • Python ≥ 3.13 required (was ≥ 3.10)
  • async-timeout dependency removed (use asyncio.timeout from stdlib)
  • Relay value semantics fixed (offset+gain applied exactly once)
  • TimeoutException is now actually raised for timeouts

Installation

This library is available on PyPI. So you can easily install it with pip:

pip install proconip

or

python -m pip install proconip

In both cases you can add --upgrade to update to the latest version.

Usage examples

Reading the current state

import asyncio
import aiohttp
from proconip import ConfigObject, GetState


async def reading_data_example():
    client_session = aiohttp.ClientSession()
    config = ConfigObject("http://192.168.2.3", "admin", "admin")
    get_state_api = GetState(client_session, config)
    data = await get_state_api.async_get_state()
    await client_session.close()
    print(f"Redox (Chlor): {data.redox_electrode.display_value}")
    print(f"pH: {data.ph_electrode.display_value}")
    for relay in (r for r in data.relays() if r.name != "n.a."):
        print(f"{relay.name}: {relay.display_value}")
    for temp in (t for t in data.temperature_objects if t.name != "n.a."):
        print(f"{temp.name}: {temp.display_value}")


asyncio.run(reading_data_example())

Switching relays

import asyncio
import aiohttp
from proconip import ConfigObject, GetState, RelaySwitch


async def relay_switching_example():
    client_session = aiohttp.ClientSession()
    config = ConfigObject("http://192.168.2.3", "admin", "admin")
    get_state_api = GetState(client_session, config)
    relay_switch = RelaySwitch(client_session, config)
    data = await get_state_api.async_get_state()
    print(f"Relay no. 2: {data.get_relay(1).display_value}")
    print(f"Relay no. 3: {data.get_relay(2).display_value}")
    await relay_switch.async_set_auto_mode(data, 1)
    data = await get_state_api.async_get_state()
    print(f"Relay no. 2: {data.get_relay(1).display_value}")
    await relay_switch.async_switch_on(data, 2)
    data = await get_state_api.async_get_state()
    print(f"Relay no. 3: {data.get_relay(2).display_value}")
    await relay_switch.async_switch_off(data, 1)
    data = await get_state_api.async_get_state()
    print(f"Relay no. 2: {data.get_relay(1).display_value}")
    await relay_switch.async_switch_off(data, 2)
    data = await get_state_api.async_get_state()
    print(f"Relay no. 3: {data.get_relay(2).display_value}")
    await client_session.close()


asyncio.run(relay_switching_example())

Starting manual dosage

Manual dosage depends on the same factors as if started from the web interface of the pool control itself.

import asyncio
import aiohttp
from proconip import ConfigObject, DosageControl


async def manual_dosage_example():
    client_session = aiohttp.ClientSession()
    config = ConfigObject("http://192.168.2.3", "admin", "admin")
    dosage_control = DosageControl(client_session, config)
    await dosage_control.async_chlorine_dosage(3600) # start for 1 hour
    await dosage_control.async_ph_minus_dosage(60) # start for 1 minute
    await client_session.close()


asyncio.run(manual_dosage_example())

Reading and changing DMX channel states

import asyncio
import aiohttp
from proconip import ConfigObject, DmxControl


async def dmx_example():
    client_session = aiohttp.ClientSession()
    config = ConfigObject("http://192.168.2.3", "admin", "admin")
    dmx_control = DmxControl(client_session, config)
    dmx_data = await dmx_control.async_get_dmx()
    for channel in dmx_data:
        print(f"{channel.name} before: {channel.value}")
        dmx_data.set(channel.index, (channel.value + 128) % 256)
        print(f"{channel.name} after: {dmx_data.get_value(channel.index)}")
      
    await dmx_control.async_set(dmx_data)
    await client_session.close()


asyncio.run(dmx_example())

A brief description of the ProCon.IP pool controller

The ProCon.IP pool controller is a low budget network attached control unit for home swimming pools. With its software switched relays, it can control multiple pumps (for the pool filter and different dosage aspects) either simply planned per time schedule or depending on a reading/value from one of its many input channels for measurements (eg. i/o flow sensors, Dallas 1-Wire thermometers, redox and pH electrodes). At least there is also the option to switch these relays on demand, which makes them also applicable for switching lights (or anything else you want) on/off. Not all of its functionality is reachable via API. In fact there is one documented API for reading (polling) values as CSV (/GetState.csv). In my memories there was another one for switching the relays on/off and on with timer. But I cannot find the second one anymore. So not even pretty, but functional: The ProCon.IP has two native web interfaces, which can be analyzed, to some kind of reverse engineer a given functionality (like switching the relays).

For more information see the following links (sorry it's only in german; haven't found an english documentation/information so far):

Get support

Need help? Please use the github issues system to ask your question. This way others can contribute or at least take advantage of the final solution.

Give support

If you want to support this project or my work in general, you can do so without having any coding abilities. Because programmers are described as machines that convert coffee (their habitual input) into code (their habitual output), there is a really simple way to support me:

Buy Me A Coffee

Release Notes

See CHANGELOG.md for the full release history.

Disclaimer

Just to be clear: I have nothing to do with the development, selling, marketing or support of the pool controller unit itself.
I just developed small TypeScript/JS and Python libraries as by-products of an ioBroker adapter and a Home Assistant integration for integrating the pool controller unit with common smart home solutions.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

proconip-2.2.0.tar.gz (35.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

proconip-2.2.0-py3-none-any.whl (25.7 kB view details)

Uploaded Python 3

File details

Details for the file proconip-2.2.0.tar.gz.

File metadata

  • Download URL: proconip-2.2.0.tar.gz
  • Upload date:
  • Size: 35.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for proconip-2.2.0.tar.gz
Algorithm Hash digest
SHA256 f3fd619ec595f2d6bde5f1f8b8fef89dd99ac39d0f142200f00bf72e06291e17
MD5 7f0e85245c3a707a267cf5b9033200e9
BLAKE2b-256 3c7a72d8533339f98dc787aa322d81f76fd3f2946b2013086dda8dca1b9e4edd

See more details on using hashes here.

Provenance

The following attestation bundles were made for proconip-2.2.0.tar.gz:

Publisher: python-publish.yml on ylabonte/proconip-pypi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file proconip-2.2.0-py3-none-any.whl.

File metadata

  • Download URL: proconip-2.2.0-py3-none-any.whl
  • Upload date:
  • Size: 25.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for proconip-2.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 006f4cb89f1daf88e4526b00173c7e690cbbdc3f00e7e7c332fd60ba3b944dec
MD5 a93096f876d0bfa2a1e2f8784a11e4c9
BLAKE2b-256 b3c5724adf8547e99ca322d8572bbb4857225a508b30fff2564567c9e1b1e5c3

See more details on using hashes here.

Provenance

The following attestation bundles were made for proconip-2.2.0-py3-none-any.whl:

Publisher: python-publish.yml on ylabonte/proconip-pypi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page