import sys as _sys
import time as _time
+try:
+ import numpy as _numpy
+ from matplotlib import pyplot as _pyplot
+except ImportError, _matplotlib_import_error:
+ _pyplot = None
+
import pycomedi.device as _pycomedi_device
import pycomedi.subdevice as _pycomedi_subdevice
import pycomedi.channel as _pycomedi_channel
"""
def __init__(self, channels=[0], temperature=False, dt=4,
- comedi_device='/dev/comedi0', data_stream=None, logger=None):
+ comedi_device='/dev/comedi0', data_stream=None, logger=None,
+ plotter=None):
self.channel_indexes = channels
self.with_temperature = temperature
self.dt = dt
self.comedi_device = comedi_device
self.data_stream = data_stream
self._logger = logger
+ self._plotter = plotter
self.temperature = None
def log(self, level=_logging.DEBUG, msg=None):
self.log(msg='teardown slow bend monitor')
self._teardown_channels()
self._teardown_temperature()
-
+
def _teardown_channels(self):
self.log(msg='teardown input channels')
if hasattr(self, 'device') and self.device is not None:
if self.temperature is not None:
self.temperature.cleanup()
self.temperature = None
-
+
def _run(self):
self.log(msg='running slow bend monitor')
self.start_time = _time.time()
fields.extend(['{} ({})'.format(name, u) for u in ['bit', unit]])
headline = '#{}'.format('\t'.join(fields))
self.data_stream.write(headline + '\n')
- self.log(_logging.INFO, headline)
self.data_stream.flush()
+ self.log(_logging.INFO, headline)
+ if self._plotter:
+ self._plotter.add_header(fields)
def _save_reading(self, time, bitvals, physicals):
self.log(msg='save measurement')
'\t'.join('{:d}\t{:g}'.format(b, p)
for b,p in zip(bitvals, physicals)))
self.data_stream.write(dataline + '\n')
- self.log(_logging.INFO, dataline)
self.data_stream.flush()
+ self.log(_logging.INFO, dataline)
+ if self._plotter:
+ self._plotter.add_points(time, bitvals, physicals)
def _wait_until(self, target_time):
self.log(msg='sleep until {}'.format(target_time))
_time.sleep(dt)
+class Plotter (object):
+ """Matplotlib-based strip-chart
+ """
+ def __init__(self, count=100):
+ self.count = count
+ if _pyplot is None:
+ raise _matplotlib_import_error
+ _pyplot.ion()
+
+ def add_header(self, fields):
+ self.figure = _pyplot.figure()
+ self.channels = len(fields)/2 # integer division
+ self.axes = []
+ self.lines = []
+ for i in range(self.channels):
+ self.axes.append(self.figure.add_subplot(self.channels, 1, i+1))
+ self.axes[i].set_title(fields[2*i+1])
+ self.lines.append(self.axes[i].plot(
+ range(self.count),
+ _numpy.zeros((self.count,), dtype=_numpy.float), 'r.'))
+ #_pyplot.show(block=False) # block is an experimental kwarg
+ _pyplot.show()
+
+ def add_points(self, time, bit_values, physical_values):
+ for i in range(self.channels):
+ phys_values = self.lines[i][0].get_ydata()
+ phys_values = _numpy.roll(phys_values, -1)
+ phys_values[-1] = physical_values[i]
+ self.lines[i][0].set_ydata(phys_values)
+ self.axes[i].relim()
+ self.axes[i].autoscale(axis='y')
+ self.figure.canvas.draw()
+
def _get_data_stream(data_dir=None, logger=None):
if data_dir is None:
return _sys.stdout
'-T', '--temperature', dest='temperature',
default=False, action='store_const', const=True,
help='Also record the temperature')
+ parser.add_argument(
+ '-p', '--plot', dest='plot',
+ default=False, action='store_const', const=True,
+ help='Display recorded physical values on a strip-chart')
parser.add_argument(
'-v', '--verbose', dest='verbose',
default=0, action='count',
logger = _get_logger(level=level)
else:
logger = None
+ if args.plot:
+ plotter = Plotter()
+ else:
+ plotter = None
data_stream = _get_data_stream(data_dir=args.data_dir, logger=logger)
try:
m = Monitor(
channels=args.channels, temperature=args.temperature, dt=args.dt,
- data_stream=data_stream, logger=logger)
+ data_stream=data_stream, logger=logger, plotter=plotter)
m.run()
finally:
if data_stream != _sys.stdout: