pychemstation 0.10.11__py3-none-any.whl → 0.10.13__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.
@@ -54,7 +54,7 @@ class CommunicationController(ABCCommunicationController):
54
54
  raise RuntimeError("Failed to get number.")
55
55
 
56
56
  def get_text_val(self, cmd: str) -> str:
57
- tries = 10
57
+ tries = 5
58
58
  for _ in range(tries):
59
59
  self.send(Command.GET_TEXT_VAL_CMD.value.format(cmd=cmd))
60
60
  res = self.receive()
@@ -5,12 +5,16 @@ import time
5
5
  import warnings
6
6
  from typing import Dict, List, Optional, Union, Tuple
7
7
 
8
- from result import Err, Ok, Result
8
+ from result import Err, Result, Ok
9
9
 
10
- from pychemstation.analysis.chromatogram import (
10
+ from ..devices.column import ColumnController
11
+ from ..devices.dad import DADController
12
+ from ..devices.pump import PumpController
13
+ from ..devices.sample_info import SampleInfo
14
+ from ....analysis.chromatogram import (
11
15
  TIME_FORMAT,
12
- AgilentChannelChromatogramData,
13
16
  AgilentHPLCChromatogram,
17
+ AgilentChannelChromatogramData,
14
18
  )
15
19
 
16
20
  from ....analysis.process_report import AgilentReport, ReportType
@@ -20,12 +24,13 @@ from ....utils.macro import Command
20
24
  from ....utils.method_types import (
21
25
  HPLCMethodParams,
22
26
  MethodDetails,
27
+ TimeTableEntry,
23
28
  Param,
24
29
  PType,
25
- TimeTableEntry,
26
30
  )
27
- from ....utils.table_types import RegisterFlag, T, Table, TableOperation
31
+ from ....utils.table_types import RegisterFlag, T, Table
28
32
  from ..devices.injector import InjectorController
33
+ from ....utils.tray_types import Tray
29
34
 
30
35
 
31
36
  class MethodController(RunController):
@@ -38,9 +43,17 @@ class MethodController(RunController):
38
43
  data_dirs: Optional[List[str]],
39
44
  table: Table,
40
45
  offline: bool,
41
- injector_controller: InjectorController,
46
+ injector: InjectorController,
47
+ pump: PumpController,
48
+ dad: DADController,
49
+ column: ColumnController,
50
+ sample_info: SampleInfo,
42
51
  ):
43
- self.injector_controller = injector_controller
52
+ self.injector = injector
53
+ self.pump = pump
54
+ self.dad = dad
55
+ self.column = column
56
+ self.sample_info = sample_info
44
57
  self.data_files: List[str] = []
45
58
  super().__init__(
46
59
  controller=controller,
@@ -50,6 +63,9 @@ class MethodController(RunController):
50
63
  offline=offline,
51
64
  )
52
65
 
66
+ def get_sample_location(self) -> Tray:
67
+ return self.sample_info.get_location()
68
+
53
69
  def get_current_method_name(self) -> str:
54
70
  self.sleepy_send(Command.GET_METHOD_CMD)
55
71
  res = self.receive()
@@ -60,18 +76,8 @@ class MethodController(RunController):
60
76
  def get_method_params(self) -> HPLCMethodParams:
61
77
  if self.controller:
62
78
  return HPLCMethodParams(
63
- organic_modifier=self.controller.get_num_val(
64
- cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
65
- register=self.table_locator.register,
66
- register_flag=RegisterFlag.SOLVENT_B_COMPOSITION,
67
- )
68
- ),
69
- flow=self.controller.get_num_val(
70
- cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
71
- register=self.table_locator.register,
72
- register_flag=RegisterFlag.FLOW,
73
- )
74
- ),
79
+ organic_modifier=self.get_om(),
80
+ flow=self.get_flow(),
75
81
  )
76
82
  raise ValueError("Communication controller is offline!")
77
83
 
@@ -135,26 +141,6 @@ class MethodController(RunController):
135
141
  method_name = res.ok_value.string_response
136
142
  return method_name
137
143
 
138
- def get_post_time(self) -> Union[int, float]:
139
- if self.controller:
140
- return self.controller.get_num_val(
141
- cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
142
- register=self.table_locator.register,
143
- register_flag=RegisterFlag.POST_TIME,
144
- )
145
- )
146
- raise ValueError("Communication controller is not online!")
147
-
148
- def get_stop_time(self) -> Union[int, float]:
149
- if self.controller:
150
- return self.controller.get_num_val(
151
- cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
152
- register=self.table_locator.register,
153
- register_flag=RegisterFlag.MAX_TIME,
154
- )
155
- )
156
- raise ValueError("Communication controller is not online!")
157
-
158
144
  def get_total_runtime(self) -> Union[int, float]:
159
145
  """Returns total method runtime in minutes."""
160
146
  return self.get_post_time() + self.get_stop_time()
@@ -214,20 +200,14 @@ class MethodController(RunController):
214
200
  self.edit_method_timetable(updated_method.timetable)
215
201
 
216
202
  if save:
217
- self.send(
218
- Command.SAVE_METHOD_CMD.value.format(
219
- commit_msg=f"saved method at {str(time.time())}"
220
- )
221
- )
203
+ self.save_method()
222
204
 
223
- def edit_initial_om(self, new_om: Union[int, float]):
224
- self._validate_organic_modifier(new_om)
225
- initial_organic_modifier: Param = Param(
226
- val=new_om,
227
- chemstation_key=RegisterFlag.SOLVENT_B_COMPOSITION,
228
- ptype=PType.NUM,
205
+ def save_method(self):
206
+ self.send(
207
+ Command.SAVE_METHOD_CMD.value.format(
208
+ commit_msg=f"saved method at {str(time.time())}"
209
+ )
229
210
  )
230
- self._update_param(initial_organic_modifier)
231
211
 
232
212
  def _validate_organic_modifier(self, new_om):
233
213
  if not (isinstance(new_om, int) or isinstance(new_om, float)):
@@ -237,13 +217,6 @@ class MethodController(RunController):
237
217
  if new_om > 100:
238
218
  raise ValueError("Organic modifer must be less than 100.")
239
219
 
240
- def edit_flow(self, new_flow: Union[int, float]):
241
- self._validate_flow(new_flow)
242
- flow: Param = Param(
243
- val=new_flow, chemstation_key=RegisterFlag.FLOW, ptype=PType.NUM
244
- )
245
- self._update_param(flow)
246
-
247
220
  def _validate_flow(self, new_flow):
248
221
  if not (isinstance(new_flow, int) or isinstance(new_flow, float)):
249
222
  raise ValueError("Flow must be int or float")
@@ -252,38 +225,12 @@ class MethodController(RunController):
252
225
  if new_flow >= 5.0:
253
226
  raise ValueError("Flow must be less than 5.0")
254
227
 
255
- def edit_stop_time(self, new_stop_time: Union[int, float]):
256
- self.validate_stop_time(new_stop_time)
257
- stop_time: Param = Param(
258
- val=new_stop_time,
259
- chemstation_key=RegisterFlag.MAX_TIME,
260
- ptype=PType.NUM,
261
- )
262
- self._update_param(
263
- Param(
264
- val="Set", chemstation_key=RegisterFlag.STOPTIME_MODE, ptype=PType.STR
265
- )
266
- )
267
- self._update_param(stop_time)
268
-
269
228
  def validate_stop_time(self, new_stop_time):
270
229
  if not (isinstance(new_stop_time, int) or isinstance(new_stop_time, float)):
271
230
  raise ValueError("Stop time must be int or float")
272
231
  if new_stop_time < 0:
273
232
  raise ValueError("Stop time must be positive")
274
233
 
275
- def edit_post_time(self, new_post_time: Union[int, float]):
276
- self.validate_post_time(new_post_time)
277
- post_time: Param = Param(
278
- val=new_post_time,
279
- chemstation_key=RegisterFlag.POST_TIME,
280
- ptype=PType.NUM,
281
- )
282
- self._update_param(
283
- Param(val="Set", chemstation_key=RegisterFlag.POSTIME_MODE, ptype=PType.STR)
284
- )
285
- self._update_param(post_time)
286
-
287
234
  def validate_post_time(self, new_post_time):
288
235
  if not (isinstance(new_post_time, int) or isinstance(new_post_time, float)):
289
236
  raise ValueError("Post time must be int or float")
@@ -298,59 +245,14 @@ class MethodController(RunController):
298
245
  new_post_time: Union[int, float] | None,
299
246
  ):
300
247
  self.delete_table()
301
- self.edit_initial_om(new_initial_om)
248
+ self._validate_flow(new_flow)
249
+ self.validate_post_time(new_post_time)
250
+ self._validate_organic_modifier(new_initial_om)
251
+ self.validate_stop_time(new_stop_time)
302
252
  self.edit_flow(new_flow)
303
- if new_stop_time:
304
- self.edit_stop_time(new_stop_time)
305
- else:
306
- self._update_param(
307
- Param(
308
- val="Off",
309
- chemstation_key=RegisterFlag.STOPTIME_MODE,
310
- ptype=PType.STR,
311
- )
312
- )
313
- if new_post_time:
314
- self.edit_post_time(new_post_time)
315
- else:
316
- self._update_param(
317
- Param(
318
- val="Off",
319
- chemstation_key=RegisterFlag.POSTIME_MODE,
320
- ptype=PType.STR,
321
- )
322
- )
323
-
324
- def _update_param(self, method_param: Param):
325
- """Change a method parameter, changes what is visibly seen in Chemstation GUI.
326
- (changes the first row in the timetable)
327
-
328
- :param method_param: a parameter to update for currently loaded method.
329
- """
330
- register = self.table_locator.register
331
- setting_command = (
332
- TableOperation.UPDATE_OBJ_HDR_VAL
333
- if method_param.ptype == PType.NUM
334
- else TableOperation.UPDATE_OBJ_HDR_TEXT
335
- )
336
- if isinstance(method_param.chemstation_key, list):
337
- for register_flag in method_param.chemstation_key:
338
- self.sleepy_send(
339
- setting_command.value.format(
340
- register=register,
341
- register_flag=register_flag,
342
- val=method_param.val,
343
- )
344
- )
345
- else:
346
- self.sleepy_send(
347
- setting_command.value.format(
348
- register=register,
349
- register_flag=method_param.chemstation_key,
350
- val=method_param.val,
351
- )
352
- )
353
- self.download()
253
+ self.edit_initial_om(new_initial_om)
254
+ self.edit_stop_time(new_stop_time)
255
+ self.edit_post_time(new_post_time)
354
256
 
355
257
  def download(self):
356
258
  self.sleepy_send("DownloadRCMethod PMP1")
@@ -585,3 +487,77 @@ class MethodController(RunController):
585
487
  Row {i + 1} ({timetable[i].start_time}) has a smaller or equal starttime than row {i} ({start_time})"""
586
488
  )
587
489
  self._validate_row(row)
490
+
491
+ def get_om(self):
492
+ return self._read_num_param(RegisterFlag.SOLVENT_B_COMPOSITION)
493
+
494
+ def get_flow(self):
495
+ return self._read_num_param(RegisterFlag.FLOW)
496
+
497
+ def get_post_time(self) -> Union[int, float]:
498
+ return self._read_num_param(RegisterFlag.POST_TIME)
499
+
500
+ def get_stop_time(self) -> Union[int, float]:
501
+ return self._read_num_param(RegisterFlag.MAX_TIME)
502
+
503
+ def edit_post_time(self, new_post_time: Optional[int | float]):
504
+ if new_post_time:
505
+ post_time: Param = Param(
506
+ val=new_post_time,
507
+ chemstation_key=RegisterFlag.POST_TIME,
508
+ ptype=PType.NUM,
509
+ )
510
+ self._update_param(
511
+ Param(
512
+ val="Set",
513
+ chemstation_key=RegisterFlag.POSTIME_MODE,
514
+ ptype=PType.STR,
515
+ )
516
+ )
517
+ self._update_param(post_time)
518
+ else:
519
+ self._update_param(
520
+ Param(
521
+ val="Off",
522
+ chemstation_key=RegisterFlag.POSTIME_MODE,
523
+ ptype=PType.STR,
524
+ )
525
+ )
526
+
527
+ def edit_stop_time(self, new_stop_time: Optional[int | float]):
528
+ if new_stop_time:
529
+ stop_time: Param = Param(
530
+ val=new_stop_time,
531
+ chemstation_key=RegisterFlag.MAX_TIME,
532
+ ptype=PType.NUM,
533
+ )
534
+ self._update_param(
535
+ Param(
536
+ val="Set",
537
+ chemstation_key=RegisterFlag.STOPTIME_MODE,
538
+ ptype=PType.STR,
539
+ )
540
+ )
541
+ self._update_param(stop_time)
542
+ else:
543
+ self._update_param(
544
+ Param(
545
+ val="Off",
546
+ chemstation_key=RegisterFlag.STOPTIME_MODE,
547
+ ptype=PType.STR,
548
+ )
549
+ )
550
+
551
+ def edit_flow(self, new_flow: Union[int, float]):
552
+ flow: Param = Param(
553
+ val=new_flow, chemstation_key=RegisterFlag.FLOW, ptype=PType.NUM
554
+ )
555
+ self._update_param(flow)
556
+
557
+ def edit_initial_om(self, new_om: Union[int, float]):
558
+ initial_organic_modifier: Param = Param(
559
+ val=new_om,
560
+ chemstation_key=RegisterFlag.SOLVENT_B_COMPOSITION,
561
+ ptype=PType.NUM,
562
+ )
563
+ self._update_param(initial_organic_modifier)
@@ -70,37 +70,39 @@ class SequenceController(RunController):
70
70
  f"couldn't read rows or sequence name: {seq_name.err_value}"
71
71
  )
72
72
 
73
- def try_int(self, val: Any) -> Optional[int]:
73
+ @staticmethod
74
+ def try_int(val: Any) -> Optional[int]:
74
75
  try:
75
76
  return int(val)
76
77
  except ValueError:
77
78
  return None
78
79
 
79
- def try_float(self, val: Any) -> Optional[float]:
80
+ @staticmethod
81
+ def try_float(val: Any) -> Optional[float]:
80
82
  try:
81
83
  return float(val)
82
84
  except ValueError:
83
85
  return None
84
86
 
85
- def try_vial_location(self, val: Any) -> Tray:
87
+ @staticmethod
88
+ def try_vial_location(val: Any) -> Tray:
86
89
  try:
87
90
  return VialBar(val) if val <= 10 else FiftyFourVialPlate.from_int(num=val)
88
91
  except ValueError:
89
92
  raise ValueError("Expected vial location, is empty.")
90
93
 
91
94
  def get_row(self, row: int) -> SequenceEntry:
92
- sample_name = self.get_text(row, RegisterFlag.NAME)
93
- vial_location = self.try_int(self.get_num(row, RegisterFlag.VIAL_LOCATION))
94
- data_file = self.get_text(row, RegisterFlag.DATA_FILE)
95
- method = self.get_text(row, RegisterFlag.METHOD)
96
- num_inj = self.try_int(self.get_num(row, RegisterFlag.NUM_INJ))
97
- inj_vol = self.try_float(self.get_text(row, RegisterFlag.INJ_VOL))
98
- inj_source = InjectionSource(self.get_text(row, RegisterFlag.INJ_SOR))
99
- sample_type = SampleType(self.get_num(row, RegisterFlag.SAMPLE_TYPE))
100
- vial_enum = self.try_vial_location(vial_location)
95
+ sample_name = self.get_sample_name(row)
96
+ vial_location = self.get_vial_location(row)
97
+ data_file = self.get_data_file(row)
98
+ method = self.get_method(row)
99
+ num_inj = self.get_num_inj(row)
100
+ inj_vol = self.get_inj_vol(row)
101
+ inj_source = self.get_inj_source(row)
102
+ sample_type = self.get_sample_type(row)
101
103
  return SequenceEntry(
102
104
  sample_name=sample_name,
103
- vial_location=vial_enum,
105
+ vial_location=vial_location,
104
106
  method=None if len(method) == 0 else method,
105
107
  num_inj=num_inj,
106
108
  inj_vol=inj_vol,
@@ -109,6 +111,32 @@ class SequenceController(RunController):
109
111
  data_file=data_file,
110
112
  )
111
113
 
114
+ def get_sample_type(self, row):
115
+ return SampleType(self.get_num(row, RegisterFlag.SAMPLE_TYPE))
116
+
117
+ def get_inj_source(self, row):
118
+ return InjectionSource(self.get_text(row, RegisterFlag.INJ_SOR))
119
+
120
+ def get_inj_vol(self, row):
121
+ return self.try_float(self.get_text(row, RegisterFlag.INJ_VOL))
122
+
123
+ def get_num_inj(self, row):
124
+ return self.try_int(self.get_num(row, RegisterFlag.NUM_INJ))
125
+
126
+ def get_method(self, row):
127
+ return self.get_text(row, RegisterFlag.METHOD)
128
+
129
+ def get_data_file(self, row):
130
+ return self.get_text(row, RegisterFlag.DATA_FILE)
131
+
132
+ def get_vial_location(self, row) -> Tray:
133
+ return self.try_vial_location(
134
+ self.try_int(self.get_num(row, RegisterFlag.VIAL_LOCATION))
135
+ )
136
+
137
+ def get_sample_name(self, row):
138
+ return self.get_text(row, RegisterFlag.NAME)
139
+
112
140
  def switch(self, seq_name: str):
113
141
  """
114
142
  Switch to the specified sequence. The sequence name does not need the '.S' extension.
@@ -145,12 +173,12 @@ class SequenceController(RunController):
145
173
  self.send(Command.SAVE_SEQUENCE_CMD)
146
174
  for i in range(int(wanted_row_num)):
147
175
  self.add_row()
148
- self.save()
176
+ self.download()
149
177
  self.send(Command.SWITCH_SEQUENCE_CMD)
150
178
  for i, row in enumerate(sequence_table.rows):
151
179
  self._edit_row(row=row, row_num=i + 1)
152
180
  self.sleep(1)
153
- self.save()
181
+ self.download()
154
182
  self.send(Command.SWITCH_SEQUENCE_CMD)
155
183
 
156
184
  def _edit_row(self, row: SequenceEntry, row_num: int):
@@ -163,7 +191,7 @@ class SequenceController(RunController):
163
191
  num_rows = self.get_row_count_safely()
164
192
  while num_rows < row_num:
165
193
  self.add_row()
166
- self.save()
194
+ self.download()
167
195
  num_rows = self.get_row_count_safely()
168
196
  if row.vial_location:
169
197
  self.edit_vial_location(row.vial_location, row_num, save=False)
@@ -181,7 +209,7 @@ class SequenceController(RunController):
181
209
  self.edit_data_file(row.data_file, row_num, save=False)
182
210
  if row.sample_type:
183
211
  self.edit_sample_type(row.sample_type, row_num, save=False)
184
- self.save()
212
+ self.download()
185
213
 
186
214
  def edit_sample_type(
187
215
  self, sample_type: SampleType, row_num: int, save: bool = True
@@ -194,17 +222,17 @@ class SequenceController(RunController):
194
222
  val=sample_type.value,
195
223
  )
196
224
  if save:
197
- self.save()
225
+ self.download()
198
226
 
199
227
  def edit_data_file(self, data_file: str, row_num: int, save: bool = True):
200
228
  self._edit_row_text(row=row_num, col_name=RegisterFlag.DATA_FILE, val=data_file)
201
229
  if save:
202
- self.save()
230
+ self.download()
203
231
 
204
232
  def edit_sample_name(self, sample_name: str, row_num: int, save: bool = True):
205
233
  self._edit_row_text(row=row_num, col_name=RegisterFlag.NAME, val=sample_name)
206
234
  if save:
207
- self.save()
235
+ self.download()
208
236
 
209
237
  def edit_injection_source(
210
238
  self, inj_source: InjectionSource, row_num: int, save: bool = True
@@ -215,7 +243,7 @@ class SequenceController(RunController):
215
243
  row=row_num, col_name=RegisterFlag.INJ_SOR, val=inj_source.value
216
244
  )
217
245
  if save:
218
- self.save()
246
+ self.download()
219
247
 
220
248
  def edit_injection_volume(
221
249
  self, inj_vol: Union[int, float], row_num: int, save: bool = True
@@ -224,12 +252,12 @@ class SequenceController(RunController):
224
252
  row=row_num, col_name=RegisterFlag.INJ_VOL, val=str(inj_vol)
225
253
  )
226
254
  if save:
227
- self.save()
255
+ self.download()
228
256
 
229
257
  def edit_num_injections(self, num_inj: int, row_num: int, save: bool = True):
230
258
  self._edit_row_num(row=row_num, col_name=RegisterFlag.NUM_INJ, val=num_inj)
231
259
  if save:
232
- self.save()
260
+ self.download()
233
261
 
234
262
  def edit_method_name(
235
263
  self, method: str, row_num: int, save: bool = True, override_check: bool = False
@@ -244,7 +272,7 @@ class SequenceController(RunController):
244
272
  )
245
273
  self._edit_row_text(row=row_num, col_name=RegisterFlag.METHOD, val=method)
246
274
  if save:
247
- self.save()
275
+ self.download()
248
276
 
249
277
  def edit_vial_location(self, loc: Tray, row_num: int, save: bool = True):
250
278
  loc_num = -1
@@ -270,7 +298,7 @@ class SequenceController(RunController):
270
298
  self._edit_row(previous_contents, num_rows)
271
299
  self.move_row(int(num_rows), row_num)
272
300
  self.delete_row(row_num + 1)
273
- self.save()
301
+ self.download()
274
302
  else:
275
303
  raise ValueError(
276
304
  "`loc` should be of type `VialBar`, `FiftyFourVialPlate`"
@@ -288,9 +316,9 @@ class SequenceController(RunController):
288
316
  row=row_num, col_name=RegisterFlag.VIAL_LOCATION, val=loc_num
289
317
  )
290
318
  if save:
291
- self.save()
319
+ self.download()
292
320
 
293
- def save(self):
321
+ def download(self):
294
322
  self.send(Command.SAVE_SEQUENCE_CMD)
295
323
 
296
324
  def run(self, stall_while_running: bool = True):
@@ -426,14 +454,19 @@ class SequenceController(RunController):
426
454
  def get_data(
427
455
  self, custom_path: Optional[str] = None
428
456
  ) -> List[AgilentChannelChromatogramData]:
429
- seq_file_dir = (
430
- SequenceDataFiles(dir=custom_path, sequence_name="")
431
- if custom_path
432
- else self.data_files[-1]
433
- )
434
- self.data_files[-1] = self._fuzzy_match_most_recent_folder(
457
+ print(custom_path)
458
+ if custom_path:
459
+ self.data_files.append(
460
+ SequenceDataFiles(dir=custom_path, sequence_name="")
461
+ )
462
+ seq_file_dir = self.data_files[-1]
463
+ possible_seq_file_name = self._fuzzy_match_most_recent_folder(
435
464
  seq_file_dir
436
- ).ok_value
465
+ )
466
+ if possible_seq_file_name.is_ok():
467
+ self.data_files[-1] = possible_seq_file_name.ok_value
468
+ else:
469
+ raise UserWarning(f"{possible_seq_file_name.err_value}")
437
470
  spectra: List[AgilentChannelChromatogramData] = []
438
471
  for row in self.data_files[-1].child_dirs:
439
472
  self.get_spectrum_at_channels(row)
@@ -1,3 +1,6 @@
1
1
  from .injector import InjectorController
2
+ from .pump import PumpController
3
+ from .column import ColumnController
4
+ from .dad import DADController
2
5
 
3
- __all__ = ["InjectorController"]
6
+ __all__ = ["InjectorController", "PumpController", "ColumnController", "DADController"]
@@ -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")