python-omnilogic-local 0.16.0__py3-none-any.whl → 0.18.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.
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
@@ -174,6 +174,12 @@ class MSPCSAD(OmniBase):
174
174
  calibration_value: float = Field(alias="CalibrationValue")
175
175
  ph_low_alarm_value: float = Field(alias="PHLowAlarmLevel")
176
176
  ph_high_alarm_value: float = Field(alias="PHHighAlarmLevel")
177
+ orp_target_level: int = Field(alias="ORP-Target-Level")
178
+ orp_runtime_level: int = Field(alias="ORP-Runtime-Level")
179
+ orp_low_alarm_level: int = Field(alias="ORP-Low-Alarm-Level")
180
+ orp_high_alarm_level: int = Field(alias="ORP-High-Alarm-Level")
181
+ orp_forced_on_time: int = Field(alias="ORP-Forced-On-Time")
182
+ orp_forced_enabled: bool = Field(alias="ORP-Forced-Enabled")
177
183
 
178
184
 
179
185
  class MSPColorLogicLight(OmniBase):
@@ -64,6 +64,9 @@ class OmniType(str, Enum):
64
64
  VALVE_ACTUATOR = "ValveActuator"
65
65
  VIRT_HEATER = "VirtualHeater"
66
66
 
67
+ def __str__(self) -> str:
68
+ return OmniType[self.name].value
69
+
67
70
 
68
71
  # Backyard/BoW
69
72
  class BackyardState(PrettyEnum):
@@ -173,6 +176,9 @@ class ColorLogicShow(PrettyEnum):
173
176
  WARM_WHITE = 25
174
177
  BRIGHT_YELLOW = 26
175
178
 
179
+ def __str__(self) -> str:
180
+ return self.name
181
+
176
182
 
177
183
  class ColorLogicPowerState(PrettyEnum):
178
184
  OFF = 0
@@ -188,6 +194,9 @@ class ColorLogicLightType(str, PrettyEnum):
188
194
  FOUR_ZERO = "COLOR_LOGIC_4_0"
189
195
  TWO_FIVE = "COLOR_LOGIC_2_5"
190
196
 
197
+ def __str__(self) -> str:
198
+ return ColorLogicLightType[self.name].value
199
+
191
200
 
192
201
  class CSADType(str, PrettyEnum):
193
202
  ACID = "ACID"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: python-omnilogic-local
3
- Version: 0.16.0
3
+ Version: 0.18.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=UgqWrAOcABlpIsBGzEmtWLEpHOe_vwMOfdnrCJz5yzg,10979
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.18.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
23
+ python_omnilogic_local-0.18.0.dist-info/METADATA,sha256=nMPRkiowV_ru3p5SjE41OMndPBlqobEYD_bf5OG1BWM,2672
24
+ python_omnilogic_local-0.18.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
25
+ python_omnilogic_local-0.18.0.dist-info/entry_points.txt,sha256=We3r6ccF9wjWKBBSywFoYUJyL1TdGI1Pjw8-0L44kvw,66
26
+ python_omnilogic_local-0.18.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=0yC7OMBUZfzBkBiLHT3QBA-B9m30conKzO9TDYruXLw,30540
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=GU1DN32vcOUMHA4rAj-OKQNhPncNGLbjzRANU9vVr8w,7856
13
- pyomnilogic_local/protocol.py,sha256=M2vyj8o_PCKyLEswb6JGpUIdyj_swEJC18KrqcQV4kI,10356
14
- pyomnilogic_local/util.py,sha256=sLkCn2eWbwP4FRiEgYlfmNxiHPeiWYjeUyvRRhWuNYE,359
15
- python_omnilogic_local-0.16.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
16
- python_omnilogic_local-0.16.0.dist-info/METADATA,sha256=3mfFKGti96Pdt8jP4awcvR0hXIoVhMGRuFwP5gCtE70,2634
17
- python_omnilogic_local-0.16.0.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
18
- python_omnilogic_local-0.16.0.dist-info/entry_points.txt,sha256=PUvdumqSijeB0dHH_s5oE2TnWtPWdJSNpSOsn8yTtOo,56
19
- python_omnilogic_local-0.16.0.dist-info/RECORD,,
@@ -1,3 +0,0 @@
1
- [console_scripts]
2
- omnilogic=pyomnilogic_local.cli:main
3
-
File without changes