import os import time import math import u3 import DS18B20 import datetime from Adafruit_IO import Client SAMPLE_RATE_SECONDS = 30 # MAX_REQUESTS is the number of packets to be read. MAX_REQUESTS = 1 # SCAN_FREQUENCY is the scan frequency of stream mode in Hz SCAN_FREQUENCY = 2000 def getPanelVoltage(s): sLen = min(len(s["AIN0"]), len(s["AIN1"])) pvVoltage = list() for idx in range(0, sLen): pvVoltage.append(s["AIN1"][idx] - s["AIN0"][idx]) rms = getRMS(pvVoltage) return round(rms, 2) def getPanelCurrent(s): pvCurrent = list() for idx in range(0, len(s["AIN6"])): pvCurrent.append(s["AIN6"][idx] * 2) rms = getRMS(pvCurrent) return round(rms, 2) def getBatteryVoltage(s): avg = sum(s["AIN2"])/len(s["AIN2"]) return round(avg, 2) def getLabJackTemp(d): t = d.getTemperature() t = ((t - 273.15)*1.8 + 32) return round(t, 2) def getAmbientTemp(s): t = s.readTemp() return round(t[1], 2) def getRMS(l): m = 0 for i in range(0, len(l)): m += (l[i] * l[i]) m = m/len(l) rms = math.sqrt(m) return rms def updateFeed(ada, name, data, logDt, f): try: ada.send(name, data) except: writeFile(f, (str(logDt.now()) + " " + name + " Connection Error...\r\n")) def buildFileName(local_dt): if(local_dt.day < 10): day_str = "0"+str(local_dt.day)+"_" else: day_str = str(local_dt.day)+"_" if(local_dt.month < 10): month_str = "0"+str(local_dt.month)+"_" else: month_str = str(local_dt.month)+"_" return(day_str+month_str+str(local_dt.year)) def buildCsvFileName(local_dt): name = buildFileName(local_dt) return('data/'+name+'.csv') def buildLogFileName(local_dt): name = buildFileName(local_dt) return('logs/'+name+".log") def writeFile(name, s): f = open(name, 'a+') f.write(s) f.close() def readFile(name): f = open(name, 'r') s = f.read() f.close() return(s) def main(): #Get date/time for logging purposes today = datetime.date.today() loggingDateTime = datetime.datetime(today.year, today.month, today.day) dataFileName = buildCsvFileName(loggingDateTime) logFileName = buildLogFileName(loggingDateTime) #Setup 1-Wire sensor list writeFile(logFileName, "Setting up 1-Wire devices...\r\n") #Path to 1-wire device directories base_dir = '/sys/bus/w1/devices/' #Get a list of 1-wire devices oneWireDeviceList = os.listdir(base_dir) #Build temp sensor list tempSensors = list() for device in oneWireDeviceList: if((device[0:2] == '28') or (device[0:2] == '10')): sensor = DS18B20.DS18B20(base_dir+device+'/w1_slave') tempSensors.append(sensor) writeFile(logFileName, "There is(are) " + str(DS18B20.DS18B20.instances) + " DS18B20 instance(s)...\r\n") #Log csv file name writeFile(logFileName, "Logging data to " + dataFileName + "...\r\n") fileLegend = "Date, Time, Panel RMS Voltage, Panel RMS Current, Panel AVG Power, Battery Voltage, LabJack Temperature, Ambient Temperature\r\n" writeFile(logFileName, "File Legend = " + fileLegend) writeFile(dataFileName, fileLegend) #Setup DAQ writeFile(logFileName, "Setting up LabJack U3-HV DAQ...\r\n") daq = u3.U3() daq.getCalibrationData() # Set FIO0-FIO3 and FIO6 to Analog daq.configIO(FIOAnalog=0x4F) writeFile(logFileName, "Configuring U3-HV stream\r\n") daq.streamConfig(NumChannels=5, PChannels=[0, 1, 2, 3, 6], NChannels=[32, 32, 32, 31, 31], Resolution=3, ScanFrequency=SCAN_FREQUENCY) #Setup aio client writeFile(logFileName, "Setting up Adafruit_IO Client...\r\n") aio = Client(readFile("utilities/aio_key")) #Ready, set , go newTimeStamp = loggingDateTime.now() oldTimeStamp = newTimeStamp while(1): #Get current date today = datetime.date.today() #If new day, make new loggingDT and file names if(today.day != loggingDateTime.day): loggingDateTime = datetime.datetime(today.year, today.month, today.day) dataFileName = buildCsvFileName(loggingDateTime) logFileName = buildLogFileName(loggingDateTime) writeFile(logFileName, "Logging data to " + dataFileName + "\r\n") writeFile(dataFileName, fileLegend) #try to set consistent 30 second interval dt = 0 while(dt < SAMPLE_RATE_SECONDS): if(newTimeStamp.second >= oldTimeStamp.second): dt = newTimeStamp.second - oldTimeStamp.second else: dt = (newTimeStamp.second + (60 - oldTimeStamp.second)) newTimeStamp = loggingDateTime.now() oldTimeStamp = newTimeStamp #Get time stamp as csv string timeStampStr = str(newTimeStamp) timeStampStr = timeStampStr.replace(' ', ',') writeLineStr = (timeStampStr + ",") daq.streamStart() panelVoltageRMS = 0 panelCurrentRMS = 0 panelAvgPower = 0 batteryVoltage = 0 labJackTemp = 0 ambientTemp = 0 dataCount = 0 for s in daq.streamData(): if s is not None: if dataCount >= MAX_REQUESTS: break if s["errors"] != 0: writeFile(logFileName, "Errors counted: %s ; %s\r\n" % (s["errors"], loggingDateTime.now())) if s["numPackets"] != daq.packetsPerRequest: writeFile(logFileName,"----- UNDERFLOW : %s ; %s\r\n" % (s["numPackets"], loggingDateTime.now())) if s["missed"] != 0: writeFile(logFileName,"+++ Missed %s\r\n" % s["missed"]) panelVoltageRMS = getPanelVoltage(s) panelCurrentRMS = getPanelCurrent(s) batteryVoltage = getBatteryVoltage(s) dataCount += 1 else: writeFile(logFileName,"No data ; %s\r\n" % loggingDateTime.now()) daq.streamStop() updateFeed(aio, 'Solar Panel RMS Voltage', panelVoltageRMS, loggingDateTime, logFileName) writeLineStr += (str(panelVoltageRMS) + ",") updateFeed(aio, 'Solar Panel RMS Current', panelCurrentRMS, loggingDateTime, logFileName) writeLineStr += (str(panelCurrentRMS) + ",") panelAvgPower = round((panelCurrentRMS*panelVoltageRMS), 2 ) updateFeed(aio, 'Solar Panel Average Power', panelAvgPower, loggingDateTime, logFileName) writeLineStr += (str(panelAvgPower) + ",") updateFeed(aio, 'Battery Voltage', batteryVoltage, loggingDateTime, logFileName) writeLineStr += (str(batteryVoltage) + ",") labJackTemp = getLabJackTemp(daq) updateFeed(aio, 'LabJack Temperature', labJackTemp, loggingDateTime, logFileName) writeLineStr += (str(labJackTemp) + ",") ambientTemp = getAmbientTemp(tempSensors[0]) updateFeed(aio, 'Ambient Temperature', ambientTemp, loggingDateTime, logFileName) writeLineStr += (str(ambientTemp) + "\r\n") #log data locally writeFile(dataFileName, writeLineStr) main()