mmcb-rs232-avt 1.0.20__py3-none-any.whl → 1.1.37__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.
@@ -11,6 +11,7 @@ the return value can be used by the shell, e.g.
11
11
  """
12
12
 
13
13
  import argparse
14
+ import fcntl
14
15
  import logging
15
16
  import math
16
17
  import sys
@@ -21,9 +22,9 @@ import types
21
22
  import serial
22
23
  import numpy as np
23
24
 
24
- from mmcb_rs232 import common
25
- from mmcb_rs232 import lexicon
26
- from mmcb_rs232 import sequence
25
+ from mmcbrs232 import common
26
+ from mmcbrs232 import lexicon
27
+ from mmcbrs232 import sequence
27
28
 
28
29
 
29
30
  ##############################################################################
@@ -70,7 +71,7 @@ def check_settlingtime(val):
70
71
  return val
71
72
 
72
73
 
73
- def check_arguments(settings):
74
+ def check_arguments(settings, command=None):
74
75
  """
75
76
  handle command line options
76
77
 
@@ -78,6 +79,7 @@ def check_arguments(settings):
78
79
  args
79
80
  settings : dictionary
80
81
  contains core information about the test environment
82
+ command : str
81
83
  --------------------------------------------------------------------------
82
84
  returns : none
83
85
  --------------------------------------------------------------------------
@@ -201,7 +203,12 @@ def check_arguments(settings):
201
203
  action='store_true',
202
204
  help='Minimal text output during normal operation')
203
205
 
204
- args = parser.parse_args()
206
+ if command is None:
207
+ args = parser.parse_args()
208
+ else:
209
+ args = parser.parse_args(
210
+ command.strip().partition(' ')[-1].split(' ')
211
+ )
205
212
 
206
213
  settings['verbose'] = args.verbose
207
214
  settings['quiet'] = args.quiet
@@ -364,7 +371,7 @@ def check_measured_voltage(settings, pipeline, ser, dev, set_voltage):
364
371
  return success
365
372
 
366
373
 
367
- def current_limit(settings, pipeline, ser, dev):
374
+ def current_limit(settings, pipeline, ser, dev, slow=True):
368
375
  """
369
376
  Set and check current limit on Hameg HMP4040, Keithley 2614b and 2410.
370
377
 
@@ -387,6 +394,8 @@ def current_limit(settings, pipeline, ser, dev):
387
394
  reference for serial port
388
395
  dev : instance of class Channel
389
396
  contains details of a device and its serial port
397
+ slow : bool
398
+ enable checking of set values
390
399
  --------------------------------------------------------------------------
391
400
  returns : none
392
401
  --------------------------------------------------------------------------
@@ -405,6 +414,9 @@ def current_limit(settings, pipeline, ser, dev):
405
414
  compliance, channel=dev.channel)
406
415
  common.send_command(pipeline, ser, dev, command_string)
407
416
 
417
+ if not slow:
418
+ return
419
+
408
420
  # read back current limit from PSU
409
421
  command_string = lexicon.power(dev.model, 'get current limit', channel=dev.channel)
410
422
  response = common.atomic_send_command_read_response(pipeline, ser, dev, command_string)
@@ -456,7 +468,7 @@ def hmp4040_constant_current(ser, pipeline, dev):
456
468
  return retval
457
469
 
458
470
 
459
- def configure_lvpsu(settings, pipeline, ser, dev):
471
+ def configure_lvpsu(settings, pipeline, ser, dev, slow=True):
460
472
  """
461
473
  Set the power supply voltage and read back the value to confirm it has
462
474
  been correctly set.
@@ -478,6 +490,8 @@ def configure_lvpsu(settings, pipeline, ser, dev):
478
490
  reference for serial port
479
491
  dev : instance of class Channel
480
492
  contains details of a device and its serial port
493
+ slow : bool
494
+ enable checking of set values
481
495
  --------------------------------------------------------------------------
482
496
  returns
483
497
  success : bool
@@ -500,7 +514,7 @@ def configure_lvpsu(settings, pipeline, ser, dev):
500
514
 
501
515
  # set and verify current limit
502
516
  if settings['current_limit'] is not None:
503
- current_limit(settings, pipeline, ser, dev)
517
+ current_limit(settings, pipeline, ser, dev, slow)
504
518
 
505
519
  # change output on/off if requested, otherwise do not change it
506
520
  if settings['on'] is not None:
@@ -531,29 +545,34 @@ def configure_lvpsu(settings, pipeline, ser, dev):
531
545
  else:
532
546
  common.set_psu_voltage(settings, pipeline, voltage, ser, dev)
533
547
 
534
- # Agilent E3647A seems to require a minimum of half a second to apply
535
- # the setting before any further RS232 interaction is reliable
536
- time.sleep(0.5)
548
+ if slow:
549
+ # Agilent E3647A seems to require a minimum of half a second to apply
550
+ # the setting before any further RS232 interaction is reliable
551
+ time.sleep(0.5)
537
552
 
538
- # Arguably the voltage set for the channel should be read back too, so
539
- # for the case where the channel output is off, some confirmation that
540
- # the value has been set correctly can be given to the user.
541
- #
542
- # check measured voltage (can only be read back if output is on)
543
- if not common.report_output_status(ser, pipeline, dev):
544
- # allow a little time for the voltage to settle before reading
545
- time.sleep(settings['settlingtime'])
553
+ # Arguably the voltage set for the channel should be read back too, so
554
+ # for the case where the channel output is off, some confirmation that
555
+ # the value has been set correctly can be given to the user.
556
+ #
557
+ # check measured voltage (can only be read back if output is on)
546
558
 
547
- if dev.manufacturer == 'hameg' and hmp4040_constant_current(ser, pipeline, dev):
548
- # When configured as a constant current source, the measured
549
- # voltage will not match the set voltage
550
- success = True
559
+ if not common.report_output_status(ser, pipeline, dev):
560
+ # allow a little time for the voltage to settle before reading
561
+ time.sleep(settings['settlingtime'])
562
+
563
+ if dev.manufacturer == 'hameg' and hmp4040_constant_current(ser, pipeline, dev):
564
+ # When configured as a constant current source, the measured
565
+ # voltage will not match the set voltage
566
+ success = True
567
+ else:
568
+ success = check_measured_voltage(settings, pipeline, ser, dev, voltage)
551
569
  else:
552
- success = check_measured_voltage(settings, pipeline, ser, dev, voltage)
570
+ message = 'with PSU output switched off, set voltage cannot be read back'
571
+ common.log_with_colour(logging.WARNING, message)
572
+ common.log_with_colour(logging.WARNING, 'assuming all is well')
573
+ success = True
553
574
  else:
554
- message = 'with PSU output switched off, set voltage cannot be read back'
555
- common.log_with_colour(logging.WARNING, message)
556
- common.log_with_colour(logging.WARNING, 'assuming all is well')
575
+ # user elected to skip checks, assume successful outcome
557
576
  success = True
558
577
 
559
578
  return success
@@ -889,46 +908,59 @@ def main():
889
908
 
890
909
  pipeline = Production()
891
910
 
892
- ##########################################################################
893
- # Check status of outputs and interlock (inhibit) on all power supplies
894
- ##########################################################################
911
+ with open(common.RS232_LOCK_GLOBAL, 'a') as lock_file:
895
912
 
896
- common.initial_power_supply_check(settings, pipeline, psus, channels, psuset=True)
913
+ # acquire the RS232 global lock
914
+ fcntl.flock(lock_file.fileno(), fcntl.LOCK_EX)
897
915
 
898
- ##########################################################################
899
- # display details of selected power supply
900
- ##########################################################################
916
+ # --------------------------------------------------------------------
901
917
 
902
- try:
903
- channel = channels[0]
904
- except IndexError:
905
- pass
906
- else:
907
- text = f'selected power supply: {channel.manufacturer} {channel.model}'
908
- if channel.serial_number:
909
- text += f' s.no. {channel.serial_number}'
910
- if channel.channel:
911
- text += f' channel {channel.channel}'
912
- if settings['port'] is not None:
913
- text += f' port {channel.port}'
914
- common.log_with_colour(logging.INFO, text, quiet=settings['quiet'])
915
-
916
- ##########################################################################
917
- # set values on given power supply channel
918
- ##########################################################################
919
-
920
- setpsu = {'lvpsu': configure_lvpsu, 'hvpsu': configure_hvpsu}
921
-
922
- with serial.Serial(port=channel.port) as ser:
923
- ser.apply_settings(channel.config)
924
- ser.reset_input_buffer()
925
- ser.reset_output_buffer()
926
- success = setpsu[channel.category](settings, pipeline, ser, channel)
927
- if success:
928
- common.log_with_colour(
929
- logging.INFO, 'operation successful',
930
- quiet=settings['quiet']
931
- )
918
+ ######################################################################
919
+ # Check status of outputs and interlock (inhibit) on all power
920
+ # supplies
921
+ ######################################################################
922
+
923
+ common.initial_power_supply_check(settings, pipeline, psus, channels, psuset=True)
924
+
925
+ ######################################################################
926
+ # display details of selected power supply
927
+ ######################################################################
928
+
929
+ try:
930
+ channel = channels[0]
931
+ except IndexError:
932
+ pass
933
+ else:
934
+ text = f'selected power supply: {channel.manufacturer} {channel.model}'
935
+ if channel.serial_number:
936
+ text += f' s.no. {channel.serial_number}'
937
+ if channel.channel:
938
+ text += f' channel {channel.channel}'
939
+ if settings['port'] is not None:
940
+ text += f' port {channel.port}'
941
+ common.log_with_colour(logging.INFO, text, quiet=settings['quiet'])
942
+
943
+ ##################################################################
944
+ # set values on given power supply channel
945
+ ##################################################################
946
+
947
+ setpsu = {'lvpsu': configure_lvpsu, 'hvpsu': configure_hvpsu}
948
+
949
+ with serial.Serial(port=channel.port) as ser:
950
+ ser.apply_settings(channel.config)
951
+ ser.reset_input_buffer()
952
+ ser.reset_output_buffer()
953
+ success = setpsu[channel.category](settings, pipeline, ser, channel)
954
+ if success:
955
+ common.log_with_colour(
956
+ logging.INFO, 'operation successful',
957
+ quiet=settings['quiet']
958
+ )
959
+
960
+ # --------------------------------------------------------------------
961
+
962
+ # release the RS232 global lock
963
+ fcntl.flock(lock_file.fileno(), fcntl.LOCK_UN)
932
964
 
933
965
  return status.success if success else status.unreserved_error_code
934
966
 
@@ -9,24 +9,30 @@ All power supplies supported by detect.py are usable by this script.
9
9
  import argparse
10
10
  import collections
11
11
  import contextlib
12
+ import fcntl
13
+ import json
14
+ import serial
12
15
  import sys
13
16
  import time
14
17
  import threading
15
18
 
16
- from mmcb_rs232 import common
17
- from mmcb_rs232 import lexicon
19
+ from mmcbrs232 import common
20
+ from mmcbrs232 import lexicon
18
21
 
19
22
 
20
23
  ##############################################################################
21
24
  # command line option handler
22
25
  ##############################################################################
23
26
 
24
- def check_arguments(settings):
27
+ def check_arguments(settings, command=None):
25
28
  """
26
29
  handle command line options
27
30
 
28
31
  --------------------------------------------------------------------------
29
- args : none
32
+ args
33
+ settings : dictionary
34
+ contains core information about the test environment
35
+ command : str
30
36
  --------------------------------------------------------------------------
31
37
  returns : none
32
38
  --------------------------------------------------------------------------
@@ -65,6 +71,14 @@ def check_arguments(settings):
65
71
  not provide a serial number over RS232. A part of the serial may be\
66
72
  supplied if it is unique amongst connected devices.',
67
73
  default=None)
74
+ parser.add_argument(
75
+ '-z', '--zserv', action='store_true',
76
+ help=(
77
+ 'ZeroMQ serial port server DEBUG option. '
78
+ 'Enables experimental code path for certain HMP4040 read '
79
+ '(--sv and --mi) operations.'
80
+ ),
81
+ )
68
82
 
69
83
  group1 = parser.add_mutually_exclusive_group()
70
84
  group1.add_argument(
@@ -86,7 +100,12 @@ def check_arguments(settings):
86
100
  help='Read measured current. Only valid if the user has specified a PSU channel.',
87
101
  )
88
102
 
89
- args = parser.parse_args()
103
+ if command is None:
104
+ args = parser.parse_args()
105
+ else:
106
+ args = parser.parse_args(
107
+ command.strip().partition(' ')[-1].split(' ')
108
+ )
90
109
 
91
110
  if args.serial:
92
111
  settings['serial'] = args.serial[0]
@@ -122,6 +141,7 @@ def check_arguments(settings):
122
141
  settings['mv'] = args.mv
123
142
  settings['si'] = args.si
124
143
  settings['mi'] = args.mi
144
+ settings['zserv'] = args.zserv
125
145
 
126
146
 
127
147
  ##############################################################################
@@ -285,7 +305,7 @@ def simple_interlock_status(ser, pipeline, dev, tcolours):
285
305
  returns : string
286
306
  --------------------------------------------------------------------------
287
307
  """
288
- assert dev.manufacturer not in {'agilent', 'hameg'},\
308
+ assert dev.manufacturer not in {'agilent', 'hameg'}, \
289
309
  'function not callable for Agilent or Hameg PSU'
290
310
 
291
311
  status_categories = {
@@ -370,7 +390,121 @@ def simple_polarity_status(ser, pipeline, dev, tcolours):
370
390
  return status_categories[polarity_positive]
371
391
 
372
392
 
373
- def power_supply_channel_status(settings, pipeline, psus, channels, tcolours):
393
+ ###############################################################################
394
+ # For ZeroMQ server use only
395
+ ###############################################################################
396
+
397
+
398
+ def hmp4040_channel_cmp(id1, id2):
399
+ """
400
+ Compare channel names
401
+ """
402
+ id1 = f'{id1}'.lower()
403
+ id2 = f'{id2}'.lower()
404
+ lut = {
405
+ '1': ('1', 'a'),
406
+ 'a': ('1', 'a'),
407
+ '2': ('2', 'b'),
408
+ 'b': ('2', 'b'),
409
+ '3': ('3', 'c'),
410
+ 'c': ('3', 'c'),
411
+ '4': ('4', 'd'),
412
+ 'd': ('4', 'd'),
413
+ }
414
+ return id1 in lut[id2]
415
+
416
+
417
+ def hmp4040_sv_fast(pipeline, channel):
418
+ """
419
+ Read measured current from an HMP4040 PSU.
420
+
421
+ This function must only be called from the ZeroMQ serial port server,
422
+ which will have already performed the necessary serial port checks and
423
+ configuration.
424
+
425
+ Simplified version of read_psu_set_voltage().
426
+
427
+ --------------------------------------------------------------------------
428
+ args
429
+ pipeline : instance of class Production
430
+ contains all the queues through which the production pipeline
431
+ processes communicate
432
+ channel : instance of class Channel
433
+ contains details of a device and its serial port
434
+ --------------------------------------------------------------------------
435
+ returns
436
+ set_volt : float or None
437
+ --------------------------------------------------------------------------
438
+ """
439
+ set_volt = None
440
+
441
+ with serial.Serial(port=channel.port) as ser:
442
+ ser.apply_settings(channel.config)
443
+ ser.reset_output_buffer()
444
+ ser.reset_input_buffer()
445
+
446
+ local_buffer = common.atomic_send_command_read_response(
447
+ pipeline, ser, channel,
448
+ lexicon.power(channel.model, 'read set voltage', channel=channel.channel)
449
+ )
450
+
451
+ with contextlib.suppress(ValueError):
452
+ set_volt = float(local_buffer)
453
+
454
+ return set_volt
455
+
456
+
457
+ def hmp4040_mi_fast(pipeline, channel):
458
+ """
459
+ Read measured current from an HMP4040 PSU.
460
+
461
+ This function must only be called from the ZeroMQ serial port server,
462
+ which will have already performed the necessary serial port checks and
463
+ configuration.
464
+
465
+ --------------------------------------------------------------------------
466
+ args
467
+ pipeline : instance of class Production
468
+ contains all the queues through which the production pipeline
469
+ processes communicate
470
+ channel : instance of class Channel
471
+ contains details of a device and its serial port
472
+ --------------------------------------------------------------------------
473
+ returns
474
+ mcurr : float or None
475
+ --------------------------------------------------------------------------
476
+ """
477
+ with serial.Serial(port=channel.port) as ser:
478
+ ser.apply_settings(channel.config)
479
+ ser.reset_output_buffer()
480
+ ser.reset_input_buffer()
481
+
482
+ # ignore readings if output is off
483
+ output_status = common.atomic_send_command_read_response(
484
+ pipeline, ser, channel,
485
+ lexicon.power(channel.model, 'check output', channel=channel.channel)
486
+ )
487
+ if output_status == '0':
488
+ return None
489
+
490
+ measured_current = common.atomic_send_command_read_response(
491
+ pipeline, ser, channel,
492
+ lexicon.power(channel.model, 'read current', channel=channel.channel)
493
+ )
494
+
495
+ mcurr = None
496
+ try:
497
+ mcurr = float(measured_current)
498
+ except ValueError:
499
+ mcurr = None
500
+
501
+ return mcurr
502
+
503
+
504
+ ###############################################################################
505
+
506
+
507
+ def power_supply_channel_status(settings, pipeline, psus, channels, tcolours, verbose=True):
374
508
  """
375
509
  Establishes RS232 communications with power supplies (as required).
376
510
  Checks status of channel outputs and interlocks (inhibits).
@@ -390,12 +524,36 @@ def power_supply_channel_status(settings, pipeline, psus, channels, tcolours):
390
524
  power supply channel
391
525
  tcolours : class
392
526
  contains ANSI colour escape sequences
527
+ verbose : bool
393
528
  --------------------------------------------------------------------------
394
529
  returns
395
530
  channels : list
396
531
  no explicit return, mutable type amended in place
397
532
  --------------------------------------------------------------------------
398
533
  """
534
+ # ------------------------------------------------------------------------
535
+ # shortcut for HMP4040 for ZeroMQ server (DEBUG)
536
+ #
537
+ # remember that the caller needs to set the model otherwise this will not
538
+ # work
539
+ # ------------------------------------------------------------------------
540
+
541
+ if settings['zserv'] and settings['model'] == 'hmp4040' and (settings['sv'] or settings['mi']):
542
+ # select PSU channel
543
+ channel = next(
544
+ c for c in channels
545
+ if hmp4040_channel_cmp(c.channel, settings['channel'])
546
+ )
547
+
548
+ if settings['sv']:
549
+ value = hmp4040_sv_fast(pipeline, channel)
550
+ elif settings['mi']:
551
+ value = hmp4040_mi_fast(pipeline, channel)
552
+
553
+ return value
554
+
555
+ # ------------------------------------------------------------------------
556
+
399
557
  port_used = collections.defaultdict(int)
400
558
 
401
559
  # this function call may change the value of variable channels
@@ -403,6 +561,8 @@ def power_supply_channel_status(settings, pipeline, psus, channels, tcolours):
403
561
  # which have been left open
404
562
  spd = common.check_ports_accessible(psus, channels, close_after_check=False)
405
563
 
564
+ results = {}
565
+
406
566
  for dev in channels:
407
567
  read_values = []
408
568
 
@@ -457,7 +617,9 @@ def power_supply_channel_status(settings, pipeline, psus, channels, tcolours):
457
617
 
458
618
  if settings['filter']:
459
619
  if settings['sv']:
460
- print(set_volt)
620
+ if verbose:
621
+ print(set_volt)
622
+ results['sv'] = set_volt
461
623
  else:
462
624
  print(f'output status: {out_stat}')
463
625
 
@@ -475,9 +637,10 @@ def power_supply_channel_status(settings, pipeline, psus, channels, tcolours):
475
637
  if current_limit is not None:
476
638
  if settings['filter']:
477
639
  if settings['si']:
478
- print(
479
- simple_current_limit(ser, pipeline, dev, eng_format=False)
480
- )
640
+ result = simple_current_limit(ser, pipeline, dev, eng_format=False)
641
+ if verbose:
642
+ print(result)
643
+ results['si'] = result
481
644
  else:
482
645
  print(f'current limit: {current_limit}')
483
646
 
@@ -494,9 +657,13 @@ def power_supply_channel_status(settings, pipeline, psus, channels, tcolours):
494
657
  mvi_text = f'{common.si_prefix(mvolt)}V, {common.si_prefix(mcurr)}A'
495
658
  else:
496
659
  if settings['mi']:
497
- print(mcurr)
660
+ if verbose:
661
+ print(mcurr)
662
+ results['mi'] = mcurr
498
663
  elif settings['mv']:
499
- print(mvolt)
664
+ if verbose:
665
+ print(mvolt)
666
+ results['mv'] = mvolt
500
667
 
501
668
  if not settings['filter']:
502
669
  read_values.append(f'measured: {mvi_text}')
@@ -537,6 +704,8 @@ def power_supply_channel_status(settings, pipeline, psus, channels, tcolours):
537
704
  for serial_port in spd.values():
538
705
  serial_port.close()
539
706
 
707
+ return next(iter(results.values())) if len(results) == 1 else json.dumps(results)
708
+
540
709
 
541
710
  def read_psu_vi(pipeline, ser, dev):
542
711
  """
@@ -695,9 +864,21 @@ def main():
695
864
  # Check status of outputs and interlock (inhibit) on all power supplies
696
865
  ##########################################################################
697
866
 
698
- power_supply_channel_status(
699
- settings, pipeline, psus, channels, common.ANSIColours
700
- )
867
+ with open(common.RS232_LOCK_GLOBAL, 'a') as lock_file:
868
+
869
+ # acquire the RS232 global lock
870
+ fcntl.flock(lock_file.fileno(), fcntl.LOCK_EX)
871
+
872
+ # --------------------------------------------------------------------
873
+
874
+ power_supply_channel_status(
875
+ settings, pipeline, psus, channels, common.ANSIColours
876
+ )
877
+
878
+ # --------------------------------------------------------------------
879
+
880
+ # release the RS232 global lock
881
+ fcntl.flock(lock_file.fileno(), fcntl.LOCK_UN)
701
882
 
702
883
 
703
884
  ##############################################################################
@@ -16,8 +16,8 @@ import time
16
16
 
17
17
  import serial
18
18
 
19
- from mmcb_rs232 import common
20
- from mmcb_rs232 import lexicon
19
+ from mmcbrs232 import common
20
+ from mmcbrs232 import lexicon
21
21
 
22
22
 
23
23
  ##############################################################################
@@ -156,6 +156,11 @@ def check_arguments(settings):
156
156
  specified with either scientific (10e-12) or engineering notation\
157
157
  (10p)',
158
158
  type=common.check_current, default=(None, None))
159
+ parser.add_argument(
160
+ '--block_rs232', required=True, action='store_true',
161
+ help='Use this option to acknowledge that running this monitoring\
162
+ script will block RS232 access for other scripts in this suite.',
163
+ )
159
164
 
160
165
  args = parser.parse_args()
161
166
 
@@ -350,9 +355,9 @@ def initial_power_supply_check(settings, pipeline, psus, channels, psuset=False)
350
355
  channels.clear()
351
356
  else:
352
357
  message = '--debug: any connected power supplies will be ignored'
353
- log_with_colour(logging.WARNING, message)
358
+ common.log_with_colour(logging.WARNING, message)
354
359
  message = '--debug: IV data will generated internally'
355
- log_with_colour(logging.WARNING, message)
360
+ common.log_with_colour(logging.WARNING, message)
356
361
 
357
362
 
358
363
  def report_output_status(ser, pipeline, dev):
@@ -398,7 +403,7 @@ def report_output_status(ser, pipeline, dev):
398
403
 
399
404
  if dev.manufacturer == 'iseg':
400
405
  if '=ON' not in output:
401
- # log_with_colour(logging.WARNING, f'{dev.ident}, output off')
406
+ # common.log_with_colour(logging.WARNING, f'{dev.ident}, output off')
402
407
  fail = True
403
408
 
404
409
  elif dev.manufacturer in {'agilent', 'hameg', 'keithley'}:
@@ -406,17 +411,17 @@ def report_output_status(ser, pipeline, dev):
406
411
  outval = int(float(output))
407
412
  except ValueError:
408
413
  message = f'{dev.ident}, problem checking output'
409
- log_with_colour(logging.ERROR, message)
414
+ common.log_with_colour(logging.ERROR, message)
410
415
  fail = True
411
416
  else:
412
417
  if outval in {0, 1}:
413
418
  if outval == 0:
414
419
  # message = f'{dev.ident}, output off'
415
- # log_with_colour(logging.WARNING, message)
420
+ # common.log_with_colour(logging.WARNING, message)
416
421
  fail = True
417
422
  else:
418
423
  message = f'{dev.ident}, problem checking output'
419
- log_with_colour(logging.ERROR, message)
424
+ common.log_with_colour(logging.ERROR, message)
420
425
  fail = True
421
426
 
422
427
  return fail
@@ -14,7 +14,7 @@ import operator as op
14
14
  import os
15
15
  import sys
16
16
 
17
- from mmcb_rs232 import common
17
+ from mmcbrs232 import common
18
18
 
19
19
 
20
20
  ##############################################################################
@@ -329,8 +329,7 @@ def _entire_sequence(maxval, maxstep, ranges):
329
329
  sys.exit()
330
330
 
331
331
  # deliver results
332
- for voltage in seqc:
333
- yield voltage
332
+ yield from seqc
334
333
 
335
334
 
336
335
  def _sequence_to_ranges(numseq):