Coverage for /Users/ajo/work/jumpstarter/jumpstarter/packages/jumpstarter-driver-power/jumpstarter_driver_power/client.py: 35%
46 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-06 10:21 +0200
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-06 10:21 +0200
1import time
2from collections.abc import Generator
4import asyncclick as click
6from .common import PowerReading
7from jumpstarter.client import DriverClient
10class PowerClient(DriverClient):
11 def on(self) -> None:
12 self.call("on")
14 def off(self) -> None:
15 self.call("off")
17 def cycle(self, wait: int = 2):
18 """Power cycle the device"""
19 self.logger.info("Starting power cycle sequence")
20 self.off()
21 self.logger.info(f"Waiting {wait} seconds...")
22 time.sleep(wait)
23 self.on()
24 self.logger.info("Power cycle sequence complete")
26 def read(self) -> Generator[PowerReading, None, None]:
27 for v in self.streamingcall("read"):
28 yield PowerReading.model_validate(v, strict=True)
30 def cli(self):
31 @click.group
32 def base():
33 """Generic power"""
34 pass
36 @base.command()
37 def on():
38 """Power on"""
39 self.on()
41 @base.command()
42 def off():
43 """Power off"""
44 self.off()
46 @base.command()
47 @click.option("--wait", "-w", default=2, help="Wait time in seconds between off and on")
48 def cycle(wait):
49 """Power cycle"""
50 click.echo(f"Power cycling with {wait} seconds wait time...")
51 self.cycle(wait)
53 return base
56class VirtualPowerClient(PowerClient):
57 def off(self, destroy: bool = False) -> None:
58 self.call('off', destroy)
60 def cli(self):
61 parent = super().cli()
63 @parent.command(name='off')
64 @click.option('--destroy', is_flag=True, help='destroy the instance after powering it off')
65 def off(destroy: bool):
66 """Power off"""
67 self.off(destroy)
69 return parent