API Reference¶
Everything below is auto-generated from the source docstrings. The public
surface is curated via __all__ in
proconip.__init__,
so anything importable as from proconip import … shows up here.
Top-level package¶
Async Python library for interacting with the ProCon.IP pool controller.
BadCredentialsException ¶
Bases: ProconipApiException
Raised when the controller rejects the request with HTTP 401 or 403.
Almost always means the username or password in the ConfigObject is wrong.
BadStatusCodeException ¶
Bases: ProconipApiException
Raised on any unexpected HTTP error status (4xx or 5xx) other than 401/403.
The original aiohttp.ClientResponseError is preserved as the cause and
can be inspected via __cause__ if the status code or response details
are needed.
Source code in src/proconip/api.py
DigitalInputControl ¶
Convenience wrapper that binds a session and config for triggering inputs.
Construct once with your aiohttp.ClientSession and ConfigObject, then
pulse digital inputs by zero-based id (0–3) without repeating those
arguments each time.
The constructor also binds a default timeout for every call made via this
wrapper. Each method then accepts an optional per-call timeout that
overrides the bound default when supplied.
Example
Source code in src/proconip/api.py
async_trigger
async
¶
async_trigger(digital_input_id: int, timeout: float | None = None, hold_seconds: float = DIGITAL_INPUT_PULSE_SECONDS) -> str
Trigger the digital input identified by digital_input_id.
| PARAMETER | DESCRIPTION |
|---|---|
digital_input_id
|
Zero-based digital input index (0–3).
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
hold_seconds
|
Seconds to hold the input HIGH between press and release. Defaults to the web UI's ~600ms.
TYPE:
|
See async_trigger_digital_input (the free function) for the full
description of behavior and raised exceptions.
Source code in src/proconip/api.py
DmxControl ¶
Convenience wrapper that binds a session and config for DMX I/O.
Construct once with your aiohttp.ClientSession and ConfigObject, then
read or write DMX channels without repeating those arguments each time.
The constructor also binds a default timeout for every call made via
this wrapper. Each method then accepts an optional per-call timeout
that overrides the bound default when supplied.
Example
Source code in src/proconip/api.py
811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 | |
async_get_raw_dmx
async
¶
Fetch the raw /GetDmx.csv body using the bound session and config.
| PARAMETER | DESCRIPTION |
|---|---|
timeout
|
Override for this call only. If
TYPE:
|
See async_get_raw_dmx (the free function) for the full description
of behavior and raised exceptions.
Source code in src/proconip/api.py
async_get_dmx
async
¶
Fetch and parse the current DMX state into a GetDmxData instance.
| PARAMETER | DESCRIPTION |
|---|---|
timeout
|
Override for this call only. If
TYPE:
|
See async_get_dmx (the free function) for the full description of
behavior and raised exceptions.
Source code in src/proconip/api.py
async_set
async
¶
Push the given DMX state back to the controller.
| PARAMETER | DESCRIPTION |
|---|---|
data
|
The
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
See async_set_dmx (the free function) for the full description of
behavior and raised exceptions.
Source code in src/proconip/api.py
DosageControl ¶
Convenience wrapper for manual dosage commands.
Construct once with your aiohttp.ClientSession and ConfigObject, then
trigger dosing per chemical without specifying the DosageTarget enum
each time.
The constructor also binds a default timeout for every call made via
this wrapper. Each method then accepts an optional per-call timeout
that overrides the bound default when supplied.
Example
Source code in src/proconip/api.py
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 | |
async_chlorine_dosage
async
¶
Run the chlorine dosage pump for dosage_duration seconds.
| PARAMETER | DESCRIPTION |
|---|---|
dosage_duration
|
Run time in seconds.
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
Subject to the same controller-side safety interlocks as manual
dosage from the web UI. See async_start_dosage for full behavior
and raised exceptions.
Source code in src/proconip/api.py
async_ph_minus_dosage
async
¶
Run the pH- dosage pump for dosage_duration seconds.
| PARAMETER | DESCRIPTION |
|---|---|
dosage_duration
|
Run time in seconds.
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
Subject to the same controller-side safety interlocks as manual
dosage from the web UI. See async_start_dosage for full behavior
and raised exceptions.
Source code in src/proconip/api.py
async_ph_plus_dosage
async
¶
Run the pH+ dosage pump for dosage_duration seconds.
| PARAMETER | DESCRIPTION |
|---|---|
dosage_duration
|
Run time in seconds.
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
Subject to the same controller-side safety interlocks as manual
dosage from the web UI. See async_start_dosage for full behavior
and raised exceptions.
Source code in src/proconip/api.py
GetState ¶
Convenience wrapper that binds a session and config for state reads.
Construct once with your aiohttp.ClientSession and ConfigObject, then
call async_get_state() (parsed) or async_get_raw_state() (CSV) without
repeating those arguments each time.
The constructor also binds a default timeout for every call made via
this wrapper. Each method then accepts an optional per-call timeout
that overrides the bound default when supplied.
Example
Source code in src/proconip/api.py
async_get_raw_state
async
¶
Fetch the raw /GetState.csv body using the bound session and config.
| PARAMETER | DESCRIPTION |
|---|---|
timeout
|
Override for this call only. If
TYPE:
|
See async_get_raw_state (the free function) for the full description
of behavior and raised exceptions.
Source code in src/proconip/api.py
async_get_state
async
¶
Fetch and parse the controller state into a GetStateData instance.
| PARAMETER | DESCRIPTION |
|---|---|
timeout
|
Override for this call only. If
TYPE:
|
See async_get_state (the free function) for the full description of
behavior and raised exceptions.
Source code in src/proconip/api.py
ProconipApiException ¶
Bases: Exception
Base exception for any failed API call.
Catch this if you want to handle all controller-side and network failures uniformly. The more specific subclasses below let you distinguish auth, HTTP, and timeout problems when that's useful.
Source code in src/proconip/api.py
RelaySwitch ¶
Convenience wrapper that binds a session and config for relay control.
Construct once with your aiohttp.ClientSession and ConfigObject, then
switch relays by aggregated relay ID (an integer) instead of
constructing Relay instances by hand.
Aggregated relay IDs run from 0 to 7 for the eight built-in relays and 8 to 15 for the eight optional external relays.
The constructor also binds a default timeout for every call made via
this wrapper. Each method then accepts an optional per-call timeout
that overrides the bound default when supplied.
Example
Source code in src/proconip/api.py
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 | |
async_switch_on
async
¶
Switch the relay identified by relay_id to manual ON.
| PARAMETER | DESCRIPTION |
|---|---|
current_state
|
A recent
TYPE:
|
relay_id
|
Aggregated relay ID (0–15).
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
Resolves the relay ID against current_state and delegates to the
free function async_switch_on. See it for the full description of
behavior and raised exceptions, including BadRelayException for
dosage relays.
Source code in src/proconip/api.py
async_switch_off
async
¶
Switch the relay identified by relay_id to manual OFF.
| PARAMETER | DESCRIPTION |
|---|---|
current_state
|
A recent
TYPE:
|
relay_id
|
Aggregated relay ID (0–15).
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
Resolves the relay ID against current_state and delegates to the
free function async_switch_off. See it for the full description of
behavior and raised exceptions.
Source code in src/proconip/api.py
async_set_auto_mode
async
¶
async_set_auto_mode(current_state: GetStateData, relay_id: int, timeout: float | None = None) -> str
Hand the relay identified by relay_id back to AUTO mode.
| PARAMETER | DESCRIPTION |
|---|---|
current_state
|
A recent
TYPE:
|
relay_id
|
Aggregated relay ID (0–15).
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
Resolves the relay ID against current_state and delegates to the
free function async_set_auto_mode. See it for the full description
of behavior and raised exceptions.
Source code in src/proconip/api.py
TimeoutException ¶
Bases: ProconipApiException
Raised when a request does not complete within the configured timeout.
This covers both network-level stalls (connection or socket I/O) and slow response bodies, since the timeout context wraps the entire exchange.
Source code in src/proconip/api.py
BadRelayException ¶
Bases: Exception
Raised when a relay argument doesn't make sense in context.
The two main cases are: switching a dosage relay on directly (rejected
by proconip.api.async_switch_on), and passing a non-relay DataObject
to GetStateData.is_dosage_relay.
Source code in src/proconip/definitions.py
ConfigObject ¶
Base URL and credentials for talking to a single ProCon.IP controller.
Instances are plain holders — no network connection is opened until they
are passed into one of the API helpers in proconip.api.
Source code in src/proconip/definitions.py
from_dict
staticmethod
¶
Build a ConfigObject from a serialized dictionary.
Useful for restoring a config that was previously written out via
to_dict (e.g. into a Home Assistant config entry).
| PARAMETER | DESCRIPTION |
|---|---|
data
|
A dict containing the keys
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ConfigObject
|
A new |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If any of the required keys is missing. The exception message names the missing key. |
Source code in src/proconip/definitions.py
to_dict ¶
Return a plain dict copy of the config, suitable for serialization.
The password is stored in the clear — encrypt the dict yourself if it will be persisted somewhere readable.
Source code in src/proconip/definitions.py
DataObject ¶
A single sensor, relay, canister, or consumption channel from /GetState.csv.
Each DataObject represents one column of the CSV response, combining the
name, unit, offset, gain, and raw value rows that the controller sends. The
column index alone determines which category the object falls into (analog,
relay, temperature, …) — see the constructor for the exact ranges.
The actual physical reading is computed once at construction via
offset + gain * raw_value and exposed as value. A pre-formatted
display_value string is also produced; for relay columns it is one of
"Auto (off)", "Auto (on)", "Off", or "On".
Source code in src/proconip/definitions.py
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | |
raw_value
property
¶
Raw value as received from the controller, before calibration.
display_value
property
¶
Pre-formatted human-readable string for display.
For sensors this is value rendered with its unit and two decimal
places. For relay columns it is one of "Auto (off)", "Auto (on)",
"Off", or "On". For column 0 (the system time field) it is "HH:MM".
category_id
property
¶
Zero-based index of this object within its category.
For example, the third temperature sensor has category_id == 2.
Use Relay.relay_id instead if you need the aggregated relay ID
across both the internal and external relay banks.
DigitalInput ¶
Bases: DataObject
Typed view of a single digital input (CSV columns 24–27).
Construct one by passing the DataObject you got from
GetStateData.digital_input_objects; the column, name, calibration, and
raw value are copied across so the physical value is computed exactly once.
GetStateData.digital_inputs() is a shorthand that does this for you.
The wrapper exists so digital inputs can be triggered (not just read):
get_bit_mask yields the bit used in the controller's WEBIO IO field.
Source code in src/proconip/definitions.py
get_bit_mask ¶
Bit for this input in the WEBIO IO field (1 << category_id).
The four digital inputs occupy bits 0–3, so this returns 1, 2, 4, or 8.
To trigger an input, pass its category_id to
async_trigger_digital_input (which derives the same mask itself); use
this method when assembling an IO payload for a manual
async_post_usrcfg_cgi write.
Source code in src/proconip/definitions.py
DmxChannelData ¶
A single DMX channel's index, name, and current value.
| ATTRIBUTE | DESCRIPTION |
|---|---|
value |
Current channel intensity, expected in the range [0, 255].
The constructor stores the value verbatim; clamping happens in
TYPE:
|
Source code in src/proconip/definitions.py
DosageTarget ¶
Bases: IntEnum
Identifies which dosing pump a manual dosage command should engage.
The numeric values match the controller's MAN_DOSAGE query parameter,
so this enum can be used directly in URL building.
Source code in src/proconip/definitions.py
GetDmxData ¶
Mutable representation of all 16 DMX channels.
Construct from a /GetDmx.csv body, then read or modify channels via
indexing, iteration, get_value, or set. Pass the (possibly mutated)
instance to proconip.api.async_set_dmx to write the new state back.
Source code in src/proconip/definitions.py
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 | |
post_data
property
¶
Form payload that updates the DMX channel state via /usrcfg.cgi.
The dict has five keys, all required by the controller:
TYPE: always"0".LEN: always"16"(channels per write).CH1_8: comma-separated values for channels 1–8.CH9_16: comma-separated values for channels 9–16.DMX512: always"1".
URL-encode and join with & to produce the actual POST body — see
proconip.api.async_set_dmx for the canonical encoding.
get_value ¶
Return the current value of the channel at index.
Equivalent to self[index].value. Provided for symmetry with
set.
set ¶
Update the value of one channel.
Values outside the [0, 255] range are silently clamped — the controller's DMX hardware only accepts 8-bit values, so callers rarely need anything else.
| PARAMETER | DESCRIPTION |
|---|---|
index
|
Zero-based channel index (0 for channel 1, 15 for channel 16).
TYPE:
|
value
|
New intensity. Clamped to [0, 255].
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
IndexError
|
If |
Source code in src/proconip/definitions.py
GetStateData ¶
Parsed representation of a single /GetState.csv response.
The CSV the controller returns has six lines: SYSINFO, names, units,
offsets, gains, and raw values. The constructor parses all six and
builds a list of DataObject instances, then groups them by category
for easy lookup.
Once constructed, an instance is read-only — it represents a snapshot. Re-fetch and reconstruct the object whenever you need fresh data.
All public properties on this class are populated eagerly at construction time, so accessing them is cheap.
Source code in src/proconip/definitions.py
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 | |
reset_root_cause
property
¶
Numeric reset-root-cause code. Decode with RESET_ROOT_CAUSE or
get_reset_root_cause_as_str.
ntp_fault_state
property
¶
Numeric NTP fault state. Decode with NTP_FAULT_STATE or
get_ntp_fault_state_as_str. Bits 0/1/2 indicate severity (logfile,
warning, error); bit 16 set indicates an NTP fault — no time received
from the NTP server (clear means the clock is in sync).
config_other_enable
property
¶
Misc configuration flags. Use the is_*_enabled methods to query
individual bits (TCP/IP boost, SD card, DMX, …).
dosage_control
property
¶
Dosage configuration flags. Use the is_*_dosage_enabled and
is_electrolysis_enabled methods to query individual bits.
ph_plus_dosage_relay_id
property
¶
Aggregated relay ID configured to act as the pH+ dosing pump.
ph_minus_dosage_relay_id
property
¶
Aggregated relay ID configured to act as the pH- dosing pump.
chlorine_dosage_relay_id
property
¶
Aggregated relay ID configured to act as the chlorine dosing pump.
analog_objects
property
¶
The five analog inputs (columns 1–5), in column order.
electrode_objects
property
¶
The two electrode readings — redox at index 0, pH at index 1.
temperature_objects
property
¶
The eight temperature sensors (columns 8–15), in column order.
relay_objects
property
¶
The eight built-in relays (columns 16–23), in column order.
These are still untyped DataObject instances. Use relays() for
Relay instances with on/off and manual/auto helpers, or
aggregated_relay_objects to also include the external relays.
digital_input_objects
property
¶
The four digital inputs (columns 24–27), in column order.
external_relay_objects
property
¶
The eight external relays (columns 28–35), in column order.
Will be present in the parsed data even when the relay extension is
not enabled in the controller config — check
is_relay_extension_enabled before treating them as live.
canister_objects
property
¶
The three canister fill-level readings (columns 36–38).
Order: chlorine, pH-, pH+. Convenience properties chlorine_canister,
ph_minus_canister, and ph_plus_canister return individual entries.
consumption_objects
property
¶
The three dosage consumption counters (columns 39–41).
Order: chlorine, pH-, pH+. Convenience properties
chlorine_consumption, ph_minus_consumption, and
ph_plus_consumption return individual entries.
chlorine_canister
property
¶
Chlorine canister fill level (column 36).
chlorine_consumption
property
¶
Cumulative chlorine consumption counter (column 39).
ph_minus_consumption
property
¶
Cumulative pH- consumption counter (column 40).
ph_plus_consumption
property
¶
Cumulative pH+ consumption counter (column 41).
aggregated_relay_objects
property
¶
All 16 relay DataObjects — internal first, then external.
Index in this list is the aggregated relay ID used by Relay.relay_id,
get_relay, and the RelaySwitch API.
chlorine_dosage_relay
property
¶
The relay configured as the chlorine dosing pump.
ph_minus_dosage_relay
property
¶
The relay configured as the pH- dosing pump.
ph_plus_dosage_relay
property
¶
The relay configured as the pH+ dosing pump.
is_chlorine_dosage_enabled ¶
is_electrolysis_enabled ¶
is_ph_minus_dosage_enabled ¶
is_ph_plus_dosage_enabled ¶
is_dosage_enabled ¶
Convenience: is the dosage chemical for this canister/consumption entity enabled?
| PARAMETER | DESCRIPTION |
|---|---|
data_entity
|
A canister (column 36–38) or consumption (column 39–41)
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if the corresponding |
bool
|
False for any other column (or if the chemical is disabled). |
Source code in src/proconip/definitions.py
get_dosage_relay ¶
Aggregated relay ID that handles the dosing for this canister/consumption entity.
| PARAMETER | DESCRIPTION |
|---|---|
data_entity
|
A canister (column 36–38) or consumption (column 39–41)
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
int | None
|
The aggregated relay ID (chlorine, pH-, or pH+) corresponding to |
int | None
|
the entity's chemical, or |
int | None
|
canister/consumption object. |
Source code in src/proconip/definitions.py
is_dosage_relay ¶
is_dosage_relay(relay_object: Relay | None = None, data_object: DataObject | None = None, relay_id: int | None = None) -> bool
Check whether a relay is one of the configured dosage control relays.
Provide one of relay_object, data_object, or relay_id. If more
than one is supplied, the first non-None argument in that precedence
order wins and the others are ignored. If none are provided the
method returns False.
| PARAMETER | DESCRIPTION |
|---|---|
relay_object
|
A
TYPE:
|
data_object
|
A
TYPE:
|
relay_id
|
An aggregated relay ID (0–15). Considered only when
both
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if the resolved argument identifies a dosage relay; False |
bool
|
otherwise (including when no argument is provided). |
| RAISES | DESCRIPTION |
|---|---|
BadRelayException
|
If |
Example
Source code in src/proconip/definitions.py
get_reset_root_cause_as_str ¶
Decode reset_root_cause to its RESET_ROOT_CAUSE label.
Falls back to the "n.a." label for any value not in the lookup table.
Source code in src/proconip/definitions.py
get_ntp_fault_state_as_str ¶
Decode ntp_fault_state to a human-readable label from NTP_FAULT_STATE.
For exact matches in the lookup table (0, 1, 2, 4,
65536) the corresponding label is returned. Composite states are
approximated by returning the highest-severity active bit (4 → 2 →
1), since the controller's CSV has no fixed combinations beyond the
listed ones. Falls back to "n.a." if no severity bit is set.
Source code in src/proconip/definitions.py
is_tcpip_boost_enabled ¶
is_sd_card_enabled ¶
is_dmx_enabled ¶
is_avatar_enabled ¶
is_relay_extension_enabled ¶
True if the external relay extension module is connected and active (bit 4).
Affects how determine_overall_relay_bit_state builds the ENA mask:
with the extension active, the mask covers all 16 bits instead of
just the internal 8.
Source code in src/proconip/definitions.py
is_high_bus_load_enabled ¶
is_flow_sensor_enabled ¶
is_repeated_mails_enabled ¶
is_dmx_extension_enabled ¶
True if the DMX extension module is enabled in the controller config (bit 8).
relays ¶
The eight built-in relays as Relay instances.
Equivalent to wrapping each entry in relay_objects with Relay(...).
digital_inputs ¶
The four digital inputs as DigitalInput instances.
Equivalent to wrapping each entry in digital_input_objects with
DigitalInput(...). Use these to get get_bit_mask() for triggering.
Source code in src/proconip/definitions.py
external_relays ¶
get_relay ¶
Return the Relay for the given aggregated relay ID (0–15).
| PARAMETER | DESCRIPTION |
|---|---|
relay_id
|
0–7 for internal relays, 8–15 for external relays.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Relay
|
A new |
| RAISES | DESCRIPTION |
|---|---|
IndexError
|
If |
Source code in src/proconip/definitions.py
get_relays ¶
determine_overall_relay_bit_state ¶
Build the two-element ENA bit field that represents the current relay state.
The controller's /usrcfg.cgi payload uses an ENA=enable_mask,on_mask
pair to set relay state. enable_mask selects which relays are in
manual mode (bit set = manual, bit clear = auto), and on_mask
selects the manual-on relays among them.
| RETURNS | DESCRIPTION |
|---|---|
list[int]
|
A two-element list |
list[int]
|
bits 0–7 (internal relays) by default, or bits 0–15 if the |
list[int]
|
external relay extension is enabled ( |
list[int]
|
The masks reflect the current state, so callers can flip a |
list[int]
|
single relay's bit and POST the result to switch only that |
list[int]
|
relay without touching the others. |
Source code in src/proconip/definitions.py
InvalidPayloadException ¶
Bases: Exception
Raised when a CSV response from the controller cannot be parsed.
Typically this means the response was empty, truncated, or did not have the expected number of CSV lines. Catching this lets callers distinguish protocol-level breakage from network errors.
Source code in src/proconip/definitions.py
Relay ¶
Bases: DataObject
A DataObject with extra methods for interrogating a relay's state.
Relay state is encoded in two bits of the underlying value:
- bit 0 — output level (0 = off, 1 = on)
- bit 1 — control mode (0 = auto, 1 = manual)
The four valid combinations correspond to the four display_value
strings from DataObject._relay_state.
Construct one by passing the DataObject you got from
GetStateData.relay_objects (or external_relay_objects); the relay's
column, name, calibration, and raw value are copied across so the
physical value is computed exactly once. GetStateData.get_relay() is
a shorthand that does this for you.
Source code in src/proconip/definitions.py
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | |
relay_id
property
¶
Aggregated relay ID across internal and external banks.
Internal relays return category_id directly (0–7); external
relays return category_id + EXTERNAL_RELAY_ID_OFFSET (8–15). This
ID matches the index used by GetStateData.aggregated_relay_objects
and RelaySwitch.async_switch_*.
is_on ¶
is_off ¶
is_manual_mode ¶
is_auto_mode ¶
get_bit_mask ¶
Bit mask for this relay in the 16-bit ENA / state field.
Internal relays occupy bits 0–7, external relays 8–15. The mask
returned here is suitable for OR-ing into the
determine_overall_relay_bit_state output before sending an ENA
update.
Source code in src/proconip/definitions.py
async_get_dmx
async
¶
async_get_dmx(client_session: ClientSession, config: ConfigObject, timeout: float = 10.0) -> GetDmxData
Fetch and parse the controller's DMX channel state.
Returns a mutable GetDmxData you can iterate over, read with [index],
or modify with set(index, value). Pass it to async_set_dmx to push
the changes back to the controller.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
GetDmxData
|
A |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
InvalidPayloadException
|
If the response is empty. |
Source code in src/proconip/api.py
async_get_raw_data
async
¶
async_get_raw_data(client_session: ClientSession, config: ConfigObject, url: URL, timeout: float = 10.0) -> str
Send an authenticated GET request and return the response body as text.
This is the low-level primitive used by the higher-level state, DMX, and dosage helpers. Most callers will want one of those instead — reach for this directly only when you need to hit a custom URL on the controller.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration. The username and password are sent as HTTP Basic auth credentials.
TYPE:
|
url
|
Fully-qualified URL to GET. Build it from
TYPE:
|
timeout
|
Maximum seconds to wait for the entire exchange (request and response body). Defaults to 10 seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body as a string. The controller typically returns |
str
|
CSV; the caller is responsible for parsing. |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
If the controller responds with HTTP 401 or 403. |
BadStatusCodeException
|
If any other 4xx or 5xx status is returned. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For DNS failures, connection resets, and other network-level errors. |
Source code in src/proconip/api.py
async_get_raw_dmx
async
¶
async_get_raw_dmx(client_session: ClientSession, config: ConfigObject, timeout: float = 10.0) -> str
Fetch the raw /GetDmx.csv body — the current 16 DMX channel values.
Use this when you want to parse the CSV yourself. To get a structured
GetDmxData you can read and mutate, call async_get_dmx instead.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
A single CSV line containing the 16 channel values. |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
async_get_raw_state
async
¶
async_get_raw_state(client_session: ClientSession, config: ConfigObject, timeout: float = 10.0) -> str
Fetch the raw /GetState.csv body from the controller.
Use this when you want to handle the CSV yourself. To get a parsed
object, call async_get_state instead.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration including base URL and credentials.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw multi-line CSV body returned by the controller. |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors (DNS, connection reset). |
Source code in src/proconip/api.py
async_get_state
async
¶
async_get_state(client_session: ClientSession, config: ConfigObject, timeout: float = 10.0) -> GetStateData
Fetch and parse the controller's current state.
This is the most common entry point: it performs the GET request, parses
the CSV response, and returns a GetStateData containing all sensor
readings, relay states, dosage configuration, and so on.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration including base URL and credentials.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
GetStateData
|
A |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
InvalidPayloadException
|
If the response is empty or truncated. |
Source code in src/proconip/api.py
async_post_usrcfg_cgi
async
¶
async_post_usrcfg_cgi(client_session: ClientSession, config: ConfigObject, payload: str, timeout: float = 10.0) -> str
Send a form-encoded POST to /usrcfg.cgi.
This is the low-level primitive behind relay switching and DMX writes.
Most callers want async_switch_on, async_switch_off,
async_set_auto_mode, or async_set_dmx instead. Use this directly only
when you need to send a payload the higher-level helpers don't construct.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration including base URL and credentials.
TYPE:
|
payload
|
The pre-encoded
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body returned by the controller. |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
async_set_auto_mode
async
¶
async_set_auto_mode(client_session: ClientSession, config: ConfigObject, current_state: GetStateData, relay: Relay, timeout: float = 10.0) -> str
Hand a relay back to the controller's automatic schedule.
This is the inverse of async_switch_on/async_switch_off: instead of
forcing a manual state, the relay's behavior is governed by the
controller's configured rules (timer, sensor thresholds, dosage logic).
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration.
TYPE:
|
current_state
|
A recent
TYPE:
|
relay
|
The relay to put back into auto mode.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body returned by |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
async_set_dmx
async
¶
async_set_dmx(client_session: ClientSession, config: ConfigObject, dmx_states: GetDmxData, timeout: float = 10.0) -> str
Push DMX channel values back to the controller.
The controller's API only accepts the full 16-channel state in a single
write. The usual pattern is: fetch with async_get_dmx, mutate channels
with dmx_states.set(index, value), then call this function to commit.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration.
TYPE:
|
dmx_states
|
The full DMX state to write. All 16 channels are sent.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body returned by |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
async_start_dosage
async
¶
async_start_dosage(client_session: ClientSession, config: ConfigObject, dosage_target: DosageTarget, dosage_duration: int, timeout: float = 10.0) -> str
Trigger a manual, time-limited dosage on the controller.
Manual dosage is the safe alternative to switching a dosage relay on directly: the controller still applies the same interlocks it uses for the web UI (canister level, dosage enabled in config, redox/pH thresholds, …). If those checks fail, the controller silently no-ops while still returning HTTP 200 — there is no "dosage refused" error in the protocol.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration.
TYPE:
|
dosage_target
|
Which dosing pump to engage (chlorine, pH-, or pH+).
TYPE:
|
dosage_duration
|
Run time in seconds. Allowed range depends on the controller's own dosage configuration; values that exceed the configured maximum are typically clamped silently by the device.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body returned by |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
async_switch_off
async
¶
async_switch_off(client_session: ClientSession, config: ConfigObject, current_state: GetStateData, relay: Relay, timeout: float = 10.0) -> str
Switch a relay to manual OFF.
Like async_switch_on, this puts the relay into manual mode but with the
output disabled. Other relays in current_state keep their state.
Unlike switching on, this is allowed for dosage relays — turning a dosage
pump off is always safe.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration.
TYPE:
|
current_state
|
A recent
TYPE:
|
relay
|
The relay to switch off.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body returned by |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
async_switch_on
async
¶
async_switch_on(client_session: ClientSession, config: ConfigObject, current_state: GetStateData, relay: Relay, timeout: float = 10.0) -> str
Switch a relay to manual ON.
Manual mode overrides the controller's schedule until the relay is
explicitly switched off or set back to auto. Other relays in
current_state are preserved by reading their bit field, which is why
a fresh GetStateData snapshot is required.
Dosage relays (chlorine, pH+, pH-) cannot be switched on this way — the
controller's safety logic interlocks them. Use async_start_dosage (or
DosageControl) instead for time-limited manual dosing.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration.
TYPE:
|
current_state
|
A recent
TYPE:
|
relay
|
The relay to switch on.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body returned by |
| RAISES | DESCRIPTION |
|---|---|
BadRelayException
|
If |
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
async_trigger_digital_input
async
¶
async_trigger_digital_input(client_session: ClientSession, config: ConfigObject, digital_input_id: int, timeout: float = 10.0, hold_seconds: float = DIGITAL_INPUT_PULSE_SECONDS) -> str
Trigger (momentarily pulse) a digital input via the WEBIO IO field.
The controller's web UI exposes each digital input as a push button: it
sets the input's bit, waits, then clears it. This sends the same two
/usrcfg.cgi writes — IO=<mask>&WEBIO=1 (press) then, after
hold_seconds, IO=0&WEBIO=1 (release) — where
mask = 1 << digital_input_id. The hold mirrors the web UI (~600ms) so
the controller reliably registers the pulse.
Unlike relay switching, no GetStateData snapshot is needed: the IO
field is written directly rather than read-modify-written.
Because the pulse is two separate writes, the release is not fully guaranteed. If the hold is cancelled (e.g. the caller's task is shut down), a best-effort release is attempted before the cancellation propagates. If the release POST itself fails (timeout / network blip), that error propagates and the input is left asserted HIGH until the next write.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration including base URL and credentials.
TYPE:
|
digital_input_id
|
Zero-based digital input index (0–3).
TYPE:
|
timeout
|
Per-request timeout in seconds, applied to each of the two POSTs.
TYPE:
|
hold_seconds
|
Seconds to hold the input HIGH between the press and release POSTs. Defaults to the web UI's ~600ms.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body returned by the release POST. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If |
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If an exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 | |
Async API client (proconip.api)¶
api ¶
Async HTTP client for the ProCon.IP pool controller.
The controller exposes four HTTP endpoints — /GetState.csv for sensor and
relay state, /GetDmx.csv for DMX channel state, /usrcfg.cgi for
configuration writes (including manual relay switching and DMX updates), and
/Command.htm for manual dosage commands. This module wraps all four with
typed exceptions and a configurable per-request timeout.
Each operation is available in two equivalent forms:
- Free async functions like
async_get_stateandasync_switch_on. These take anaiohttp.ClientSessionandConfigObjectexplicitly, which makes them composable in larger applications that already manage their own session lifecycle. - OO wrappers like
GetState,RelaySwitch,DosageControl, andDmxControl. These bind the session and config once at construction and expose ergonomic instance methods so callers don't have to repeat those arguments on every call.
The OO wrappers delegate to the free functions, so behavior is identical.
All requests use HTTP Basic auth and run inside an asyncio.timeout block
that covers both the request and the response body read. Network failures,
HTTP error codes, and timeouts are all mapped to ProconipApiException
subclasses so callers can handle them uniformly.
ProconipApiException ¶
Bases: Exception
Base exception for any failed API call.
Catch this if you want to handle all controller-side and network failures uniformly. The more specific subclasses below let you distinguish auth, HTTP, and timeout problems when that's useful.
Source code in src/proconip/api.py
BadCredentialsException ¶
Bases: ProconipApiException
Raised when the controller rejects the request with HTTP 401 or 403.
Almost always means the username or password in the ConfigObject is wrong.
BadStatusCodeException ¶
Bases: ProconipApiException
Raised on any unexpected HTTP error status (4xx or 5xx) other than 401/403.
The original aiohttp.ClientResponseError is preserved as the cause and
can be inspected via __cause__ if the status code or response details
are needed.
Source code in src/proconip/api.py
TimeoutException ¶
Bases: ProconipApiException
Raised when a request does not complete within the configured timeout.
This covers both network-level stalls (connection or socket I/O) and slow response bodies, since the timeout context wraps the entire exchange.
Source code in src/proconip/api.py
GetState ¶
Convenience wrapper that binds a session and config for state reads.
Construct once with your aiohttp.ClientSession and ConfigObject, then
call async_get_state() (parsed) or async_get_raw_state() (CSV) without
repeating those arguments each time.
The constructor also binds a default timeout for every call made via
this wrapper. Each method then accepts an optional per-call timeout
that overrides the bound default when supplied.
Example
Source code in src/proconip/api.py
async_get_raw_state
async
¶
Fetch the raw /GetState.csv body using the bound session and config.
| PARAMETER | DESCRIPTION |
|---|---|
timeout
|
Override for this call only. If
TYPE:
|
See async_get_raw_state (the free function) for the full description
of behavior and raised exceptions.
Source code in src/proconip/api.py
async_get_state
async
¶
Fetch and parse the controller state into a GetStateData instance.
| PARAMETER | DESCRIPTION |
|---|---|
timeout
|
Override for this call only. If
TYPE:
|
See async_get_state (the free function) for the full description of
behavior and raised exceptions.
Source code in src/proconip/api.py
RelaySwitch ¶
Convenience wrapper that binds a session and config for relay control.
Construct once with your aiohttp.ClientSession and ConfigObject, then
switch relays by aggregated relay ID (an integer) instead of
constructing Relay instances by hand.
Aggregated relay IDs run from 0 to 7 for the eight built-in relays and 8 to 15 for the eight optional external relays.
The constructor also binds a default timeout for every call made via
this wrapper. Each method then accepts an optional per-call timeout
that overrides the bound default when supplied.
Example
Source code in src/proconip/api.py
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 | |
async_switch_on
async
¶
Switch the relay identified by relay_id to manual ON.
| PARAMETER | DESCRIPTION |
|---|---|
current_state
|
A recent
TYPE:
|
relay_id
|
Aggregated relay ID (0–15).
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
Resolves the relay ID against current_state and delegates to the
free function async_switch_on. See it for the full description of
behavior and raised exceptions, including BadRelayException for
dosage relays.
Source code in src/proconip/api.py
async_switch_off
async
¶
Switch the relay identified by relay_id to manual OFF.
| PARAMETER | DESCRIPTION |
|---|---|
current_state
|
A recent
TYPE:
|
relay_id
|
Aggregated relay ID (0–15).
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
Resolves the relay ID against current_state and delegates to the
free function async_switch_off. See it for the full description of
behavior and raised exceptions.
Source code in src/proconip/api.py
async_set_auto_mode
async
¶
async_set_auto_mode(current_state: GetStateData, relay_id: int, timeout: float | None = None) -> str
Hand the relay identified by relay_id back to AUTO mode.
| PARAMETER | DESCRIPTION |
|---|---|
current_state
|
A recent
TYPE:
|
relay_id
|
Aggregated relay ID (0–15).
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
Resolves the relay ID against current_state and delegates to the
free function async_set_auto_mode. See it for the full description
of behavior and raised exceptions.
Source code in src/proconip/api.py
DosageControl ¶
Convenience wrapper for manual dosage commands.
Construct once with your aiohttp.ClientSession and ConfigObject, then
trigger dosing per chemical without specifying the DosageTarget enum
each time.
The constructor also binds a default timeout for every call made via
this wrapper. Each method then accepts an optional per-call timeout
that overrides the bound default when supplied.
Example
Source code in src/proconip/api.py
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 | |
async_chlorine_dosage
async
¶
Run the chlorine dosage pump for dosage_duration seconds.
| PARAMETER | DESCRIPTION |
|---|---|
dosage_duration
|
Run time in seconds.
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
Subject to the same controller-side safety interlocks as manual
dosage from the web UI. See async_start_dosage for full behavior
and raised exceptions.
Source code in src/proconip/api.py
async_ph_minus_dosage
async
¶
Run the pH- dosage pump for dosage_duration seconds.
| PARAMETER | DESCRIPTION |
|---|---|
dosage_duration
|
Run time in seconds.
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
Subject to the same controller-side safety interlocks as manual
dosage from the web UI. See async_start_dosage for full behavior
and raised exceptions.
Source code in src/proconip/api.py
async_ph_plus_dosage
async
¶
Run the pH+ dosage pump for dosage_duration seconds.
| PARAMETER | DESCRIPTION |
|---|---|
dosage_duration
|
Run time in seconds.
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
Subject to the same controller-side safety interlocks as manual
dosage from the web UI. See async_start_dosage for full behavior
and raised exceptions.
Source code in src/proconip/api.py
DmxControl ¶
Convenience wrapper that binds a session and config for DMX I/O.
Construct once with your aiohttp.ClientSession and ConfigObject, then
read or write DMX channels without repeating those arguments each time.
The constructor also binds a default timeout for every call made via
this wrapper. Each method then accepts an optional per-call timeout
that overrides the bound default when supplied.
Example
Source code in src/proconip/api.py
811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 | |
async_get_raw_dmx
async
¶
Fetch the raw /GetDmx.csv body using the bound session and config.
| PARAMETER | DESCRIPTION |
|---|---|
timeout
|
Override for this call only. If
TYPE:
|
See async_get_raw_dmx (the free function) for the full description
of behavior and raised exceptions.
Source code in src/proconip/api.py
async_get_dmx
async
¶
Fetch and parse the current DMX state into a GetDmxData instance.
| PARAMETER | DESCRIPTION |
|---|---|
timeout
|
Override for this call only. If
TYPE:
|
See async_get_dmx (the free function) for the full description of
behavior and raised exceptions.
Source code in src/proconip/api.py
async_set
async
¶
Push the given DMX state back to the controller.
| PARAMETER | DESCRIPTION |
|---|---|
data
|
The
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
See async_set_dmx (the free function) for the full description of
behavior and raised exceptions.
Source code in src/proconip/api.py
DigitalInputControl ¶
Convenience wrapper that binds a session and config for triggering inputs.
Construct once with your aiohttp.ClientSession and ConfigObject, then
pulse digital inputs by zero-based id (0–3) without repeating those
arguments each time.
The constructor also binds a default timeout for every call made via this
wrapper. Each method then accepts an optional per-call timeout that
overrides the bound default when supplied.
Example
Source code in src/proconip/api.py
async_trigger
async
¶
async_trigger(digital_input_id: int, timeout: float | None = None, hold_seconds: float = DIGITAL_INPUT_PULSE_SECONDS) -> str
Trigger the digital input identified by digital_input_id.
| PARAMETER | DESCRIPTION |
|---|---|
digital_input_id
|
Zero-based digital input index (0–3).
TYPE:
|
timeout
|
Override for this call only. If
TYPE:
|
hold_seconds
|
Seconds to hold the input HIGH between press and release. Defaults to the web UI's ~600ms.
TYPE:
|
See async_trigger_digital_input (the free function) for the full
description of behavior and raised exceptions.
Source code in src/proconip/api.py
async_get_raw_data
async
¶
async_get_raw_data(client_session: ClientSession, config: ConfigObject, url: URL, timeout: float = 10.0) -> str
Send an authenticated GET request and return the response body as text.
This is the low-level primitive used by the higher-level state, DMX, and dosage helpers. Most callers will want one of those instead — reach for this directly only when you need to hit a custom URL on the controller.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration. The username and password are sent as HTTP Basic auth credentials.
TYPE:
|
url
|
Fully-qualified URL to GET. Build it from
TYPE:
|
timeout
|
Maximum seconds to wait for the entire exchange (request and response body). Defaults to 10 seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body as a string. The controller typically returns |
str
|
CSV; the caller is responsible for parsing. |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
If the controller responds with HTTP 401 or 403. |
BadStatusCodeException
|
If any other 4xx or 5xx status is returned. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For DNS failures, connection resets, and other network-level errors. |
Source code in src/proconip/api.py
async_get_raw_state
async
¶
async_get_raw_state(client_session: ClientSession, config: ConfigObject, timeout: float = 10.0) -> str
Fetch the raw /GetState.csv body from the controller.
Use this when you want to handle the CSV yourself. To get a parsed
object, call async_get_state instead.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration including base URL and credentials.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw multi-line CSV body returned by the controller. |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors (DNS, connection reset). |
Source code in src/proconip/api.py
async_get_state
async
¶
async_get_state(client_session: ClientSession, config: ConfigObject, timeout: float = 10.0) -> GetStateData
Fetch and parse the controller's current state.
This is the most common entry point: it performs the GET request, parses
the CSV response, and returns a GetStateData containing all sensor
readings, relay states, dosage configuration, and so on.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration including base URL and credentials.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
GetStateData
|
A |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
InvalidPayloadException
|
If the response is empty or truncated. |
Source code in src/proconip/api.py
async_post_usrcfg_cgi
async
¶
async_post_usrcfg_cgi(client_session: ClientSession, config: ConfigObject, payload: str, timeout: float = 10.0) -> str
Send a form-encoded POST to /usrcfg.cgi.
This is the low-level primitive behind relay switching and DMX writes.
Most callers want async_switch_on, async_switch_off,
async_set_auto_mode, or async_set_dmx instead. Use this directly only
when you need to send a payload the higher-level helpers don't construct.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration including base URL and credentials.
TYPE:
|
payload
|
The pre-encoded
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body returned by the controller. |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
async_switch_on
async
¶
async_switch_on(client_session: ClientSession, config: ConfigObject, current_state: GetStateData, relay: Relay, timeout: float = 10.0) -> str
Switch a relay to manual ON.
Manual mode overrides the controller's schedule until the relay is
explicitly switched off or set back to auto. Other relays in
current_state are preserved by reading their bit field, which is why
a fresh GetStateData snapshot is required.
Dosage relays (chlorine, pH+, pH-) cannot be switched on this way — the
controller's safety logic interlocks them. Use async_start_dosage (or
DosageControl) instead for time-limited manual dosing.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration.
TYPE:
|
current_state
|
A recent
TYPE:
|
relay
|
The relay to switch on.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body returned by |
| RAISES | DESCRIPTION |
|---|---|
BadRelayException
|
If |
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
async_switch_off
async
¶
async_switch_off(client_session: ClientSession, config: ConfigObject, current_state: GetStateData, relay: Relay, timeout: float = 10.0) -> str
Switch a relay to manual OFF.
Like async_switch_on, this puts the relay into manual mode but with the
output disabled. Other relays in current_state keep their state.
Unlike switching on, this is allowed for dosage relays — turning a dosage
pump off is always safe.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration.
TYPE:
|
current_state
|
A recent
TYPE:
|
relay
|
The relay to switch off.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body returned by |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
async_set_auto_mode
async
¶
async_set_auto_mode(client_session: ClientSession, config: ConfigObject, current_state: GetStateData, relay: Relay, timeout: float = 10.0) -> str
Hand a relay back to the controller's automatic schedule.
This is the inverse of async_switch_on/async_switch_off: instead of
forcing a manual state, the relay's behavior is governed by the
controller's configured rules (timer, sensor thresholds, dosage logic).
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration.
TYPE:
|
current_state
|
A recent
TYPE:
|
relay
|
The relay to put back into auto mode.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body returned by |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
async_start_dosage
async
¶
async_start_dosage(client_session: ClientSession, config: ConfigObject, dosage_target: DosageTarget, dosage_duration: int, timeout: float = 10.0) -> str
Trigger a manual, time-limited dosage on the controller.
Manual dosage is the safe alternative to switching a dosage relay on directly: the controller still applies the same interlocks it uses for the web UI (canister level, dosage enabled in config, redox/pH thresholds, …). If those checks fail, the controller silently no-ops while still returning HTTP 200 — there is no "dosage refused" error in the protocol.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration.
TYPE:
|
dosage_target
|
Which dosing pump to engage (chlorine, pH-, or pH+).
TYPE:
|
dosage_duration
|
Run time in seconds. Allowed range depends on the controller's own dosage configuration; values that exceed the configured maximum are typically clamped silently by the device.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body returned by |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
async_get_raw_dmx
async
¶
async_get_raw_dmx(client_session: ClientSession, config: ConfigObject, timeout: float = 10.0) -> str
Fetch the raw /GetDmx.csv body — the current 16 DMX channel values.
Use this when you want to parse the CSV yourself. To get a structured
GetDmxData you can read and mutate, call async_get_dmx instead.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
A single CSV line containing the 16 channel values. |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
async_get_dmx
async
¶
async_get_dmx(client_session: ClientSession, config: ConfigObject, timeout: float = 10.0) -> GetDmxData
Fetch and parse the controller's DMX channel state.
Returns a mutable GetDmxData you can iterate over, read with [index],
or modify with set(index, value). Pass it to async_set_dmx to push
the changes back to the controller.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
GetDmxData
|
A |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
InvalidPayloadException
|
If the response is empty. |
Source code in src/proconip/api.py
async_set_dmx
async
¶
async_set_dmx(client_session: ClientSession, config: ConfigObject, dmx_states: GetDmxData, timeout: float = 10.0) -> str
Push DMX channel values back to the controller.
The controller's API only accepts the full 16-channel state in a single
write. The usual pattern is: fetch with async_get_dmx, mutate channels
with dmx_states.set(index, value), then call this function to commit.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration.
TYPE:
|
dmx_states
|
The full DMX state to write. All 16 channels are sent.
TYPE:
|
timeout
|
Per-request timeout in seconds.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body returned by |
| RAISES | DESCRIPTION |
|---|---|
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If the exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
async_trigger_digital_input
async
¶
async_trigger_digital_input(client_session: ClientSession, config: ConfigObject, digital_input_id: int, timeout: float = 10.0, hold_seconds: float = DIGITAL_INPUT_PULSE_SECONDS) -> str
Trigger (momentarily pulse) a digital input via the WEBIO IO field.
The controller's web UI exposes each digital input as a push button: it
sets the input's bit, waits, then clears it. This sends the same two
/usrcfg.cgi writes — IO=<mask>&WEBIO=1 (press) then, after
hold_seconds, IO=0&WEBIO=1 (release) — where
mask = 1 << digital_input_id. The hold mirrors the web UI (~600ms) so
the controller reliably registers the pulse.
Unlike relay switching, no GetStateData snapshot is needed: the IO
field is written directly rather than read-modify-written.
Because the pulse is two separate writes, the release is not fully guaranteed. If the hold is cancelled (e.g. the caller's task is shut down), a best-effort release is attempted before the cancellation propagates. If the release POST itself fails (timeout / network blip), that error propagates and the input is left asserted HIGH until the next write.
| PARAMETER | DESCRIPTION |
|---|---|
client_session
|
An open
TYPE:
|
config
|
Controller configuration including base URL and credentials.
TYPE:
|
digital_input_id
|
Zero-based digital input index (0–3).
TYPE:
|
timeout
|
Per-request timeout in seconds, applied to each of the two POSTs.
TYPE:
|
hold_seconds
|
Seconds to hold the input HIGH between the press and release POSTs. Defaults to the web UI's ~600ms.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The raw response body returned by the release POST. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If |
BadCredentialsException
|
On HTTP 401 or 403. |
BadStatusCodeException
|
On any other 4xx or 5xx response. |
TimeoutException
|
If an exchange exceeds |
ProconipApiException
|
For network-level errors. |
Source code in src/proconip/api.py
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 | |
Data structures (proconip.definitions)¶
definitions ¶
Data structures for the ProCon.IP CSV and form-encoded HTTP APIs.
This module contains everything that's needed to describe the controller's data shape without making any network calls — typed wrappers around the CSV responses, helpers for the bit-field flags they encode, and a few small exceptions that get raised when something is malformed.
Path constants (API_PATH_*) and category strings (CATEGORY_*) are exposed
because the rest of the library and downstream callers (notably a Home
Assistant integration) build on them.
The classes you will most often work with are:
ConfigObject— base URL plus credentials.GetStateData— parsed/GetState.csvresponse. Exposes individual sensors, relays, dosage flags, and a few derived helpers.Relay— convenience wrapper around a relayDataObjectwith on/off and manual/auto interrogation methods.GetDmxData/DmxChannelData— parsed and mutable representation of the 16 DMX channels.
DosageTarget ¶
Bases: IntEnum
Identifies which dosing pump a manual dosage command should engage.
The numeric values match the controller's MAN_DOSAGE query parameter,
so this enum can be used directly in URL building.
Source code in src/proconip/definitions.py
ConfigObject ¶
Base URL and credentials for talking to a single ProCon.IP controller.
Instances are plain holders — no network connection is opened until they
are passed into one of the API helpers in proconip.api.
Source code in src/proconip/definitions.py
from_dict
staticmethod
¶
Build a ConfigObject from a serialized dictionary.
Useful for restoring a config that was previously written out via
to_dict (e.g. into a Home Assistant config entry).
| PARAMETER | DESCRIPTION |
|---|---|
data
|
A dict containing the keys
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ConfigObject
|
A new |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If any of the required keys is missing. The exception message names the missing key. |
Source code in src/proconip/definitions.py
to_dict ¶
Return a plain dict copy of the config, suitable for serialization.
The password is stored in the clear — encrypt the dict yourself if it will be persisted somewhere readable.
Source code in src/proconip/definitions.py
DataObject ¶
A single sensor, relay, canister, or consumption channel from /GetState.csv.
Each DataObject represents one column of the CSV response, combining the
name, unit, offset, gain, and raw value rows that the controller sends. The
column index alone determines which category the object falls into (analog,
relay, temperature, …) — see the constructor for the exact ranges.
The actual physical reading is computed once at construction via
offset + gain * raw_value and exposed as value. A pre-formatted
display_value string is also produced; for relay columns it is one of
"Auto (off)", "Auto (on)", "Off", or "On".
Source code in src/proconip/definitions.py
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | |
raw_value
property
¶
Raw value as received from the controller, before calibration.
display_value
property
¶
Pre-formatted human-readable string for display.
For sensors this is value rendered with its unit and two decimal
places. For relay columns it is one of "Auto (off)", "Auto (on)",
"Off", or "On". For column 0 (the system time field) it is "HH:MM".
category_id
property
¶
Zero-based index of this object within its category.
For example, the third temperature sensor has category_id == 2.
Use Relay.relay_id instead if you need the aggregated relay ID
across both the internal and external relay banks.
Relay ¶
Bases: DataObject
A DataObject with extra methods for interrogating a relay's state.
Relay state is encoded in two bits of the underlying value:
- bit 0 — output level (0 = off, 1 = on)
- bit 1 — control mode (0 = auto, 1 = manual)
The four valid combinations correspond to the four display_value
strings from DataObject._relay_state.
Construct one by passing the DataObject you got from
GetStateData.relay_objects (or external_relay_objects); the relay's
column, name, calibration, and raw value are copied across so the
physical value is computed exactly once. GetStateData.get_relay() is
a shorthand that does this for you.
Source code in src/proconip/definitions.py
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | |
relay_id
property
¶
Aggregated relay ID across internal and external banks.
Internal relays return category_id directly (0–7); external
relays return category_id + EXTERNAL_RELAY_ID_OFFSET (8–15). This
ID matches the index used by GetStateData.aggregated_relay_objects
and RelaySwitch.async_switch_*.
is_on ¶
is_off ¶
is_manual_mode ¶
is_auto_mode ¶
get_bit_mask ¶
Bit mask for this relay in the 16-bit ENA / state field.
Internal relays occupy bits 0–7, external relays 8–15. The mask
returned here is suitable for OR-ing into the
determine_overall_relay_bit_state output before sending an ENA
update.
Source code in src/proconip/definitions.py
DigitalInput ¶
Bases: DataObject
Typed view of a single digital input (CSV columns 24–27).
Construct one by passing the DataObject you got from
GetStateData.digital_input_objects; the column, name, calibration, and
raw value are copied across so the physical value is computed exactly once.
GetStateData.digital_inputs() is a shorthand that does this for you.
The wrapper exists so digital inputs can be triggered (not just read):
get_bit_mask yields the bit used in the controller's WEBIO IO field.
Source code in src/proconip/definitions.py
get_bit_mask ¶
Bit for this input in the WEBIO IO field (1 << category_id).
The four digital inputs occupy bits 0–3, so this returns 1, 2, 4, or 8.
To trigger an input, pass its category_id to
async_trigger_digital_input (which derives the same mask itself); use
this method when assembling an IO payload for a manual
async_post_usrcfg_cgi write.
Source code in src/proconip/definitions.py
GetStateData ¶
Parsed representation of a single /GetState.csv response.
The CSV the controller returns has six lines: SYSINFO, names, units,
offsets, gains, and raw values. The constructor parses all six and
builds a list of DataObject instances, then groups them by category
for easy lookup.
Once constructed, an instance is read-only — it represents a snapshot. Re-fetch and reconstruct the object whenever you need fresh data.
All public properties on this class are populated eagerly at construction time, so accessing them is cheap.
Source code in src/proconip/definitions.py
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 | |
reset_root_cause
property
¶
Numeric reset-root-cause code. Decode with RESET_ROOT_CAUSE or
get_reset_root_cause_as_str.
ntp_fault_state
property
¶
Numeric NTP fault state. Decode with NTP_FAULT_STATE or
get_ntp_fault_state_as_str. Bits 0/1/2 indicate severity (logfile,
warning, error); bit 16 set indicates an NTP fault — no time received
from the NTP server (clear means the clock is in sync).
config_other_enable
property
¶
Misc configuration flags. Use the is_*_enabled methods to query
individual bits (TCP/IP boost, SD card, DMX, …).
dosage_control
property
¶
Dosage configuration flags. Use the is_*_dosage_enabled and
is_electrolysis_enabled methods to query individual bits.
ph_plus_dosage_relay_id
property
¶
Aggregated relay ID configured to act as the pH+ dosing pump.
ph_minus_dosage_relay_id
property
¶
Aggregated relay ID configured to act as the pH- dosing pump.
chlorine_dosage_relay_id
property
¶
Aggregated relay ID configured to act as the chlorine dosing pump.
analog_objects
property
¶
The five analog inputs (columns 1–5), in column order.
electrode_objects
property
¶
The two electrode readings — redox at index 0, pH at index 1.
temperature_objects
property
¶
The eight temperature sensors (columns 8–15), in column order.
relay_objects
property
¶
The eight built-in relays (columns 16–23), in column order.
These are still untyped DataObject instances. Use relays() for
Relay instances with on/off and manual/auto helpers, or
aggregated_relay_objects to also include the external relays.
digital_input_objects
property
¶
The four digital inputs (columns 24–27), in column order.
external_relay_objects
property
¶
The eight external relays (columns 28–35), in column order.
Will be present in the parsed data even when the relay extension is
not enabled in the controller config — check
is_relay_extension_enabled before treating them as live.
canister_objects
property
¶
The three canister fill-level readings (columns 36–38).
Order: chlorine, pH-, pH+. Convenience properties chlorine_canister,
ph_minus_canister, and ph_plus_canister return individual entries.
consumption_objects
property
¶
The three dosage consumption counters (columns 39–41).
Order: chlorine, pH-, pH+. Convenience properties
chlorine_consumption, ph_minus_consumption, and
ph_plus_consumption return individual entries.
chlorine_canister
property
¶
Chlorine canister fill level (column 36).
chlorine_consumption
property
¶
Cumulative chlorine consumption counter (column 39).
ph_minus_consumption
property
¶
Cumulative pH- consumption counter (column 40).
ph_plus_consumption
property
¶
Cumulative pH+ consumption counter (column 41).
aggregated_relay_objects
property
¶
All 16 relay DataObjects — internal first, then external.
Index in this list is the aggregated relay ID used by Relay.relay_id,
get_relay, and the RelaySwitch API.
chlorine_dosage_relay
property
¶
The relay configured as the chlorine dosing pump.
ph_minus_dosage_relay
property
¶
The relay configured as the pH- dosing pump.
ph_plus_dosage_relay
property
¶
The relay configured as the pH+ dosing pump.
is_chlorine_dosage_enabled ¶
is_electrolysis_enabled ¶
is_ph_minus_dosage_enabled ¶
is_ph_plus_dosage_enabled ¶
is_dosage_enabled ¶
Convenience: is the dosage chemical for this canister/consumption entity enabled?
| PARAMETER | DESCRIPTION |
|---|---|
data_entity
|
A canister (column 36–38) or consumption (column 39–41)
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if the corresponding |
bool
|
False for any other column (or if the chemical is disabled). |
Source code in src/proconip/definitions.py
get_dosage_relay ¶
Aggregated relay ID that handles the dosing for this canister/consumption entity.
| PARAMETER | DESCRIPTION |
|---|---|
data_entity
|
A canister (column 36–38) or consumption (column 39–41)
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
int | None
|
The aggregated relay ID (chlorine, pH-, or pH+) corresponding to |
int | None
|
the entity's chemical, or |
int | None
|
canister/consumption object. |
Source code in src/proconip/definitions.py
is_dosage_relay ¶
is_dosage_relay(relay_object: Relay | None = None, data_object: DataObject | None = None, relay_id: int | None = None) -> bool
Check whether a relay is one of the configured dosage control relays.
Provide one of relay_object, data_object, or relay_id. If more
than one is supplied, the first non-None argument in that precedence
order wins and the others are ignored. If none are provided the
method returns False.
| PARAMETER | DESCRIPTION |
|---|---|
relay_object
|
A
TYPE:
|
data_object
|
A
TYPE:
|
relay_id
|
An aggregated relay ID (0–15). Considered only when
both
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if the resolved argument identifies a dosage relay; False |
bool
|
otherwise (including when no argument is provided). |
| RAISES | DESCRIPTION |
|---|---|
BadRelayException
|
If |
Example
Source code in src/proconip/definitions.py
get_reset_root_cause_as_str ¶
Decode reset_root_cause to its RESET_ROOT_CAUSE label.
Falls back to the "n.a." label for any value not in the lookup table.
Source code in src/proconip/definitions.py
get_ntp_fault_state_as_str ¶
Decode ntp_fault_state to a human-readable label from NTP_FAULT_STATE.
For exact matches in the lookup table (0, 1, 2, 4,
65536) the corresponding label is returned. Composite states are
approximated by returning the highest-severity active bit (4 → 2 →
1), since the controller's CSV has no fixed combinations beyond the
listed ones. Falls back to "n.a." if no severity bit is set.
Source code in src/proconip/definitions.py
is_tcpip_boost_enabled ¶
is_sd_card_enabled ¶
is_dmx_enabled ¶
is_avatar_enabled ¶
is_relay_extension_enabled ¶
True if the external relay extension module is connected and active (bit 4).
Affects how determine_overall_relay_bit_state builds the ENA mask:
with the extension active, the mask covers all 16 bits instead of
just the internal 8.
Source code in src/proconip/definitions.py
is_high_bus_load_enabled ¶
is_flow_sensor_enabled ¶
is_repeated_mails_enabled ¶
is_dmx_extension_enabled ¶
True if the DMX extension module is enabled in the controller config (bit 8).
relays ¶
The eight built-in relays as Relay instances.
Equivalent to wrapping each entry in relay_objects with Relay(...).
digital_inputs ¶
The four digital inputs as DigitalInput instances.
Equivalent to wrapping each entry in digital_input_objects with
DigitalInput(...). Use these to get get_bit_mask() for triggering.
Source code in src/proconip/definitions.py
external_relays ¶
get_relay ¶
Return the Relay for the given aggregated relay ID (0–15).
| PARAMETER | DESCRIPTION |
|---|---|
relay_id
|
0–7 for internal relays, 8–15 for external relays.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Relay
|
A new |
| RAISES | DESCRIPTION |
|---|---|
IndexError
|
If |
Source code in src/proconip/definitions.py
get_relays ¶
determine_overall_relay_bit_state ¶
Build the two-element ENA bit field that represents the current relay state.
The controller's /usrcfg.cgi payload uses an ENA=enable_mask,on_mask
pair to set relay state. enable_mask selects which relays are in
manual mode (bit set = manual, bit clear = auto), and on_mask
selects the manual-on relays among them.
| RETURNS | DESCRIPTION |
|---|---|
list[int]
|
A two-element list |
list[int]
|
bits 0–7 (internal relays) by default, or bits 0–15 if the |
list[int]
|
external relay extension is enabled ( |
list[int]
|
The masks reflect the current state, so callers can flip a |
list[int]
|
single relay's bit and POST the result to switch only that |
list[int]
|
relay without touching the others. |
Source code in src/proconip/definitions.py
DmxChannelData ¶
A single DMX channel's index, name, and current value.
| ATTRIBUTE | DESCRIPTION |
|---|---|
value |
Current channel intensity, expected in the range [0, 255].
The constructor stores the value verbatim; clamping happens in
TYPE:
|
Source code in src/proconip/definitions.py
GetDmxData ¶
Mutable representation of all 16 DMX channels.
Construct from a /GetDmx.csv body, then read or modify channels via
indexing, iteration, get_value, or set. Pass the (possibly mutated)
instance to proconip.api.async_set_dmx to write the new state back.
Source code in src/proconip/definitions.py
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 | |
post_data
property
¶
Form payload that updates the DMX channel state via /usrcfg.cgi.
The dict has five keys, all required by the controller:
TYPE: always"0".LEN: always"16"(channels per write).CH1_8: comma-separated values for channels 1–8.CH9_16: comma-separated values for channels 9–16.DMX512: always"1".
URL-encode and join with & to produce the actual POST body — see
proconip.api.async_set_dmx for the canonical encoding.
get_value ¶
Return the current value of the channel at index.
Equivalent to self[index].value. Provided for symmetry with
set.
set ¶
Update the value of one channel.
Values outside the [0, 255] range are silently clamped — the controller's DMX hardware only accepts 8-bit values, so callers rarely need anything else.
| PARAMETER | DESCRIPTION |
|---|---|
index
|
Zero-based channel index (0 for channel 1, 15 for channel 16).
TYPE:
|
value
|
New intensity. Clamped to [0, 255].
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
IndexError
|
If |
Source code in src/proconip/definitions.py
BadRelayException ¶
Bases: Exception
Raised when a relay argument doesn't make sense in context.
The two main cases are: switching a dosage relay on directly (rejected
by proconip.api.async_switch_on), and passing a non-relay DataObject
to GetStateData.is_dosage_relay.
Source code in src/proconip/definitions.py
InvalidPayloadException ¶
Bases: Exception
Raised when a CSV response from the controller cannot be parsed.
Typically this means the response was empty, truncated, or did not have the expected number of CSV lines. Catching this lets callers distinguish protocol-level breakage from network errors.