From 1e8e186394626aae1014276769a28d16ff83d805 Mon Sep 17 00:00:00 2001 From: Correl Roush Date: Tue, 12 Nov 2024 16:45:51 -0500 Subject: [PATCH] Add command to fetch switch configuration --- ipowerswitch.py | 85 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/ipowerswitch.py b/ipowerswitch.py index 9053e9a..0fc8ca9 100644 --- a/ipowerswitch.py +++ b/ipowerswitch.py @@ -18,6 +18,17 @@ class SwitchStatus(str, enum.Enum): off = "off" +@dataclasses.dataclass +class SwitchConfiguration: + outlet: int + name: str + power_resume_delay: int + ring_on_reset: bool + safe_shutdown: bool + safe_reboot: bool + shutdown_delay: int + + @dataclasses.dataclass class Switch: address: str @@ -76,6 +87,33 @@ class Switch: for outlet in range(1, outlets + 1) } + def switch_config(self, switch_id: int) -> dict[int, SwitchConfiguration]: + url = yarl.URL(f"http://{self.address}").joinpath( + f"iswitch{switch_id:02d}", + "config.htm", + ) + response = requests.get( + str(url), + auth=requests.auth.HTTPBasicAuth(self.user, self.password), + ) + soup = bs4.BeautifulSoup(response.content, features="html.parser") + inputs = {i["name"]: i for i in soup.find_all("input")} + outlets = int(inputs["OUTLET"]["value"]) + configs = {} + for outlet in range(1, outlets + 1): + letter = chr(ord("a") + (outlets - 1)) + config = SwitchConfiguration( + outlet=outlet, + name=inputs[f"T{outlet}"]["value"].strip(), + power_resume_delay=int(inputs[f"power_{letter}"]["value"]), + ring_on_reset=inputs[f"act{outlet}"].has_attr("checked"), + safe_shutdown=inputs[f"shut{outlet}"].has_attr("checked"), + safe_reboot=inputs[f"rbt{outlet}"].has_attr("checked"), + shutdown_delay=int(inputs[f"dlt{letter}"]["value"]), + ) + configs[outlet] = config + return configs + app = typer.Typer() console = rich.console.Console() @@ -113,6 +151,53 @@ def status(context: typer.Context, switch_id: SwitchIdArgument) -> None: console.print(table) +@app.command() +def config(context: typer.Context, switch_id: SwitchIdArgument) -> None: + switch: Switch = context.obj + configs = switch.switch_config(switch_id) + + def y_n(value: bool) -> str: + return "Y" if value else "N" + + if not console.is_interactive: + for key in sorted(configs.keys()): + config = configs[key] + console.print( + "\t".join( + [ + config.name, + str(config.power_resume_delay), + y_n(config.ring_on_reset), + y_n(config.safe_shutdown), + y_n(config.safe_reboot), + str(config.shutdown_delay), + ] + ) + ) + else: + table = rich.table.Table( + "Outlet", + "Name", + "Power Resume Delay", + "Ring On/Reset", + "Safe Shutdown/Reboot", + ) + for key in sorted(configs.keys()): + config = configs[key] + table.add_row( + str(key), + config.name, + f"{config.power_resume_delay} sec", + y_n(config.ring_on_reset), + "[{} / {}] {}".format( + y_n(config.safe_shutdown), + y_n(config.safe_reboot), + f"{config.shutdown_delay} sec", + ), + ) + console.print(table) + + @app.callback() def main( context: typer.Context,