Skip to content

feat: add chlorinator diagnostics - #154

Open
kmbulebu wants to merge 2 commits into
cryptk:mainfrom
kmbulebu:agent/chlorinator-diagnostics
Open

feat: add chlorinator diagnostics#154
kmbulebu wants to merge 2 commits into
cryptk:mainfrom
kmbulebu:agent/chlorinator-diagnostics

Conversation

@kmbulebu

Copy link
Copy Markdown

Adds requests for salt cell chlorinator measurements and relay polarity.

Parse cell voltage, current, cell and board temperatures, and instant and average salt levels while preserving the raw controller values.

Tested against my pool setup.

measurement = await api.async_get_chlorinator_measurement(
      pool_id=7,
      chlorinator_id=8,
  )

  print(f"Cell voltage: {measurement.voltage:.2f} V")
  print(f"Cell current: {measurement.current:.2f} A")
  print(f"Cell temperature: {measurement.cell_temperature_f:.1f} °F")
  print(f"Board temperature: {measurement.board_temperature_f:.1f} °F")
  print(f"Instant salt: {measurement.instant_salt_level} ppm")
  print(f"Average salt: {measurement.average_salt_level} ppm")

  polarity = await api.async_get_chlorinator_relay_polarity(
      pool_id=7,
      chlorinator_id=8,
  )

  print(f"Relay polarity: {polarity.relay_setting}")

Sample with chlorinator on:

  Cell voltage: 31.64 V
  Cell current: 0.36 A
  Cell temperature: 85.4 °F
  Board temperature: 119.5 °F
  Instant salt: 2869 ppm
  Average salt: 2936 ppm
  Relay polarity: 1

Sample with chlorinator off:

  Cell voltage: 0.00 V
  Cell current: 0.00 A
  Cell temperature: 0.0 °F
  Board temperature: 0.0 °F
  Instant salt: 0 ppm
  Average salt: 2900 ppm

kmbulebu added 2 commits July 19, 2026 17:32
Add local API requests for chlorinator measurements and relay polarity.

Parse cell voltage, current, cell and board temperatures, and instant and
average salt levels while preserving the raw controller values.
@sonarqubecloud

Copy link
Copy Markdown

"""Parse a chlorinator diagnostic XML response."""
data = xml_parse(xml, force_list=("Parameter",))
response_name = data.get("Response", {}).get("Name")
if response_name != cls.expected_response_name:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what the point of all of this work to set and verify response names is? Are you concerned that it might send a request and somehow get a response intended for a different request? That doesn't happen. The way the protocol works, every request sent to the Omni via the async_send_and_receive method creates it's own datagram endpoint (so it's own local port), so responses sent from the omni will be sent to a port specific to that request.

There are other (likely more efficient) ways to do this that I plan to look into in the future (involving using a single local port for sending and receiving responses, and matching responses with the transmitted message based on message IDs, etc), but for now, the fact that ever message sent uses a different local port disambiguates the responses.

Was there some other reason for this response_name matching that I'm just not seeing?

# Lookup table used by OmniLogic to convert the cell and board thermistor ADC
# readings to tenths of a degree Fahrenheit. Values between entries are
# interpolated using the low three bits of the raw reading.
_TEMPERATURE_TENTHS_F = (

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How were these values determined?

RUN_GROUP = 317
RESTORE_IDLE_STATE = 340
GET_FILTER_DIAGNOSTIC = 386
GET_DIAGNOSTIC = 386

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internally, the Omni refers to message type 386 as UI_GET_FILTER_DIAGNOSTIC, which is why I have it named GET_FILTER_DIAGNOSTIC here. Where possible, I attempt to align the names of things in the library to match the names used internally by the OmniLogic system. It helps me to keep things straight when I am cross referencing documentation and such.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants