|
| 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 | + MSPBoW, |
| 10 | + MSPConfig, |
| 11 | +) |
| 12 | +from pyomnilogic_local.models.telemetry import ( |
| 13 | + Telemetry, |
| 14 | + TelemetryType, |
| 15 | +) |
| 16 | +from pyomnilogic_local.omnitypes import ( |
| 17 | + BodyOfWaterType, |
| 18 | +) |
| 19 | + |
| 20 | + |
| 21 | +@click.command() |
| 22 | +@click.pass_context |
| 23 | +def bows(ctx: click.Context) -> None: |
| 24 | + """List all Bodies of Water (BOWs) and their current status. |
| 25 | +
|
| 26 | + Displays information about all bodies of water including their system IDs, |
| 27 | + names, types (pool/spa), water temperature, flow status, and attached equipment. |
| 28 | +
|
| 29 | + Example: |
| 30 | + omnilogic get bows |
| 31 | + """ |
| 32 | + mspconfig: MSPConfig = ctx.obj["MSPCONFIG"] |
| 33 | + telemetry: Telemetry = ctx.obj["TELEMETRY"] |
| 34 | + |
| 35 | + bows_found = False |
| 36 | + |
| 37 | + # Check for BOWs in the backyard |
| 38 | + if mspconfig.backyard.bow: |
| 39 | + for bow in mspconfig.backyard.bow: |
| 40 | + bows_found = True |
| 41 | + _print_bow_info(bow, telemetry.get_telem_by_systemid(bow.system_id)) |
| 42 | + |
| 43 | + if not bows_found: |
| 44 | + click.echo("No Bodies of Water found in the system configuration.") |
| 45 | + |
| 46 | + |
| 47 | +def _print_bow_info(bow: MSPBoW, telemetry: TelemetryType | None) -> None: |
| 48 | + """Format and print Body of Water information in a nice table format. |
| 49 | +
|
| 50 | + Args: |
| 51 | + bow: BOW object from MSPConfig with attributes to display |
| 52 | + telemetry: Telemetry object containing current state information |
| 53 | + """ |
| 54 | + click.echo("\n" + "=" * 60) |
| 55 | + click.echo("BODY OF WATER") |
| 56 | + click.echo("=" * 60) |
| 57 | + |
| 58 | + # Combine config and telemetry data |
| 59 | + bow_data: dict[Any, Any] = {**dict(bow), **dict(telemetry)} if telemetry else dict(bow) |
| 60 | + |
| 61 | + # Fields to exclude from main display (we'll show equipment counts instead) |
| 62 | + exclude_fields = {"filter", "relay", "heater", "sensor", "colorlogic_light", "pump", "chlorinator", "csad"} |
| 63 | + |
| 64 | + for attr_name, value in bow_data.items(): |
| 65 | + if attr_name in exclude_fields: |
| 66 | + continue |
| 67 | + |
| 68 | + if attr_name == "type": |
| 69 | + value = BodyOfWaterType(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 | + |
| 78 | + # Show equipment summary |
| 79 | + click.echo("\nAttached Equipment:") |
| 80 | + click.echo("-" * 60) |
| 81 | + |
| 82 | + equipment_counts = [] |
| 83 | + if bow.filter: |
| 84 | + equipment_counts.append(f"Filters: {len(bow.filter)}") |
| 85 | + if bow.pump: |
| 86 | + equipment_counts.append(f"Pumps: {len(bow.pump)}") |
| 87 | + if bow.heater: |
| 88 | + equipment_counts.append("Heater: 1 (virtual)") |
| 89 | + if bow.heater.heater_equipment: |
| 90 | + equipment_counts.append(f" - Physical Heaters: {len(bow.heater.heater_equipment)}") |
| 91 | + if bow.sensor: |
| 92 | + equipment_counts.append(f"Sensors: {len(bow.sensor)}") |
| 93 | + if bow.colorlogic_light: |
| 94 | + equipment_counts.append(f"ColorLogic Lights: {len(bow.colorlogic_light)}") |
| 95 | + if bow.relay: |
| 96 | + equipment_counts.append(f"Relays: {len(bow.relay)}") |
| 97 | + if bow.chlorinator: |
| 98 | + equipment_counts.append("Chlorinator: 1") |
| 99 | + if bow.csad: |
| 100 | + equipment_counts.append(f"CSADs: {len(bow.csad)}") |
| 101 | + |
| 102 | + if equipment_counts: |
| 103 | + for count in equipment_counts: |
| 104 | + click.echo(f" {count}") |
| 105 | + else: |
| 106 | + click.echo(" None") |
| 107 | + |
| 108 | + click.echo("=" * 60) |
0 commit comments