from writers.csv import csv from DataLogger import DataLogger from time import sleep from devices.ArduinoDevice import ArduinoDevice writer = csv('testLog') logger = DataLogger(writer) logger.add_device(ArduinoDevice()) logger.start() try: while True: print("hi") sleep(1) finally: logger.end()
class Model(Thread): def __init__(self, **kwargs): Thread.__init__(self) # Serial thread self.serialthread = SerialPort() # Controller Read/Write variables over serial self.controller = DistantIO() # Serial protocol self.protocol = Protocol() # Variable manager self.variable_manager = VariableManager(self) self.variable_manager.start() self.running = True; # Data logger self.logger = DataLogger() def get_ports(self): return self.serialthread.get_ports() def connect_com(self,COM_port): # Start serial thread (can run without COM port connected) if not self.serialthread.isAlive(): self.serialthread.start() self.serialthread.connect(COM_port,115200) #Model update running in a thread def run(self): while self.running: if self.serialthread.char_available(): c = self.serialthread.get_char() if not c is None: self.protocol.process_rx(c) if self.protocol.available(): p = self.protocol.get() # Dump payload if controller is in heavy load ? pub.sendMessage('new_rx_payload',rxpayload=p)#USED ? if not p is None: self.controller.decode(p) def disconnect_com(self): self.serialthread.disconnect() def stop(self): self.running = False self.serialthread.stop() self.variable_manager.stop() if self.serialthread.isAlive(): self.serialthread.join(0.1) if self.serialthread.isAlive(): self.serialthread.join(1) if self.serialthread.isAlive(): print("--- Serial thread not properly joined.") if self.variable_manager.isAlive(): self.variable_manager.join(0.1) if self.variable_manager.isAlive(): self.variable_manager.join(1) self.stop_controller() def start_controller(self): #Get command for querying variable table MCU side cmd = self.controller.encode(cmd='table') #Feed command to serial protocol payload processor frame = self.protocol.process_tx(cmd) #Send command self.serialthread.write(frame) def stop_controller(self): #TODO : Tell MCU to stop sending all data pass def start_log(self): self.logger.start() def stop_log(self): self.logger.record_all() def read_var(self, varid): # Get command cmd = self.controller.encode(cmd='read',var_id=varid) # Feed command to serial protocol payload processor frame = self.protocol.process_tx(cmd) # Send command self.serialthread.write(frame) def write_var(self,varid,value): # Get command cmd = self.controller.encode(cmd='write',var_id=varid,value=value) if cmd == None: return # Feed command to serial protocol payload processor frame = self.protocol.process_tx(cmd) # Send command self.serialthread.write(frame) def stop_read_var(self,varid): # Get command cmd = self.controller.encode(cmd='stop',var_id=varid) if cmd == None: return # Feed command to serial protocol payload processor frame = self.protocol.process_tx(cmd) # Send command self.serialthread.write(frame) def stop_read_all_vars(): # Get command cmd = self.controller.encode(cmd='stopall') if cmd == None: return # Feed command to serial protocol payload processor frame = self.protocol.process_tx(cmd) # Send command self.serialthread.write(frame) def get_var_info(self,varid): return self.controller.get_var_info(varid)
#! /usr/bin/env python3 import argparse from DataLogger import DataLogger parser = argparse.ArgumentParser() parser.add_argument( "--clear", action="store_true", help= "Clear all data stored on Solar Light UV Radiometer internal data logger.") args = parser.parse_args() dataLogger = DataLogger(args.clear) dataLogger.start()
class Plotter: """ This class is responsible for plotting all the data items in the list to a file in png format using gnuplot """ def __init__(self, outputFileName, title, xlabel, ylabel, N, interval, gnuplot = "gnuplot"): """ The ctor outputFileName The file name with which the png file is to be created title Title of the plot xlabel X axis label ylabel Y axis label N number of data objects to get in interval Interval at which the data is to captured gnuplot The gnuplot program, on windows env, supply the complete path """ if (type(title) != type('') or type(xlabel) != type('') or type(ylabel) != type('')): raise ValueError, "This function expects 'title', 'xlabel' and 'ylabel' all to \ be strings" if (type(interval) != type(1) or type(N) != type(1) ): raise ValueError, "This function requires both 'interval' and 'N' to be of integer type" if (type(gnuplot) != type('')): raise ValueError, "Path to gnuplot must be a string" self.gnuplot = gnuplot self.plotItems = [] # will hold all the plot items self.stopEvent = threading.Event() self.n = N self.interval = interval self.DataLogger = None self.out = outputFileName self.reRgb = re.compile(r'#[a-fA-F0-9]{6}$') self.gnuplotScript = """ set term png size 1000,500 set output [output_here] set xlabel [xlabel_here] set ylabel [ylabel_here] set xdata time set timefmt "%b-%d-%H:%M:%S" set grid """ self.gnuplotScript = self.gnuplotScript.replace('[output_here]', "'"+outputFileName+"'") self.gnuplotScript = self.gnuplotScript.replace('[xlabel_here]', "'"+xlabel+"'") self.gnuplotScript = self.gnuplotScript.replace('[ylabel_here]', "'"+ylabel+"'") self.tempScript = "" def addPlotItem(self, itemName, itemColor, itemCb): """ This will add items to our "plotItems" list and when it is time to get the data, this list will be walked through itemName Name of the item as it appears in the graph itemColor Color with this data item is to be plotted, in hexadecimal format itemCb Call back function for this item that will supply the data Note: This has to be called before calling the "begin" function """ if not self.reRgb.match(itemColor): raise ValueError, "Not a valid RGB color code" self.plotItems.append(PlotItem(itemName, itemColor, itemCb)) def __theCallBack__(self): """ The call back method, which will execute all the callback functions in the list and will aggregate the data """ dataList = [] for plotItem in self.plotItems: try: temp = plotItem.itemCb() except Exception as ex: raise ex # "One of the call back function has failed " if (type(temp) != type(1) and type(temp) != type(1.1)): raise ValueError, "The function %s should return an int or a float type" %plotItem.itemCb.__name__ dataList.append(temp) # Return the data list that we have to the logger return dataList def begin(self): """ Starts the logger thread """ if self.DataLogger == None: self.DataLogger = DataLogger(self.__theCallBack__, self.n, self.interval, self.stopEvent) self.DataLogger.start() def stop(self): """ Stop the logging thread """ self.stopEvent.set() try: if DataLogger != None: print "Stopping the datalogger " self.DataLogger.join() self.DataLogger = None except: pass self.tempScript = "" def __del__(self): self.stop() def getOutPutFileName(self): return self.out def __addToGnuPlotCmdColorTitle__(self, color, title): """ Internal method that will add plot title and color """ if self.tempScript.find("plot") < 0: self.tempScript = self.tempScript + "\nplot " self.tempScript = self.tempScript + "'-' using 1:2 with lines title '%s' lt rgb '%s', " %(title, color) def __addToGnuPlotCmdDataTime__(self, data, time): """ Add the date and time information """ self.tempScript = self.tempScript + "\n%s %s" %(time, data) def __addToGnuPlotCmdEOD__(self): """ Add end of data """ self.tempScript = self.tempScript + "\ne\n" def __addToGnuPlotCmdXRange__(self, startTime, endTime): """ Set the start and end time """ start = startTime.strftime("%b-%d-%H:%M:%S") end = endTime.strftime("%b-%d-%H:%M:%S") self.tempScript = self.gnuplotScript self.tempScript = self.tempScript + """\nset xrange ["%s":"%s"]\n""" %(start, end) self.tempScript = self.tempScript + r'set format x "%H:%M\n%b-%d' def plot(self): """ This method will get the recorded data and plots it to png file using gnuplot """ recordedList = self.DataLogger.getDataList() if len(recordedList) == 0: return -1 # No records n = len(self.plotItems) # Set the x axis range temp = len(recordedList[0]) startTime = recordedList[0][0].time endTime = recordedList[0][temp-1].time self.__addToGnuPlotCmdXRange__(startTime, endTime) for j in range (0, n): self.__addToGnuPlotCmdColorTitle__(self.plotItems[j].color, self.plotItems[j].name) i=0 for record in recordedList: # Now, add all the data points for gnuplot to chew on for rec in record: timeData = rec.time.strftime("%b-%d-%H:%M:%S") data = str(rec.data) self.__addToGnuPlotCmdDataTime__(data, timeData) self.__addToGnuPlotCmdEOD__() i = i+1 #print self.tempScript plot = subprocess.Popen([self.gnuplot], stdin=subprocess.PIPE) plot.communicate(self.tempScript) print self.tempScript self.tempScript = ""