python-omnilogic-local 0.15.2__py3-none-any.whl → 0.17.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pyomnilogic_local/api.py CHANGED
@@ -572,3 +572,44 @@ class OmniLogicAPI:
572
572
  req_body = ET.tostring(body_element, xml_declaration=True, encoding="unicode")
573
573
 
574
574
  return await self.async_send_message(MessageType.SET_SPILLOVER, req_body, False)
575
+
576
+ async def async_set_group_enable(
577
+ self,
578
+ group_id: int,
579
+ enabled: int | bool,
580
+ is_countdown_timer: bool = False,
581
+ start_time_hours: int = 0,
582
+ start_time_minutes: int = 0,
583
+ end_time_hours: int = 0,
584
+ end_time_minutes: int = 0,
585
+ days_active: int = 0,
586
+ recurring: bool = False,
587
+ ) -> None:
588
+ body_element = ET.Element("Request", {"xmlns": "http://nextgen.hayward.com/api"})
589
+
590
+ name_element = ET.SubElement(body_element, "Name")
591
+ name_element.text = "RunGroupCmd"
592
+
593
+ parameters_element = ET.SubElement(body_element, "Parameters")
594
+ parameter = ET.SubElement(parameters_element, "Parameter", name="GroupID", dataType="int")
595
+ parameter.text = str(group_id)
596
+ parameter = ET.SubElement(parameters_element, "Parameter", name="Data", dataType="int")
597
+ parameter.text = str(int(enabled))
598
+ parameter = ET.SubElement(parameters_element, "Parameter", name="IsCountDownTimer", dataType="bool")
599
+ parameter.text = str(int(is_countdown_timer))
600
+ parameter = ET.SubElement(parameters_element, "Parameter", name="StartTimeHours", dataType="int")
601
+ parameter.text = str(start_time_hours)
602
+ parameter = ET.SubElement(parameters_element, "Parameter", name="StartTimeMinutes", dataType="int")
603
+ parameter.text = str(start_time_minutes)
604
+ parameter = ET.SubElement(parameters_element, "Parameter", name="EndTimeHours", dataType="int")
605
+ parameter.text = str(end_time_hours)
606
+ parameter = ET.SubElement(parameters_element, "Parameter", name="EndTimeMinutes", dataType="int")
607
+ parameter.text = str(end_time_minutes)
608
+ parameter = ET.SubElement(parameters_element, "Parameter", name="DaysActive", dataType="int")
609
+ parameter.text = str(days_active)
610
+ parameter = ET.SubElement(parameters_element, "Parameter", name="Recurring", dataType="bool")
611
+ parameter.text = str(int(recurring))
612
+
613
+ req_body = ET.tostring(body_element, xml_declaration=True, encoding="unicode")
614
+
615
+ return await self.async_send_message(MessageType.RUN_GROUP_CMD, req_body, False)
File without changes
@@ -0,0 +1,25 @@
1
+ import asyncio
2
+
3
+ import click
4
+
5
+ from pyomnilogic_local.api import OmniLogicAPI
6
+ from pyomnilogic_local.cli.debug import commands as debug
7
+ from pyomnilogic_local.cli.get import commands as get
8
+
9
+
10
+ async def get_omni(host: str) -> OmniLogicAPI:
11
+ return OmniLogicAPI(host, 10444, 5.0)
12
+
13
+
14
+ @click.group()
15
+ @click.pass_context
16
+ @click.option("--host", default="127.0.0.1", help="Hostname or IP address of omnilogic system")
17
+ def entrypoint(ctx: click.Context, host: str) -> None:
18
+ ctx.ensure_object(dict)
19
+ omni = asyncio.run(get_omni(host))
20
+
21
+ ctx.obj["OMNI"] = omni
22
+
23
+
24
+ entrypoint.add_command(debug.debug)
25
+ entrypoint.add_command(get.get)
File without changes
@@ -0,0 +1,95 @@
1
+ # Need to figure out how to resolve the 'Untyped decorator makes function "..." untyped' errors in mypy when using click decorators
2
+ # mypy: disable-error-code="misc"
3
+ import asyncio
4
+ from typing import Literal, overload
5
+
6
+ import click
7
+
8
+ from pyomnilogic_local.api import OmniLogicAPI
9
+ from pyomnilogic_local.cli.utils import async_get_mspconfig, async_get_telemetry
10
+ from pyomnilogic_local.models.filter_diagnostics import FilterDiagnostics
11
+
12
+
13
+ @click.group()
14
+ @click.option("--raw/--no-raw", default=False, help="Output the raw XML from the OmniLogic, do not parse the response")
15
+ @click.pass_context
16
+ def debug(ctx: click.Context, raw: bool) -> None:
17
+ # Container for all get commands
18
+
19
+ ctx.ensure_object(dict)
20
+ ctx.obj["RAW"] = raw
21
+
22
+
23
+ @debug.command()
24
+ @click.pass_context
25
+ def get_mspconfig(ctx: click.Context) -> None:
26
+ mspconfig = asyncio.run(async_get_mspconfig(ctx.obj["OMNI"], ctx.obj["RAW"]))
27
+ click.echo(mspconfig)
28
+
29
+
30
+ @debug.command()
31
+ @click.pass_context
32
+ def get_telemetry(ctx: click.Context) -> None:
33
+ telemetry = asyncio.run(async_get_telemetry(ctx.obj["OMNI"], ctx.obj["RAW"]))
34
+ click.echo(telemetry)
35
+
36
+
37
+ @debug.command()
38
+ @click.pass_context
39
+ def get_alarm_list(ctx: click.Context) -> None:
40
+ alarm_list = asyncio.run(async_get_alarm_list(ctx.obj["OMNI"]))
41
+ click.echo(alarm_list)
42
+
43
+
44
+ async def async_get_alarm_list(omni: OmniLogicAPI) -> str:
45
+ alarm_list = await omni.async_get_alarm_list()
46
+ return alarm_list
47
+
48
+
49
+ @debug.command()
50
+ @click.option("--pool-id", help="System ID of the Body Of Water the filter is associated with")
51
+ @click.option("--filter-id", help="System ID of the filter to request diagnostics for")
52
+ @click.pass_context
53
+ def get_filter_diagnostics(ctx: click.Context, pool_id: int, filter_id: int) -> None:
54
+ filter_diags = asyncio.run(async_get_filter_diagnostics(ctx.obj["OMNI"], pool_id, filter_id, ctx.obj["RAW"]))
55
+ if ctx.obj["RAW"]:
56
+ click.echo(filter_diags)
57
+ else:
58
+ drv1 = chr(filter_diags.get_param_by_name("DriveFWRevisionB1"))
59
+ drv2 = chr(filter_diags.get_param_by_name("DriveFWRevisionB2"))
60
+ drv3 = chr(filter_diags.get_param_by_name("DriveFWRevisionB3"))
61
+ drv4 = chr(filter_diags.get_param_by_name("DriveFWRevisionB4"))
62
+ dfw1 = chr(filter_diags.get_param_by_name("DisplayFWRevisionB1"))
63
+ dfw2 = chr(filter_diags.get_param_by_name("DisplayFWRevisionB2"))
64
+ dfw3 = chr(filter_diags.get_param_by_name("DisplayFWRevisionB3"))
65
+ dfw4 = chr(filter_diags.get_param_by_name("DisplayFWRevisionB4"))
66
+ pow1 = filter_diags.get_param_by_name("PowerMSB")
67
+ pow2 = filter_diags.get_param_by_name("PowerLSB")
68
+ errs = filter_diags.get_param_by_name("ErrorStatus")
69
+ click.echo(
70
+ f"DRIVE FW REV: {drv1}{drv2}.{drv3}{drv4}\n"
71
+ f"DISPLAY FW REV: {dfw1}{dfw2}.{dfw3}.{dfw4}\n"
72
+ f"POWER: {pow1:x}{pow2:x}W\n"
73
+ f"ERROR STATUS: {errs}"
74
+ )
75
+
76
+
77
+ @overload
78
+ async def async_get_filter_diagnostics(omni: OmniLogicAPI, pool_id: int, filter_id: int, raw: Literal[True]) -> str: ...
79
+ @overload
80
+ async def async_get_filter_diagnostics(omni: OmniLogicAPI, pool_id: int, filter_id: int, raw: Literal[False]) -> FilterDiagnostics: ...
81
+ async def async_get_filter_diagnostics(omni: OmniLogicAPI, pool_id: int, filter_id: int, raw: bool) -> FilterDiagnostics | str:
82
+ filter_diags = await omni.async_get_filter_diagnostics(pool_id, filter_id, raw=raw)
83
+ return filter_diags
84
+
85
+
86
+ @debug.command()
87
+ @click.pass_context
88
+ def get_log_config(ctx: click.Context) -> None:
89
+ log_config = asyncio.run(async_get_log_config(ctx.obj["OMNI"]))
90
+ click.echo(log_config)
91
+
92
+
93
+ async def async_get_log_config(omni: OmniLogicAPI) -> str:
94
+ log_config = await omni.async_get_log_config()
95
+ return log_config
File without changes
@@ -0,0 +1,33 @@
1
+ # Need to figure out how to resolve the 'Untyped decorator makes function "..." untyped' errors in mypy when using click decorators
2
+ # mypy: disable-error-code="misc"
3
+ import asyncio
4
+
5
+ import click
6
+
7
+ from pyomnilogic_local.cli.utils import async_get_mspconfig
8
+
9
+
10
+ @click.group()
11
+ @click.pass_context
12
+ def get(ctx: click.Context) -> None:
13
+ # Container for all get commands
14
+
15
+ ctx.ensure_object(dict)
16
+
17
+
18
+ @get.command()
19
+ @click.pass_context
20
+ def lights(ctx: click.Context) -> None:
21
+ mspconfig = asyncio.run(async_get_mspconfig(ctx.obj["OMNI"]))
22
+ # Return data about lights in the backyard
23
+ if mspconfig.backyard.colorlogic_light:
24
+ for light in mspconfig.backyard.colorlogic_light:
25
+ click.echo(light)
26
+
27
+ # Return data about lights in the Body of Water
28
+ if mspconfig.backyard.bow:
29
+ for bow in mspconfig.backyard.bow:
30
+ if bow.colorlogic_light:
31
+ for cl_light in bow.colorlogic_light:
32
+ for k, v in cl_light:
33
+ click.echo(f"{k:15}\t{str(v)}")
@@ -0,0 +1,15 @@
1
+ from pyomnilogic_local.api import OmniLogicAPI
2
+ from pyomnilogic_local.models.mspconfig import MSPConfig
3
+ from pyomnilogic_local.models.telemetry import Telemetry
4
+
5
+
6
+ async def async_get_mspconfig(omni: OmniLogicAPI, raw: bool = False) -> MSPConfig:
7
+ mspconfig: MSPConfig
8
+ mspconfig = await omni.async_get_config(raw=raw)
9
+ return mspconfig
10
+
11
+
12
+ async def async_get_telemetry(omni: OmniLogicAPI, raw: bool = False) -> Telemetry:
13
+ telemetry: Telemetry
14
+ telemetry = await omni.async_get_telemetry(raw=raw)
15
+ return telemetry
@@ -23,6 +23,7 @@ class MessageType(Enum):
23
23
  GET_ALARM_LIST = 304
24
24
  SET_STANDALONE_LIGHT_SHOW = 308
25
25
  SET_SPILLOVER = 311
26
+ RUN_GROUP_CMD = 317
26
27
  RESTORE_IDLE_STATE = 340
27
28
  GET_FILTER_DIAGNOSTIC_INFO = 386
28
29
  HANDSHAKE = 1000
@@ -63,6 +64,9 @@ class OmniType(str, Enum):
63
64
  VALVE_ACTUATOR = "ValveActuator"
64
65
  VIRT_HEATER = "VirtualHeater"
65
66
 
67
+ def __str__(self) -> str:
68
+ return OmniType[self.name].value
69
+
66
70
 
67
71
  # Backyard/BoW
68
72
  class BackyardState(PrettyEnum):
@@ -172,6 +176,9 @@ class ColorLogicShow(PrettyEnum):
172
176
  WARM_WHITE = 25
173
177
  BRIGHT_YELLOW = 26
174
178
 
179
+ def __str__(self) -> str:
180
+ return self.name
181
+
175
182
 
176
183
  class ColorLogicPowerState(PrettyEnum):
177
184
  OFF = 0
@@ -187,6 +194,9 @@ class ColorLogicLightType(str, PrettyEnum):
187
194
  FOUR_ZERO = "COLOR_LOGIC_4_0"
188
195
  TWO_FIVE = "COLOR_LOGIC_2_5"
189
196
 
197
+ def __str__(self) -> str:
198
+ return ColorLogicLightType[self.name].value
199
+
190
200
 
191
201
  class CSADType(str, PrettyEnum):
192
202
  ACID = "ACID"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: python-omnilogic-local
3
- Version: 0.15.2
3
+ Version: 0.17.0
4
4
  Summary: A library for local control of Hayward OmniHub/OmniLogic pool controllers using their local API
5
5
  License: Apache-2.0
6
6
  Author: Chris Jowett
@@ -12,6 +12,7 @@ Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
14
  Classifier: Programming Language :: Python :: 3.13
15
+ Requires-Dist: click (>=8.0.0,<8.1.0)
15
16
  Requires-Dist: pydantic (>=1.10.17)
16
17
  Requires-Dist: xmltodict (>=0.13.0,<0.14.0)
17
18
  Description-Content-Type: text/markdown
@@ -0,0 +1,26 @@
1
+ pyomnilogic_local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ pyomnilogic_local/api.py,sha256=0yC7OMBUZfzBkBiLHT3QBA-B9m30conKzO9TDYruXLw,30540
3
+ pyomnilogic_local/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ pyomnilogic_local/cli/cli.py,sha256=JP3IIwMlV0CtJXa-Zr5Kp_HfzTG-N-B-TADDjPzErNY,633
5
+ pyomnilogic_local/cli/debug/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ pyomnilogic_local/cli/debug/commands.py,sha256=1G3I_qJzwby0zYnjofr_tCrT7D4XSw4TZK_ujX9ifkI,3747
7
+ pyomnilogic_local/cli/get/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ pyomnilogic_local/cli/get/commands.py,sha256=EE0WjN3sd9-bslothw4pMs7fi0czk1ACb4ZBSE5A1WQ,1034
9
+ pyomnilogic_local/cli/utils.py,sha256=b485Pe33bumwIOg4v_fmylZ6LN8Vh9cS6SRNaNpL5IE,532
10
+ pyomnilogic_local/cli_legacy.py,sha256=YsLPDuBUM9hDmSiYVfz0H346OtPUgRwiLHfKWUKbD7Q,3930
11
+ pyomnilogic_local/exceptions.py,sha256=7-EYTP-_VgGrA8WWGwQPUE1NGjJEDWB-ovyvSM2iaNY,164
12
+ pyomnilogic_local/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ pyomnilogic_local/models/const.py,sha256=j4HSiPJW5If296yJ-AiIsBI9EdlckF4QkVFIpTLb5C4,51
14
+ pyomnilogic_local/models/filter_diagnostics.py,sha256=74-VjHB-Rf6imeJTYawybA40_m_wb1Dww-Eu4ucGBdo,1577
15
+ pyomnilogic_local/models/leadmessage.py,sha256=XnzXTpLLQzhLQR1OgfAjKmW5N8BBgM7OrntUi1I2VRY,410
16
+ pyomnilogic_local/models/mspconfig.py,sha256=6YUz5e1V25KX0VynT6iwyZyzi8cPUvZwwLSY0M2bTV0,10594
17
+ pyomnilogic_local/models/telemetry.py,sha256=8ncC-10SRQneFmrH-LrnlVTS3Q-oqeXS_EtYKiIfDks,10612
18
+ pyomnilogic_local/models/util.py,sha256=X9jCiU3hFbI0Nc6NSCnvwyVK9XyA3BsiA9W7JYCJmKs,1462
19
+ pyomnilogic_local/omnitypes.py,sha256=31CvXH4FmyelTdZA7NAJQvkilho9qbIPwnymEEQ8d5Y,8067
20
+ pyomnilogic_local/protocol.py,sha256=M2vyj8o_PCKyLEswb6JGpUIdyj_swEJC18KrqcQV4kI,10356
21
+ pyomnilogic_local/util.py,sha256=sLkCn2eWbwP4FRiEgYlfmNxiHPeiWYjeUyvRRhWuNYE,359
22
+ python_omnilogic_local-0.17.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
23
+ python_omnilogic_local-0.17.0.dist-info/METADATA,sha256=bWu4U75I6FIZUh26EHazG8vpTxZUXGtIeyFcxgiRxio,2672
24
+ python_omnilogic_local-0.17.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
25
+ python_omnilogic_local-0.17.0.dist-info/entry_points.txt,sha256=We3r6ccF9wjWKBBSywFoYUJyL1TdGI1Pjw8-0L44kvw,66
26
+ python_omnilogic_local-0.17.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.0.0
2
+ Generator: poetry-core 2.0.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ omnilogic=pyomnilogic_local.cli.cli:entrypoint
3
+
@@ -1,19 +0,0 @@
1
- pyomnilogic_local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- pyomnilogic_local/api.py,sha256=G991ro3UM-ksVg9gGjTArOvZe41MWsSopbcyqPwwdsU,28390
3
- pyomnilogic_local/cli.py,sha256=YsLPDuBUM9hDmSiYVfz0H346OtPUgRwiLHfKWUKbD7Q,3930
4
- pyomnilogic_local/exceptions.py,sha256=7-EYTP-_VgGrA8WWGwQPUE1NGjJEDWB-ovyvSM2iaNY,164
5
- pyomnilogic_local/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- pyomnilogic_local/models/const.py,sha256=j4HSiPJW5If296yJ-AiIsBI9EdlckF4QkVFIpTLb5C4,51
7
- pyomnilogic_local/models/filter_diagnostics.py,sha256=74-VjHB-Rf6imeJTYawybA40_m_wb1Dww-Eu4ucGBdo,1577
8
- pyomnilogic_local/models/leadmessage.py,sha256=XnzXTpLLQzhLQR1OgfAjKmW5N8BBgM7OrntUi1I2VRY,410
9
- pyomnilogic_local/models/mspconfig.py,sha256=6YUz5e1V25KX0VynT6iwyZyzi8cPUvZwwLSY0M2bTV0,10594
10
- pyomnilogic_local/models/telemetry.py,sha256=8ncC-10SRQneFmrH-LrnlVTS3Q-oqeXS_EtYKiIfDks,10612
11
- pyomnilogic_local/models/util.py,sha256=X9jCiU3hFbI0Nc6NSCnvwyVK9XyA3BsiA9W7JYCJmKs,1462
12
- pyomnilogic_local/omnitypes.py,sha256=rmmBo1xKgsHsX9bjbBh-0YPv4lID1jGrNNU1W1m6zBo,7832
13
- pyomnilogic_local/protocol.py,sha256=M2vyj8o_PCKyLEswb6JGpUIdyj_swEJC18KrqcQV4kI,10356
14
- pyomnilogic_local/util.py,sha256=sLkCn2eWbwP4FRiEgYlfmNxiHPeiWYjeUyvRRhWuNYE,359
15
- python_omnilogic_local-0.15.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
16
- python_omnilogic_local-0.15.2.dist-info/METADATA,sha256=JnhXfISXcBHkTvEJjHfYPvhQcc_F2Nx1FvxZvaSqyfo,2634
17
- python_omnilogic_local-0.15.2.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
18
- python_omnilogic_local-0.15.2.dist-info/entry_points.txt,sha256=PUvdumqSijeB0dHH_s5oE2TnWtPWdJSNpSOsn8yTtOo,56
19
- python_omnilogic_local-0.15.2.dist-info/RECORD,,
@@ -1,3 +0,0 @@
1
- [console_scripts]
2
- omnilogic=pyomnilogic_local.cli:main
3
-
File without changes