|
| 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) |
0 commit comments