Skip to content

Commit b9092ab

Browse files
committed
feat: add more equipment to CLI get command
1 parent 11aa138 commit b9092ab

File tree

8 files changed

+478
-0
lines changed

8 files changed

+478
-0
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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+
4+
from typing import Any, cast
5+
6+
import click
7+
8+
from pyomnilogic_local.models.mspconfig import (
9+
MSPChlorinator,
10+
MSPConfig,
11+
)
12+
from pyomnilogic_local.models.telemetry import (
13+
Telemetry,
14+
TelemetryChlorinator,
15+
)
16+
from pyomnilogic_local.omnitypes import (
17+
ChlorinatorCellType,
18+
ChlorinatorDispenserType,
19+
ChlorinatorOperatingMode,
20+
)
21+
22+
23+
@click.command()
24+
@click.pass_context
25+
def chlorinators(ctx: click.Context) -> None:
26+
"""List all chlorinators and their current settings.
27+
28+
Displays information about all chlorinators including their system IDs, names,
29+
salt levels, operational status, alerts, and errors.
30+
31+
Example:
32+
omnilogic get chlorinators
33+
"""
34+
mspconfig: MSPConfig = ctx.obj["MSPCONFIG"]
35+
telemetry: Telemetry = ctx.obj["TELEMETRY"]
36+
37+
chlorinators_found = False
38+
39+
# Check for chlorinators in Bodies of Water
40+
if mspconfig.backyard.bow:
41+
for bow in mspconfig.backyard.bow:
42+
if bow.chlorinator:
43+
chlorinators_found = True
44+
_print_chlorinator_info(
45+
bow.chlorinator, cast(TelemetryChlorinator, telemetry.get_telem_by_systemid(bow.chlorinator.system_id))
46+
)
47+
48+
if not chlorinators_found:
49+
click.echo("No chlorinators found in the system configuration.")
50+
51+
52+
def _print_chlorinator_info(chlorinator: MSPChlorinator, telemetry: TelemetryChlorinator | None) -> None:
53+
"""Format and print chlorinator information in a nice table format.
54+
55+
Args:
56+
chlorinator: Chlorinator object from MSPConfig with attributes to display
57+
telemetry: Telemetry object containing current state information
58+
"""
59+
click.echo("\n" + "=" * 60)
60+
click.echo("CHLORINATOR")
61+
click.echo("=" * 60)
62+
63+
chlor_data: dict[Any, Any] = {**dict(chlorinator), **dict(telemetry)} if telemetry else dict(chlorinator)
64+
for attr_name, value in chlor_data.items():
65+
if attr_name == "cell_type":
66+
value = ChlorinatorCellType(value).pretty()
67+
elif attr_name == "dispenser_type":
68+
value = ChlorinatorDispenserType(value).pretty()
69+
elif attr_name == "operating_mode":
70+
value = ChlorinatorOperatingMode(value).pretty()
71+
elif attr_name in ("status", "alerts", "errors") and isinstance(value, list):
72+
# These are computed properties that return lists of flag names
73+
value = ", ".join(value) if value else "None"
74+
elif isinstance(value, list):
75+
# Format other lists nicely
76+
value = ", ".join(str(v) for v in value) if value else "None"
77+
78+
# Format the attribute name to be more readable
79+
display_name = attr_name.replace("_", " ").title()
80+
click.echo(f"{display_name:20} : {value}")
81+
click.echo("=" * 60)

pyomnilogic_local/cli/get/commands.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@
66
from pyomnilogic_local.cli import ensure_connection
77
from pyomnilogic_local.cli.get.backyard import backyard
88
from pyomnilogic_local.cli.get.bows import bows
9+
from pyomnilogic_local.cli.get.chlorinators import chlorinators
10+
from pyomnilogic_local.cli.get.csads import csads
911
from pyomnilogic_local.cli.get.filters import filters
12+
from pyomnilogic_local.cli.get.groups import groups
1013
from pyomnilogic_local.cli.get.heaters import heaters
1114
from pyomnilogic_local.cli.get.lights import lights
15+
from pyomnilogic_local.cli.get.pumps import pumps
16+
from pyomnilogic_local.cli.get.relays import relays
17+
from pyomnilogic_local.cli.get.sensors import sensors
1218
from pyomnilogic_local.cli.get.valves import valves
1319

1420

@@ -28,7 +34,13 @@ def get(ctx: click.Context) -> None:
2834
# Register subcommands
2935
get.add_command(backyard)
3036
get.add_command(bows)
37+
get.add_command(chlorinators)
38+
get.add_command(csads)
3139
get.add_command(filters)
40+
get.add_command(groups)
3241
get.add_command(heaters)
3342
get.add_command(lights)
43+
get.add_command(pumps)
44+
get.add_command(relays)
45+
get.add_command(sensors)
3446
get.add_command(valves)

pyomnilogic_local/cli/get/csads.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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+
4+
from typing import Any, cast
5+
6+
import click
7+
8+
from pyomnilogic_local.models.mspconfig import (
9+
MSPCSAD,
10+
MSPConfig,
11+
)
12+
from pyomnilogic_local.models.telemetry import (
13+
Telemetry,
14+
TelemetryCSAD,
15+
)
16+
from pyomnilogic_local.omnitypes import (
17+
CSADMode,
18+
CSADType,
19+
)
20+
21+
22+
@click.command()
23+
@click.pass_context
24+
def csads(ctx: click.Context) -> None:
25+
"""List all CSAD (Chemistry Sense and Dispense) systems and their current settings.
26+
27+
Displays information about all CSAD systems including their system IDs, names,
28+
current pH/ORP readings, mode, and target values.
29+
30+
Example:
31+
omnilogic get csads
32+
"""
33+
mspconfig: MSPConfig = ctx.obj["MSPCONFIG"]
34+
telemetry: Telemetry = ctx.obj["TELEMETRY"]
35+
36+
csads_found = False
37+
38+
# Check for CSADs in Bodies of Water
39+
if mspconfig.backyard.bow:
40+
for bow in mspconfig.backyard.bow:
41+
if bow.csad:
42+
for csad in bow.csad:
43+
csads_found = True
44+
_print_csad_info(csad, cast(TelemetryCSAD, telemetry.get_telem_by_systemid(csad.system_id)))
45+
46+
if not csads_found:
47+
click.echo("No CSAD systems found in the system configuration.")
48+
49+
50+
def _print_csad_info(csad: MSPCSAD, telemetry: TelemetryCSAD | None) -> None:
51+
"""Format and print CSAD information in a nice table format.
52+
53+
Args:
54+
csad: CSAD object from MSPConfig with attributes to display
55+
telemetry: Telemetry object containing current state information
56+
"""
57+
click.echo("\n" + "=" * 60)
58+
click.echo("CSAD (CHEMISTRY SENSE AND DISPENSE)")
59+
click.echo("=" * 60)
60+
61+
csad_data: dict[Any, Any] = {**dict(csad), **dict(telemetry)} if telemetry else dict(csad)
62+
for attr_name, value in csad_data.items():
63+
if attr_name == "equip_type":
64+
value = CSADType(value).pretty()
65+
elif attr_name == "mode":
66+
value = CSADMode(value).pretty()
67+
elif isinstance(value, list):
68+
# Format lists nicely
69+
value = ", ".join(str(v) for v in value) if value else "None"
70+
71+
# Format the attribute name to be more readable
72+
display_name = attr_name.replace("_", " ").title()
73+
click.echo(f"{display_name:20} : {value}")
74+
click.echo("=" * 60)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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+
4+
from typing import Any, cast
5+
6+
import click
7+
8+
from pyomnilogic_local.models.mspconfig import (
9+
MSPConfig,
10+
MSPGroup,
11+
)
12+
from pyomnilogic_local.models.telemetry import (
13+
Telemetry,
14+
TelemetryGroup,
15+
)
16+
from pyomnilogic_local.omnitypes import (
17+
GroupState,
18+
)
19+
20+
21+
@click.command()
22+
@click.pass_context
23+
def groups(ctx: click.Context) -> None:
24+
"""List all groups and their current settings.
25+
26+
Displays information about all groups including their system IDs, names,
27+
current state, and icon IDs.
28+
29+
Example:
30+
omnilogic get groups
31+
"""
32+
mspconfig: MSPConfig = ctx.obj["MSPCONFIG"]
33+
telemetry: Telemetry = ctx.obj["TELEMETRY"]
34+
35+
groups_found = False
36+
37+
# Check for groups at the top level
38+
if mspconfig.groups:
39+
for group in mspconfig.groups:
40+
groups_found = True
41+
_print_group_info(group, cast(TelemetryGroup, telemetry.get_telem_by_systemid(group.system_id)))
42+
43+
if not groups_found:
44+
click.echo("No groups found in the system configuration.")
45+
46+
47+
def _print_group_info(group: MSPGroup, telemetry: TelemetryGroup | None) -> None:
48+
"""Format and print group information in a nice table format.
49+
50+
Args:
51+
group: Group object from MSPConfig with attributes to display
52+
telemetry: Telemetry object containing current state information
53+
"""
54+
click.echo("\n" + "=" * 60)
55+
click.echo("GROUP")
56+
click.echo("=" * 60)
57+
58+
group_data: dict[Any, Any] = {**dict(group), **dict(telemetry)} if telemetry else dict(group)
59+
for attr_name, value in group_data.items():
60+
if attr_name == "bow_id":
61+
# Skip bow_id as it's not relevant for groups
62+
continue
63+
if attr_name == "state":
64+
value = GroupState(value).pretty()
65+
elif isinstance(value, list):
66+
# Format lists nicely
67+
value = ", ".join(str(v) for v in value) if value else "None"
68+
69+
# Format the attribute name to be more readable
70+
display_name = attr_name.replace("_", " ").title()
71+
click.echo(f"{display_name:20} : {value}")
72+
click.echo("=" * 60)

pyomnilogic_local/cli/get/pumps.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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+
4+
from typing import Any
5+
6+
import click
7+
8+
from pyomnilogic_local.models.mspconfig import (
9+
MSPConfig,
10+
MSPPump,
11+
)
12+
from pyomnilogic_local.models.telemetry import (
13+
Telemetry,
14+
TelemetryType,
15+
)
16+
from pyomnilogic_local.omnitypes import (
17+
PumpFunction,
18+
PumpState,
19+
PumpType,
20+
)
21+
22+
23+
@click.command()
24+
@click.pass_context
25+
def pumps(ctx: click.Context) -> None:
26+
"""List all pumps and their current settings.
27+
28+
Displays information about all pumps including their system IDs, names,
29+
current state, speed settings, and pump type.
30+
31+
Example:
32+
omnilogic get pumps
33+
"""
34+
mspconfig: MSPConfig = ctx.obj["MSPCONFIG"]
35+
telemetry: Telemetry = ctx.obj["TELEMETRY"]
36+
37+
pumps_found = False
38+
39+
# Check for pumps in Bodies of Water
40+
if mspconfig.backyard.bow:
41+
for bow in mspconfig.backyard.bow:
42+
if bow.pump:
43+
for pump in bow.pump:
44+
pumps_found = True
45+
_print_pump_info(pump, telemetry.get_telem_by_systemid(pump.system_id))
46+
47+
if not pumps_found:
48+
click.echo("No pumps found in the system configuration.")
49+
50+
51+
def _print_pump_info(pump: MSPPump, telemetry: TelemetryType | None) -> None:
52+
"""Format and print pump information in a nice table format.
53+
54+
Args:
55+
pump: Pump object from MSPConfig with attributes to display
56+
telemetry: Telemetry object containing current state information
57+
"""
58+
click.echo("\n" + "=" * 60)
59+
click.echo("PUMP")
60+
click.echo("=" * 60)
61+
62+
pump_data: dict[Any, Any] = {**dict(pump), **dict(telemetry)} if telemetry else dict(pump)
63+
for attr_name, value in pump_data.items():
64+
if attr_name == "state":
65+
value = PumpState(value).pretty()
66+
elif attr_name == "equip_type":
67+
value = PumpType(value).pretty()
68+
elif attr_name == "function":
69+
value = PumpFunction(value).pretty()
70+
elif isinstance(value, list):
71+
# Format lists nicely
72+
value = ", ".join(str(v) for v in value) if value else "None"
73+
74+
# Format the attribute name to be more readable
75+
display_name = attr_name.replace("_", " ").title()
76+
click.echo(f"{display_name:20} : {value}")
77+
click.echo("=" * 60)

0 commit comments

Comments
 (0)