|
1 | 1 | import shlex
|
2 | 2 | import time
|
3 | 3 | import math
|
| 4 | +import ast |
4 | 5 | from importlib import import_module
|
5 | 6 |
|
6 | 7 | import attr
|
@@ -109,6 +110,81 @@ def get(self):
|
109 | 110 | return False
|
110 | 111 | raise ExecutionError(f"Did not find port status in sispmctl output ({repr(output)})")
|
111 | 112 |
|
| 113 | +@target_factory.reg_driver |
| 114 | +@attr.s(eq=False) |
| 115 | +class TenmaSerialDriver(Driver, PowerResetMixin, PowerProtocol): |
| 116 | + """TenmaSerialDriver - Driver using a Single Output Programmable to control a |
| 117 | + target's power using the tenma-serial tool https://github.com/kxtells/tenma-serial/""" |
| 118 | + |
| 119 | + bindings = {"port": {"TenmaSerialPort", "NetworkTenmaSerialPort"}, } |
| 120 | + delay = attr.ib(default=2.0, validator=attr.validators.instance_of(float)) |
| 121 | + ovp = attr.ib(default=False, validator=attr.validators.instance_of(bool)) |
| 122 | + ocp = attr.ib(default=False, validator=attr.validators.instance_of(bool)) |
| 123 | + voltage = attr.ib(default=12000, validator=attr.validators.instance_of(int)) |
| 124 | + current = attr.ib(default=2000, validator=attr.validators.instance_of(int)) |
| 125 | + |
| 126 | + def __attrs_post_init__(self): |
| 127 | + super().__attrs_post_init__() |
| 128 | + if self.target.env: |
| 129 | + self.tool = self.target.env.config.get_tool('tenma-control') |
| 130 | + else: |
| 131 | + self.tool = 'tenma-control' |
| 132 | + |
| 133 | + def _get_tenmaserial_prefix(self): |
| 134 | + options = [] |
| 135 | + |
| 136 | + # overvoltage protection (bool) |
| 137 | + if self.ovp: |
| 138 | + options.append('--ovp-enable') |
| 139 | + else: |
| 140 | + options.append('--ovp-disable') |
| 141 | + |
| 142 | + # overcurrent protection (bool) |
| 143 | + if self.ocp: |
| 144 | + options.append('--ocp-enable') |
| 145 | + else: |
| 146 | + options.append('--ocp-disable') |
| 147 | + |
| 148 | + # set mV (int) |
| 149 | + options.append(f'-v {self.voltage}') |
| 150 | + |
| 151 | + # set mA (int) |
| 152 | + options.append(f'-c {self.current}') |
| 153 | + |
| 154 | + return self.port.command_prefix + [ |
| 155 | + self.tool, |
| 156 | + str(self.port.path), |
| 157 | + ] + options |
| 158 | + |
| 159 | + @Driver.check_active |
| 160 | + @step() |
| 161 | + def on(self): |
| 162 | + cmd = ['--on'] |
| 163 | + processwrapper.check_output(self._get_tenmaserial_prefix() + cmd) |
| 164 | + |
| 165 | + @Driver.check_active |
| 166 | + @step() |
| 167 | + def off(self): |
| 168 | + cmd = ['--off'] |
| 169 | + processwrapper.check_output(self._get_tenmaserial_prefix() + cmd) |
| 170 | + |
| 171 | + @Driver.check_active |
| 172 | + @step() |
| 173 | + def cycle(self): |
| 174 | + self.off() |
| 175 | + time.sleep(self.delay) |
| 176 | + self.on() |
| 177 | + |
| 178 | + @Driver.check_active |
| 179 | + @step() |
| 180 | + def get(self): |
| 181 | + cmd = ['-S'] |
| 182 | + output = processwrapper.check_output(self._get_tenmaserial_prefix() + cmd) |
| 183 | + status = ast.literal_eval(output.decode('utf-8').strip().splitlines()[1]) |
| 184 | + if status['outEnabled']: |
| 185 | + return True |
| 186 | + else: |
| 187 | + return False |
112 | 188 |
|
113 | 189 | @target_factory.reg_driver
|
114 | 190 | @attr.s(eq=False)
|
|
0 commit comments