Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions pyomnilogic_local/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,54 @@ async def async_set_chlorinator_enable(self, pool_id: int, enabled: int | bool)

return await self.async_send_message(MessageType.SET_CHLOR_ENABLED, req_body, False)

# This is used to set the ORP target value on a CSAD
async def async_set_csad_orp_target_level(
self,
pool_id: int,
csad_id: int,
orp_target: int,
) -> None:
body_element = ET.Element("Request", {"xmlns": XML_NAMESPACE})

name_element = ET.SubElement(body_element, "Name")
name_element.text = "SetUICSADORPTargetLevel"

parameters_element = ET.SubElement(body_element, "Parameters")
parameter = ET.SubElement(parameters_element, "Parameter", name="PoolId", dataType="int")
parameter.text = str(pool_id)
parameter = ET.SubElement(parameters_element, "Parameter", name="CSADID", dataType="int", alias="EquipmentID")
parameter.text = str(csad_id)
parameter = ET.SubElement(parameters_element, "Parameter", name="ORPTargetValue", dataType="byte", alias="Data1")
parameter.text = str(orp_target)

req_body = ET.tostring(body_element, xml_declaration=True, encoding=XML_ENCODING)

return await self.async_send_message(MessageType.SET_CSAD_ORP_TARGET, req_body, False)

# This is used to set the pH target value on a CSAD
async def async_set_csad_target_value(
self,
pool_id: int,
csad_id: int,
ph_target: float,
) -> None:
body_element = ET.Element("Request", {"xmlns": XML_NAMESPACE})

name_element = ET.SubElement(body_element, "Name")
name_element.text = "UISetCSADTargetValue"

parameters_element = ET.SubElement(body_element, "Parameters")
parameter = ET.SubElement(parameters_element, "Parameter", name="PoolId", dataType="int")
parameter.text = str(pool_id)
parameter = ET.SubElement(parameters_element, "Parameter", name="CSADID", dataType="int", alias="EquipmentID")
parameter.text = str(csad_id)
parameter = ET.SubElement(parameters_element, "Parameter", name="TargetValue", dataType="float", alias="Data1")
parameter.text = str(ph_target)

req_body = ET.tostring(body_element, xml_declaration=True, encoding=XML_ENCODING)

return await self.async_send_message(MessageType.SET_CSAD_TARGET_VALUE, req_body, False)

async def async_set_chlorinator_params(
self,
pool_id: int,
Expand Down
79 changes: 79 additions & 0 deletions pyomnilogic_local/cli/debug/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,3 +319,82 @@ def set_chlor_params(ctx: click.Context, bow_id: int, equip_id: int, timed_perce
except Exception as e:
click.echo(f"Error setting chlorinator parameters: {e}", err=True)
raise click.Abort from e


@debug.command()
@click.argument("bow_id", type=int)
@click.argument("csad_id", type=int)
@click.argument("target", type=float)
@click.pass_context
def set_csad_ph(ctx: click.Context, bow_id: int, csad_id: int, target: float) -> None:
"""Set the pH target value for a CSAD (Chemical Sense and Dispense).

This command sets the target pH level that the CSAD will attempt to maintain.

BOW_ID: The Body of Water (pool/spa) system ID
CSAD_ID: The CSAD equipment system ID
TARGET: Target pH value (typically 7.0-8.0)

Examples:
# Set pH target to 7.4
omnilogic --host 192.168.1.100 debug set-csad-ph 7 20 7.4

# Set pH target to 7.2
omnilogic --host 192.168.1.100 debug set-csad-ph 7 20 7.2

"""
ensure_connection(ctx)
omni: OmniLogicAPI = ctx.obj["OMNI"]

# Validate target pH (typical range is 6.8-8.2, but allow wider range)
if not 0.0 <= target <= 14.0:
click.echo(f"Error: pH target must be between 0.0-14.0, got {target}", err=True)
raise click.Abort

# Execute the command
try:
asyncio.run(omni.async_set_csad_target_value(pool_id=bow_id, csad_id=csad_id, ph_target=target))
click.echo(f"Successfully set CSAD {csad_id} in BOW {bow_id} pH target to {target}")
except Exception as e:
click.echo(f"Error setting CSAD pH target: {e}", err=True)
raise click.Abort from e


@debug.command()
@click.argument("bow_id", type=int)
@click.argument("csad_id", type=int)
@click.argument("target", type=int)
@click.pass_context
def set_csad_orp(ctx: click.Context, bow_id: int, csad_id: int, target: int) -> None:
"""Set the ORP target level for a CSAD (Chemical Sense and Dispense).

This command sets the target ORP (Oxidation-Reduction Potential) level in
millivolts that the CSAD will attempt to maintain.

BOW_ID: The Body of Water (pool/spa) system ID
CSAD_ID: The CSAD equipment system ID
TARGET: Target ORP value in millivolts (typically 600-800 mV)

Examples:
# Set ORP target to 700 mV
omnilogic --host 192.168.1.100 debug set-csad-orp 7 20 700

# Set ORP target to 650 mV
omnilogic --host 192.168.1.100 debug set-csad-orp 7 20 650

"""
ensure_connection(ctx)
omni: OmniLogicAPI = ctx.obj["OMNI"]

# Validate target ORP (typical range is 400-900 mV, but allow 0-1000)
if not 0 <= target <= 1000:
click.echo(f"Error: ORP target must be between 0-1000 mV, got {target}", err=True)
raise click.Abort

# Execute the command
try:
asyncio.run(omni.async_set_csad_orp_target_level(pool_id=bow_id, csad_id=csad_id, orp_target=target))
click.echo(f"Successfully set CSAD {csad_id} in BOW {bow_id} ORP target to {target} mV")
except Exception as e:
click.echo(f"Error setting CSAD ORP target: {e}", err=True)
raise click.Abort from e
4 changes: 4 additions & 0 deletions pyomnilogic_local/omnitypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ class MessageType(IntEnum, PrettyEnum):
CREATE_SCHEDULE = 230
DELETE_SCHEDULE = 231
EDIT_SCHEDULE = 233
SET_CSAD_TARGET_VALUE = 253
SET_CSAD_ORP_TARGET = 281
GET_TELEMETRY = 300
GET_ALARM_LIST = 304
SET_STANDALONE_LIGHT_SHOW = 308
SET_SPILLOVER = 311
RUN_GROUP_CMD = 317
Expand All @@ -31,6 +34,7 @@ class MessageType(IntEnum, PrettyEnum):
ACK = 1002
MSP_TELEMETRY_UPDATE = 1004
MSP_CONFIGURATIONUPDATE = 1003
MSP_ALARM_LIST_RESPONSE = 1304
MSP_LEADMESSAGE = 1998
MSP_BLOCKMESSAGE = 1999

Expand Down