Skip to content

Commit 4cc07b2

Browse files
committed
button protocol and driver: Add a new protocol and driver for a Button
A button can be used to simulate pressing a physical button on a device. For example a DigitalOutputButtonDriver can be used when a reset button is connected via a relay to a DigitalOutput. In addition there are the ManualButtonDriver and ExternalButtonDriver drivers analogous to the ManualPowerDriver and ExternalPowerDriver drivers. Operations on a button include "press", "release", "press_for", and "get". Signed-off-by: Perry Melange <[email protected]>
1 parent 22f4b81 commit 4cc07b2

File tree

4 files changed

+131
-0
lines changed

4 files changed

+131
-0
lines changed

labgrid/driver/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
DigitalOutputPowerDriver, YKUSHPowerDriver, \
1717
USBPowerDriver, SiSPMPowerDriver, NetworkPowerDriver, \
1818
PDUDaemonDriver
19+
from .buttondriver import ManualButtonDriver, ExternalButtonDriver, \
20+
DigitalOutputButtonDriver
1921
from .usbloader import MXSUSBDriver, IMXUSBDriver, BDIMXUSBDriver, RKUSBDriver, UUUDriver
2022
from .usbsdmuxdriver import USBSDMuxDriver
2123
from .usbsdwiredriver import USBSDWireDriver

labgrid/driver/buttondriver.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import shlex
2+
import time
3+
4+
import attr
5+
6+
from ..factory import target_factory
7+
from ..protocol import ButtonProtocol, DigitalOutputProtocol
8+
from ..step import step
9+
from ..util.helper import processwrapper
10+
from .common import Driver
11+
12+
13+
@target_factory.reg_driver
14+
@attr.s(eq=False)
15+
class ManualButtonDriver(Driver, ButtonProtocol):
16+
"""ManualButtonDriver - Driver to tell the user to control a target's button"""
17+
18+
@Driver.check_active
19+
@step()
20+
def press(self):
21+
self.target.interact(
22+
f"Press and hold the button on target {self.target.name} and press enter"
23+
)
24+
25+
@Driver.check_active
26+
@step()
27+
def release(self):
28+
self.target.interact(
29+
f"Release the button on the target {self.target.name} press enter"
30+
)
31+
32+
@Driver.check_active
33+
@step()
34+
def press_for(self):
35+
self.target.interact(
36+
f"Press and then Release the button on target {self.target.name} for {self.delay} seconds and press enter"
37+
)
38+
39+
@target_factory.reg_driver
40+
@attr.s(eq=False)
41+
class ExternalButtonDriver(Driver, ButtonProtocol):
42+
"""ExternalButtonDriver - Driver using an external command to control a target's button"""
43+
cmd_press = attr.ib(validator=attr.validators.instance_of(str))
44+
cmd_release = attr.ib(validator=attr.validators.instance_of(str))
45+
cmd_press_for = attr.ib(validator=attr.validators.instance_of(str))
46+
delay = attr.ib(default=1.0, validator=attr.validators.instance_of(float))
47+
48+
@Driver.check_active
49+
@step()
50+
def press(self):
51+
cmd = shlex.split(self.cmd_press)
52+
processwrapper.check_output(cmd)
53+
54+
@Driver.check_active
55+
@step()
56+
def release(self):
57+
cmd = shlex.split(self.cmd_release)
58+
processwrapper.check_output(cmd)
59+
60+
@Driver.check_active
61+
@step()
62+
def press_for(self):
63+
if self.cmd_press_for is not None:
64+
cmd = shlex.split(self.cmd_press_for)
65+
processwrapper.check_output(cmd)
66+
else:
67+
self.press()
68+
time.sleep(self.delay)
69+
self.release()
70+
71+
@target_factory.reg_driver
72+
@attr.s(eq=False)
73+
class DigitalOutputButtonDriver(Driver, ButtonProtocol):
74+
"""
75+
DigitalOutputButtonDriver uses a DigitalOutput to control a button
76+
"""
77+
bindings = {"output": DigitalOutputProtocol, }
78+
delay = attr.ib(default=1.0, validator=attr.validators.instance_of(float))
79+
80+
def __attrs_post_init__(self):
81+
super().__attrs_post_init__()
82+
83+
@Driver.check_active
84+
@step()
85+
def press(self):
86+
self.output.set(True)
87+
88+
@Driver.check_active
89+
@step()
90+
def release(self):
91+
self.output.set(False)
92+
93+
@Driver.check_active
94+
@step()
95+
def press_for(self):
96+
self.press()
97+
time.sleep(self.delay)
98+
self.release()
99+
100+
@Driver.check_active
101+
@step()
102+
def get(self):
103+
return self.output.get()

labgrid/protocol/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from .consoleprotocol import ConsoleProtocol
44
from .linuxbootprotocol import LinuxBootProtocol
55
from .powerprotocol import PowerProtocol
6+
from .buttonprotocol import ButtonProtocol
67
from .filetransferprotocol import FileTransferProtocol
78
from .infoprotocol import InfoProtocol
89
from .digitaloutputprotocol import DigitalOutputProtocol

labgrid/protocol/buttonprotocol.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import abc
2+
3+
4+
class ButtonProtocol(abc.ABC):
5+
"""Abstract class providing the ButtonProtocol interface"""
6+
7+
@abc.abstractmethod
8+
def press(self):
9+
"""Implementations should "press and hold" the button."""
10+
raise NotImplementedError
11+
12+
@abc.abstractmethod
13+
def release(self):
14+
"""Implementations should "release" the button"""
15+
raise NotImplementedError
16+
17+
@abc.abstractmethod
18+
def press_for(self, time: float):
19+
"""Implementations should "press" the button for time seconds and then "release" the button again"""
20+
raise NotImplementedError
21+
22+
@abc.abstractmethod
23+
def get(self):
24+
"""Implementations should return the status of the button"""
25+
raise NotImplementedError

0 commit comments

Comments
 (0)