diff --git a/ipowerswitch.py b/ipowerswitch.py index 4d45876..9053e9a 100644 --- a/ipowerswitch.py +++ b/ipowerswitch.py @@ -1,10 +1,14 @@ import dataclasses import enum import logging +import re import typing +import bs4 import requests import requests.auth +import rich.console +import rich.table import typer import yarl @@ -55,8 +59,26 @@ class Switch: def switch_off(self, switch_id: int, outlet: int) -> None: return self.switch(switch_id, outlet, from_state=SwitchStatus.on) + def switch_status(self, switch_id: int) -> dict[int, SwitchStatus]: + url = yarl.URL(f"http://{self.address}").joinpath( + f"iswitch{switch_id:02d}", + "index.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["value"] for i in soup.find_all("input", type="hidden")} + outlets = int(inputs["OUTLET"]) + return { + outlet: SwitchStatus[inputs.get(f"STATUS{outlet}", "off").strip().lower()] + for outlet in range(1, outlets + 1) + } + app = typer.Typer() +console = rich.console.Console() SwitchIdArgument = typing.Annotated[int, typer.Argument(min=1, max=16)] OutletArgument = typing.Annotated[int, typer.Argument(min=1, max=8)] @@ -77,6 +99,20 @@ def switch( switch.switch_off(switch_id, outlet) +@app.command() +def status(context: typer.Context, switch_id: SwitchIdArgument) -> None: + switch: Switch = context.obj + statuses = switch.switch_status(switch_id) + if not console.is_interactive: + for key in sorted(statuses.keys()): + console.print(f"{key}\t{statuses[key].value.upper()}") + else: + table = rich.table.Table("Outlet", "Status") + for key in sorted(statuses.keys()): + table.add_row(str(key), statuses[key].value.upper()) + console.print(table) + + @app.callback() def main( context: typer.Context,