pychemstation 0.10.10__py3-none-any.whl → 0.10.12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pychemstation/control/controllers/comm.py +1 -1
- pychemstation/control/controllers/data_aq/method.py +128 -211
- pychemstation/control/controllers/data_aq/sequence.py +74 -51
- pychemstation/control/controllers/devices/column.py +61 -0
- pychemstation/control/controllers/devices/dad.py +85 -0
- pychemstation/control/controllers/devices/injector.py +20 -12
- pychemstation/control/controllers/devices/pump.py +131 -0
- pychemstation/control/controllers/devices/sample_info.py +27 -0
- pychemstation/control/hplc.py +36 -12
- pychemstation/utils/abc_tables/device.py +17 -3
- pychemstation/utils/abc_tables/table.py +166 -75
- pychemstation/utils/device_types.py +66 -0
- pychemstation/utils/macro.py +2 -0
- pychemstation/utils/table_types.py +65 -8
- {pychemstation-0.10.10.dist-info → pychemstation-0.10.12.dist-info}/METADATA +2 -2
- {pychemstation-0.10.10.dist-info → pychemstation-0.10.12.dist-info}/RECORD +18 -14
- {pychemstation-0.10.10.dist-info → pychemstation-0.10.12.dist-info}/WHEEL +0 -0
- {pychemstation-0.10.10.dist-info → pychemstation-0.10.12.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
from typing import List, Dict
|
2
|
+
|
3
|
+
from ....control.controllers import CommunicationController
|
4
|
+
from ....utils.abc_tables.device import DeviceController
|
5
|
+
from ....utils.macro import Command
|
6
|
+
from ....utils.method_types import Param, PType
|
7
|
+
from ....utils.table_types import Device, Table, RegisterFlag
|
8
|
+
|
9
|
+
|
10
|
+
class ColumnController(DeviceController):
|
11
|
+
def __init__(
|
12
|
+
self, controller: CommunicationController, table: Table | Device, offline: bool
|
13
|
+
):
|
14
|
+
super().__init__(controller, table, offline)
|
15
|
+
if not self.offline:
|
16
|
+
self.display_to_internal: Dict[str, str] = {
|
17
|
+
display_name: real_name
|
18
|
+
for display_name, real_name in zip(
|
19
|
+
self.check_available_column_positions(),
|
20
|
+
self._internal_column_positions(),
|
21
|
+
)
|
22
|
+
}
|
23
|
+
self.internal_to_display: Dict[str, str] = dict(
|
24
|
+
map(reversed, self.display_to_internal.items()) # type: ignore
|
25
|
+
)
|
26
|
+
|
27
|
+
def check_column_position(self):
|
28
|
+
return self.internal_to_display[
|
29
|
+
self._read_str_param(register_flag=RegisterFlag.COLUMN_POSITION)
|
30
|
+
]
|
31
|
+
|
32
|
+
def _internal_column_positions(self) -> List[str]:
|
33
|
+
return self._read_str_param(
|
34
|
+
register_flag=RegisterFlag.AVAIL_COLUMN_POSITIONS
|
35
|
+
).split("|")
|
36
|
+
|
37
|
+
def check_available_column_positions(self) -> List[str]:
|
38
|
+
return self._read_str_param(
|
39
|
+
register_flag=RegisterFlag.AVAIL_COLUMN_DISPLAY_VALUES
|
40
|
+
).split("|")
|
41
|
+
|
42
|
+
def change_column_position(self, column: str):
|
43
|
+
if column not in self.display_to_internal.keys():
|
44
|
+
raise ValueError(f"Please use one of: {self.display_to_internal.keys()}")
|
45
|
+
self._update_param(
|
46
|
+
Param(
|
47
|
+
ptype=PType.STR,
|
48
|
+
chemstation_key=RegisterFlag.COLUMN_POSITION,
|
49
|
+
val=self.display_to_internal[column],
|
50
|
+
),
|
51
|
+
)
|
52
|
+
|
53
|
+
def turn_off(self):
|
54
|
+
self.sleepy_send(Command.COLUMN_OFF_CMD)
|
55
|
+
pass
|
56
|
+
|
57
|
+
def turn_on(self):
|
58
|
+
self.sleepy_send(Command.COLUMN_ON_CMD)
|
59
|
+
|
60
|
+
def download(self):
|
61
|
+
self.sleepy_send("DownloadRCMethod THM1")
|
@@ -0,0 +1,85 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import warnings
|
4
|
+
|
5
|
+
from ...controllers import CommunicationController
|
6
|
+
from ....utils.abc_tables.device import DeviceController
|
7
|
+
from ....utils.device_types import DADChannels, DADChannel
|
8
|
+
from ....utils.macro import Command
|
9
|
+
from ....utils.method_types import Param, PType
|
10
|
+
from ....utils.table_types import RegisterFlag, Table, Device
|
11
|
+
|
12
|
+
|
13
|
+
class DADController(DeviceController):
|
14
|
+
def __init__(
|
15
|
+
self, controller: CommunicationController, table: Table | Device, offline: bool
|
16
|
+
):
|
17
|
+
super().__init__(controller, table, offline)
|
18
|
+
|
19
|
+
def download(self):
|
20
|
+
self.sleepy_send("DownloadRCMethod DAD1")
|
21
|
+
|
22
|
+
def turn_off(self):
|
23
|
+
self.send(Command.LAMP_OFF_CMD)
|
24
|
+
|
25
|
+
def turn_on(self):
|
26
|
+
self.send(Command.LAMP_ON_CMD)
|
27
|
+
|
28
|
+
def load_wavelengths(self) -> DADChannels:
|
29
|
+
return DADChannels(
|
30
|
+
A=self._read_num_param(RegisterFlag.SIGNAL_A),
|
31
|
+
A_ON=bool(self._read_num_param(RegisterFlag.SIGNAL_A_USED)),
|
32
|
+
B=self._read_num_param(RegisterFlag.SIGNAL_B),
|
33
|
+
B_ON=bool(self._read_num_param(RegisterFlag.SIGNAL_B_USED)),
|
34
|
+
C=self._read_num_param(RegisterFlag.SIGNAL_C),
|
35
|
+
C_ON=bool(self._read_num_param(RegisterFlag.SIGNAL_C_USED)),
|
36
|
+
D=self._read_num_param(RegisterFlag.SIGNAL_D),
|
37
|
+
D_ON=bool(self._read_num_param(RegisterFlag.SIGNAL_D_USED)),
|
38
|
+
E=self._read_num_param(RegisterFlag.SIGNAL_E),
|
39
|
+
E_ON=bool(self._read_num_param(RegisterFlag.SIGNAL_E_USED)),
|
40
|
+
)
|
41
|
+
|
42
|
+
def edit_wavelength(self, signal: int, wavelength: DADChannel):
|
43
|
+
warnings.warn("You may need to check that the wavelength is calibrated.")
|
44
|
+
register = RegisterFlag.SIGNAL_A
|
45
|
+
match wavelength:
|
46
|
+
case DADChannel.A:
|
47
|
+
register = RegisterFlag.SIGNAL_A
|
48
|
+
case DADChannel.B:
|
49
|
+
register = RegisterFlag.SIGNAL_B
|
50
|
+
case DADChannel.C:
|
51
|
+
register = RegisterFlag.SIGNAL_C
|
52
|
+
case DADChannel.D:
|
53
|
+
register = RegisterFlag.SIGNAL_D
|
54
|
+
case DADChannel.E:
|
55
|
+
register = RegisterFlag.SIGNAL_E
|
56
|
+
self._update_param(
|
57
|
+
Param(
|
58
|
+
ptype=PType.NUM,
|
59
|
+
val=signal,
|
60
|
+
chemstation_key=register,
|
61
|
+
)
|
62
|
+
)
|
63
|
+
self.download()
|
64
|
+
|
65
|
+
def set_wavelength_usage(self, wavelength: DADChannel, on: bool):
|
66
|
+
register = RegisterFlag.SIGNAL_A_USED
|
67
|
+
match wavelength:
|
68
|
+
case DADChannel.A:
|
69
|
+
register = RegisterFlag.SIGNAL_A_USED
|
70
|
+
case DADChannel.B:
|
71
|
+
register = RegisterFlag.SIGNAL_B_USED
|
72
|
+
case DADChannel.C:
|
73
|
+
register = RegisterFlag.SIGNAL_C_USED
|
74
|
+
case DADChannel.D:
|
75
|
+
register = RegisterFlag.SIGNAL_D_USED
|
76
|
+
case DADChannel.E:
|
77
|
+
register = RegisterFlag.SIGNAL_E_USED
|
78
|
+
self._update_param(
|
79
|
+
Param(
|
80
|
+
ptype=PType.NUM,
|
81
|
+
val=int(on),
|
82
|
+
chemstation_key=register,
|
83
|
+
)
|
84
|
+
)
|
85
|
+
self.download()
|
@@ -1,5 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
import warnings
|
4
|
+
|
3
5
|
from ....control.controllers import CommunicationController
|
4
6
|
from ....utils.abc_tables.device import DeviceController
|
5
7
|
from ....utils.injector_types import (
|
@@ -15,7 +17,7 @@ from ....utils.injector_types import (
|
|
15
17
|
DrawDefaultVolume,
|
16
18
|
DrawDefaultLocation,
|
17
19
|
)
|
18
|
-
from ....utils.
|
20
|
+
from ....utils.method_types import Param, PType
|
19
21
|
from ....utils.table_types import RegisterFlag, Table
|
20
22
|
from ....utils.tray_types import Tray, FiftyFourVialPlate, VialBar, LocationPlus
|
21
23
|
|
@@ -26,6 +28,21 @@ class InjectorController(DeviceController):
|
|
26
28
|
):
|
27
29
|
super().__init__(controller, table, offline)
|
28
30
|
|
31
|
+
def turn_off(self):
|
32
|
+
warnings.warn("Injector has no on/off state.")
|
33
|
+
|
34
|
+
def turn_on(self):
|
35
|
+
warnings.warn("Injector has no on/off state.")
|
36
|
+
|
37
|
+
def change_injection_volume(self, new_injection_volume: float):
|
38
|
+
self._update_param(
|
39
|
+
param=Param(
|
40
|
+
ptype=PType.NUM,
|
41
|
+
val=new_injection_volume,
|
42
|
+
chemstation_key=RegisterFlag.INJECTION_VOLUME,
|
43
|
+
)
|
44
|
+
)
|
45
|
+
|
29
46
|
def try_vial_location(self, val: str) -> Tray:
|
30
47
|
try:
|
31
48
|
return FiftyFourVialPlate.from_str(val)
|
@@ -93,14 +110,5 @@ class InjectorController(DeviceController):
|
|
93
110
|
raise ValueError("No valid function found.")
|
94
111
|
|
95
112
|
def load(self) -> InjectorTable | None:
|
96
|
-
rows = self.
|
97
|
-
|
98
|
-
row_response = rows.value
|
99
|
-
if isinstance(row_response, Response):
|
100
|
-
return InjectorTable(
|
101
|
-
functions=[
|
102
|
-
self.get_row(i + 1)
|
103
|
-
for i in range(int(row_response.num_response))
|
104
|
-
]
|
105
|
-
)
|
106
|
-
raise ValueError("Couldn't read injector table rows.")
|
113
|
+
rows = self.get_row_count_safely()
|
114
|
+
return InjectorTable(functions=[self.get_row(i + 1) for i in range(rows)])
|
@@ -0,0 +1,131 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import warnings
|
4
|
+
|
5
|
+
from ....utils.macro import Command
|
6
|
+
from ....control.controllers import CommunicationController
|
7
|
+
from ....utils.abc_tables.device import DeviceController
|
8
|
+
from ....utils.device_types import (
|
9
|
+
SolventBottle,
|
10
|
+
MaybeBottle,
|
11
|
+
MaybePumpPosition,
|
12
|
+
PumpValve,
|
13
|
+
PumpPosition,
|
14
|
+
)
|
15
|
+
from ....utils.table_types import Table, RegisterFlag, Device
|
16
|
+
|
17
|
+
|
18
|
+
class PumpController(DeviceController):
|
19
|
+
def __init__(
|
20
|
+
self, controller: CommunicationController, table: Table | Device, offline: bool
|
21
|
+
):
|
22
|
+
super().__init__(controller, table, offline)
|
23
|
+
self.A_position: MaybePumpPosition = (
|
24
|
+
self.load_pump_position(PumpValve.A) if not offline else None
|
25
|
+
)
|
26
|
+
self.B_position: MaybePumpPosition = (
|
27
|
+
self.load_pump_position(PumpValve.B) if not offline else None
|
28
|
+
)
|
29
|
+
self.A1: MaybeBottle = None
|
30
|
+
self.A2: MaybeBottle = None
|
31
|
+
self.B1: MaybeBottle = None
|
32
|
+
self.B2: MaybeBottle = None
|
33
|
+
self.waste_bottle: MaybeBottle = None
|
34
|
+
|
35
|
+
def load_pump_position(self, pump_valve: PumpValve) -> PumpPosition:
|
36
|
+
match pump_valve:
|
37
|
+
case PumpValve.A:
|
38
|
+
return PumpPosition.from_str(
|
39
|
+
self._read_str_param(RegisterFlag.PUMPCHANNEL_SELECTION)
|
40
|
+
)
|
41
|
+
case PumpValve.B:
|
42
|
+
return PumpPosition.from_str(
|
43
|
+
self._read_str_param(RegisterFlag.PUMPCHANNEL2_SELECTION)
|
44
|
+
)
|
45
|
+
case _:
|
46
|
+
raise ValueError("Expected one of PumpValve.A or PumpValve.B")
|
47
|
+
|
48
|
+
def load_bottles(self):
|
49
|
+
self.A1 = self.get_solvent_bottle_a1()
|
50
|
+
self.A2 = self.get_solvent_bottle_a2()
|
51
|
+
self.B1 = self.get_solvent_bottle_b1()
|
52
|
+
self.B2 = self.get_solvent_bottle_b2()
|
53
|
+
|
54
|
+
@property
|
55
|
+
def rinse_method(self):
|
56
|
+
return self._rinse_method
|
57
|
+
|
58
|
+
@rinse_method.setter
|
59
|
+
def rinse_method(self, new_rinse_method: str):
|
60
|
+
self._rinse_method = new_rinse_method
|
61
|
+
|
62
|
+
def turn_off(self):
|
63
|
+
self.send(Command.PUMP_OFF_CMD)
|
64
|
+
|
65
|
+
def turn_on(self):
|
66
|
+
self.send(Command.PUMP_ON_CMD)
|
67
|
+
|
68
|
+
def get_solvent_bottle_a1(self) -> SolventBottle:
|
69
|
+
return SolventBottle(
|
70
|
+
absolute_filled=self._read_num_param(
|
71
|
+
RegisterFlag.BOTTLE_A1_ABSOLUTE_FILLING
|
72
|
+
),
|
73
|
+
percent_filled=self._read_num_param(RegisterFlag.BOTTLE_A1_PERCENT_FILLING),
|
74
|
+
max_volume=self._read_num_param(RegisterFlag.BOTTLE_A1_MAX),
|
75
|
+
in_use=self.A_position == PumpPosition.ONE,
|
76
|
+
user_name=self._read_str_param(RegisterFlag.BOTTLE_A1_USER_NAME),
|
77
|
+
type=PumpValve.A,
|
78
|
+
)
|
79
|
+
|
80
|
+
def get_solvent_bottle_a2(self) -> SolventBottle:
|
81
|
+
return SolventBottle(
|
82
|
+
absolute_filled=self._read_num_param(
|
83
|
+
RegisterFlag.BOTTLE_A2_ABSOLUTE_FILLING
|
84
|
+
),
|
85
|
+
percent_filled=self._read_num_param(RegisterFlag.BOTTLE_A2_PERCENT_FILLING),
|
86
|
+
max_volume=self._read_num_param(RegisterFlag.BOTTLE_A2_MAX),
|
87
|
+
in_use=self.A_position == PumpPosition.TWO,
|
88
|
+
user_name=self._read_str_param(RegisterFlag.BOTTLE_A2_USER_NAME),
|
89
|
+
type=PumpValve.A,
|
90
|
+
)
|
91
|
+
|
92
|
+
def get_solvent_bottle_b1(self) -> SolventBottle:
|
93
|
+
return SolventBottle(
|
94
|
+
absolute_filled=self._read_num_param(
|
95
|
+
RegisterFlag.BOTTLE_B1_ABSOLUTE_FILLING
|
96
|
+
),
|
97
|
+
percent_filled=self._read_num_param(RegisterFlag.BOTTLE_B1_PERCENT_FILLING),
|
98
|
+
max_volume=self._read_num_param(RegisterFlag.BOTTLE_B1_MAX),
|
99
|
+
in_use=self.A_position == PumpPosition.ONE,
|
100
|
+
user_name=self._read_str_param(RegisterFlag.BOTTLE_B1_USER_NAME),
|
101
|
+
type=PumpValve.B,
|
102
|
+
)
|
103
|
+
|
104
|
+
def get_solvent_bottle_b2(self) -> SolventBottle:
|
105
|
+
return SolventBottle(
|
106
|
+
absolute_filled=self._read_num_param(
|
107
|
+
RegisterFlag.BOTTLE_B2_ABSOLUTE_FILLING
|
108
|
+
),
|
109
|
+
percent_filled=self._read_num_param(RegisterFlag.BOTTLE_B2_PERCENT_FILLING),
|
110
|
+
max_volume=self._read_num_param(RegisterFlag.BOTTLE_B2_MAX),
|
111
|
+
in_use=self.A_position == PumpPosition.TWO,
|
112
|
+
user_name=self._read_str_param(RegisterFlag.BOTTLE_B2_USER_NAME),
|
113
|
+
type=PumpValve.B,
|
114
|
+
)
|
115
|
+
|
116
|
+
def get_waste_bottle_stats(self):
|
117
|
+
max_vol = None
|
118
|
+
try:
|
119
|
+
max_vol = self._read_num_param(RegisterFlag.WASTE_BOTTLE_MAX)
|
120
|
+
except RuntimeError:
|
121
|
+
warnings.warn(
|
122
|
+
"No maximum volume available! All other SolventBottle parameters may not be reliable."
|
123
|
+
)
|
124
|
+
self.waste_bottle = SolventBottle(
|
125
|
+
absolute_filled=self._read_num_param(RegisterFlag.WASTE_BOTTLE_PERCENT),
|
126
|
+
percent_filled=self._read_num_param(RegisterFlag.WASTE_BOTTLE_ABSOLUTE),
|
127
|
+
max_volume=max_vol,
|
128
|
+
in_use=True,
|
129
|
+
user_name="Waste Bottle",
|
130
|
+
type=None,
|
131
|
+
)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
from ....control.controllers import CommunicationController
|
2
|
+
from ....utils.abc_tables.device import DeviceController
|
3
|
+
from ....utils.table_types import Table, Device, RegisterFlag
|
4
|
+
from ....utils.tray_types import Tray, VialBar, FiftyFourVialPlate
|
5
|
+
|
6
|
+
|
7
|
+
class SampleInfo(DeviceController):
|
8
|
+
def turn_off(self):
|
9
|
+
raise NotImplementedError
|
10
|
+
|
11
|
+
def turn_on(self):
|
12
|
+
raise NotImplementedError
|
13
|
+
|
14
|
+
def __init__(
|
15
|
+
self, controller: CommunicationController, table: Table | Device, offline: bool
|
16
|
+
):
|
17
|
+
super().__init__(controller, table, offline)
|
18
|
+
|
19
|
+
def get_location(self) -> Tray:
|
20
|
+
location = self._read_str_param(RegisterFlag.VIAL_NUMBER)
|
21
|
+
try:
|
22
|
+
return FiftyFourVialPlate.from_int(location)
|
23
|
+
except ValueError:
|
24
|
+
try:
|
25
|
+
return VialBar(location)
|
26
|
+
except ValueError:
|
27
|
+
raise ValueError("Could not read vial location.")
|
pychemstation/control/hplc.py
CHANGED
@@ -9,19 +9,20 @@ from __future__ import annotations
|
|
9
9
|
import os.path
|
10
10
|
from typing import Dict, List, Optional, Tuple, Union
|
11
11
|
|
12
|
-
from
|
13
|
-
from
|
14
|
-
AgilentHPLCChromatogram,
|
15
|
-
)
|
12
|
+
from .controllers.devices.column import ColumnController
|
13
|
+
from .controllers.devices.dad import DADController
|
16
14
|
from .controllers.devices.injector import InjectorController
|
17
15
|
from .controllers.data_aq.sequence import SequenceController, MethodController
|
16
|
+
from .controllers.devices.pump import PumpController
|
17
|
+
from .controllers.devices.sample_info import SampleInfo
|
18
|
+
from ..analysis import AgilentHPLCChromatogram, AgilentChannelChromatogramData
|
18
19
|
from ..analysis.process_report import AgilentReport, ReportType
|
19
20
|
from ..control.controllers import CommunicationController
|
20
21
|
from ..utils.injector_types import InjectorTable
|
21
22
|
from ..utils.macro import Command, Response, Status
|
22
23
|
from ..utils.method_types import MethodDetails
|
23
24
|
from ..utils.sequence_types import SequenceTable, SequenceDataFiles
|
24
|
-
from ..utils.table_types import Table
|
25
|
+
from ..utils.table_types import Table, Device
|
25
26
|
|
26
27
|
|
27
28
|
class HPLCController:
|
@@ -32,7 +33,15 @@ class HPLCController:
|
|
32
33
|
|
33
34
|
INJECTOR_TABLE = Table(register="RCWLS1Pretreatment[1]", name="InstructionTable")
|
34
35
|
|
35
|
-
|
36
|
+
PUMP_DEVICE = Device(register="RCPMP1Status")
|
37
|
+
|
38
|
+
INJECTOR_DEVICE = Device(register="RCWLS1Method")
|
39
|
+
|
40
|
+
SAMPLE_INFO = Table(register="_CONFIG", name="SampleInfo")
|
41
|
+
|
42
|
+
COLUMN_TEMP_DEVICE = Device(register="RCTHM1Method")
|
43
|
+
|
44
|
+
DAD_DEVICE = Device(register="RCDAD1Method")
|
36
45
|
|
37
46
|
def __init__(
|
38
47
|
self,
|
@@ -68,9 +77,21 @@ class HPLCController:
|
|
68
77
|
data_dirs=data_dirs,
|
69
78
|
table=self.METHOD_TIMETABLE,
|
70
79
|
offline=offline,
|
71
|
-
|
80
|
+
injector=InjectorController(
|
72
81
|
controller=self.comm, table=self.INJECTOR_TABLE, offline=offline
|
73
82
|
),
|
83
|
+
pump=PumpController(
|
84
|
+
controller=self.comm, table=self.PUMP_DEVICE, offline=offline
|
85
|
+
),
|
86
|
+
dad=DADController(
|
87
|
+
controller=self.comm, table=self.DAD_DEVICE, offline=offline
|
88
|
+
),
|
89
|
+
column=ColumnController(
|
90
|
+
controller=self.comm, table=self.COLUMN_TEMP_DEVICE, offline=offline
|
91
|
+
),
|
92
|
+
sample_info=SampleInfo(
|
93
|
+
controller=self.comm, table=self.SAMPLE_INFO, offline=offline
|
94
|
+
),
|
74
95
|
)
|
75
96
|
self.sequence_controller: SequenceController = SequenceController(
|
76
97
|
controller=self.comm,
|
@@ -304,7 +325,10 @@ class HPLCController:
|
|
304
325
|
return self.sequence_controller.load()
|
305
326
|
|
306
327
|
def load_injector_program(self) -> InjectorTable | None:
|
307
|
-
return self.method_controller.
|
328
|
+
return self.method_controller.injector.load()
|
329
|
+
|
330
|
+
def load_sample_location(self):
|
331
|
+
self.method_controller.get_location()
|
308
332
|
|
309
333
|
def standby(self):
|
310
334
|
"""Switches all modules in standby mode. All lamps and pumps are switched off."""
|
@@ -316,19 +340,19 @@ class HPLCController:
|
|
316
340
|
|
317
341
|
def lamp_on(self):
|
318
342
|
"""Turns the UV lamp on."""
|
319
|
-
self.
|
343
|
+
self.method_controller.dad.turn_on()
|
320
344
|
|
321
345
|
def lamp_off(self):
|
322
346
|
"""Turns the UV lamp off."""
|
323
|
-
self.
|
347
|
+
self.method_controller.dad.turn_off()
|
324
348
|
|
325
349
|
def pump_on(self):
|
326
350
|
"""Turns on the pump on."""
|
327
|
-
self.
|
351
|
+
self.method_controller.pump.turn_on()
|
328
352
|
|
329
353
|
def pump_off(self):
|
330
354
|
"""Turns the pump off."""
|
331
|
-
self.
|
355
|
+
self.method_controller.pump.turn_off()
|
332
356
|
|
333
357
|
def instrument_off(self):
|
334
358
|
"""Shuts the entire instrument off, including pumps, lamps, thermostat."""
|
@@ -1,9 +1,9 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from abc import ABC
|
3
|
+
from abc import ABC, abstractmethod
|
4
4
|
|
5
5
|
from .table import ABCTableController
|
6
|
-
from ..table_types import Table
|
6
|
+
from ..table_types import Table, Device
|
7
7
|
from ...control.controllers import CommunicationController
|
8
8
|
|
9
9
|
|
@@ -15,8 +15,11 @@ class DeviceController(ABCTableController, ABC):
|
|
15
15
|
:param offline: whether the communication controller is online.
|
16
16
|
"""
|
17
17
|
|
18
|
+
def get_row(self, row: int):
|
19
|
+
raise NotImplementedError
|
20
|
+
|
18
21
|
def __init__(
|
19
|
-
self, controller: CommunicationController, table: Table, offline: bool
|
22
|
+
self, controller: CommunicationController, table: Table | Device, offline: bool
|
20
23
|
):
|
21
24
|
super().__init__(controller=controller, table=table)
|
22
25
|
self.offline = offline
|
@@ -25,3 +28,14 @@ class DeviceController(ABCTableController, ABC):
|
|
25
28
|
if cls is ABCTableController:
|
26
29
|
raise TypeError(f"only children of '{cls.__name__}' may be instantiated")
|
27
30
|
return object.__new__(cls)
|
31
|
+
|
32
|
+
def download(self):
|
33
|
+
raise NotImplementedError
|
34
|
+
|
35
|
+
@abstractmethod
|
36
|
+
def turn_off(self):
|
37
|
+
pass
|
38
|
+
|
39
|
+
@abstractmethod
|
40
|
+
def turn_on(self):
|
41
|
+
pass
|