python-omnilogic-local 0.16.0__py3-none-any.whl → 0.18.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- pyomnilogic_local/cli/__init__.py +0 -0
- pyomnilogic_local/cli/cli.py +25 -0
- pyomnilogic_local/cli/debug/__init__.py +0 -0
- pyomnilogic_local/cli/debug/commands.py +95 -0
- pyomnilogic_local/cli/get/__init__.py +0 -0
- pyomnilogic_local/cli/get/commands.py +33 -0
- pyomnilogic_local/cli/utils.py +15 -0
- pyomnilogic_local/models/mspconfig.py +6 -0
- pyomnilogic_local/omnitypes.py +9 -0
- {python_omnilogic_local-0.16.0.dist-info → python_omnilogic_local-0.18.0.dist-info}/METADATA +2 -1
- python_omnilogic_local-0.18.0.dist-info/RECORD +26 -0
- {python_omnilogic_local-0.16.0.dist-info → python_omnilogic_local-0.18.0.dist-info}/WHEEL +1 -1
- python_omnilogic_local-0.18.0.dist-info/entry_points.txt +3 -0
- python_omnilogic_local-0.16.0.dist-info/RECORD +0 -19
- python_omnilogic_local-0.16.0.dist-info/entry_points.txt +0 -3
- /pyomnilogic_local/{cli.py → cli_legacy.py} +0 -0
- {python_omnilogic_local-0.16.0.dist-info → python_omnilogic_local-0.18.0.dist-info}/LICENSE +0 -0
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):
|
pyomnilogic_local/omnitypes.py
CHANGED
@@ -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"
|
{python_omnilogic_local-0.16.0.dist-info → python_omnilogic_local-0.18.0.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: python-omnilogic-local
|
3
|
-
Version: 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,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,,
|
File without changes
|
File without changes
|