Jul-24-2018, 08:44 AM
Hi there,
I have this program (datalog_v26) that reads sensors and writes the readings to disk.
Like the calling program datalog_v26, its runs every few seconds resulting every time in an entry on disk that the pump is (still) on or off which is somewhat useless as i only want to see the transitions.
So in pumpcontrol i added lines 74-76 and 83-85.
"prevpumpstat referenced before assignment" in line 73 or 84.
Question is: how do i prevent the useless disk writes and log only once the transition from on to off or vice versa? I wrecked my brain but my Python knowledge is insufficient.
Thansk for any pointers,
Steffen
I have this program (datalog_v26) that reads sensors and writes the readings to disk.
#!/usr/bin/env python #====================================================================== # Program name: datalog_v26 # Versie 2.6; 20/07/2018 # Reads the sensors and stores them on HD. # Controls bilge pumps. # Uses function pumpcontrol and key_check # # # # #====================================================================== #Importeer benodigde libraries. import sys import time import csv import os import spidev import RPi.GPIO as GPIO import I2C_LCD_driver_twoLCD from key_check import status from pumpcontrol import pumpcontrol # Set variabelen en GPIO pins. mylcd1 = I2C_LCD_driver_twoLCD.lcd(0x26) mylcd2 = I2C_LCD_driver_twoLCD.lcd(0x27) spi = spidev.SpiDev() spi.open(0,0) GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(23,GPIO.OUT) GPIO.setup(24,GPIO.OUT) GPIO.setup(25,GPIO.OUT) # Function reads mcp3008 adc. def read_MCP(channel): adc = spi.xfer2([1,(8+channel)<<4,0],20000) adcread = ((adc[1]&3) << 8) + adc[2] return adcread # Function to read multiple ds18b20 sensors on a 1wire bus on gpio 4 def read_ds18b20(sensorid): device = "/sys/bus/w1/devices/"+ sensorid +"/w1_slave" try: with open (device) as tfile: text = tfile.read() except FileNotFoundError: GPIO.output(25,True) # Turn on GPIO25 with FileNotFound LED to indicate ID not present. notemp = 9999 return notemp # Format the reading from sensor sensor_data =text.split(" ")[20] temp_raw = float(sensor_data[2:]) temp = temp_raw / 1000 digitemp = '%.1f' % temp # print ("digitemp = " + digitemp) return digitemp # Writes data to disk def write_to_disk(writedata): csvfile = "/media/pi/Seagate Portable/testdata.csv" with open (csvfile, 'a') as output: writer = csv.writer(output, delimiter = ',' ,lineterminator = '\n') writer.writerow(writedata) GPIO.output(25,False) # Reset FileNotFound LED while True: datum = (time.strftime('%d/%m/%Y')) tijd = (time.strftime('%H:%M:%S')) while True: datum = (time.strftime('%d/%m/%Y')) tijd = (time.strftime('%H:%M:%S')) # time.sleep(1) # Checks the stus of the key switch. if status()== 'ON': # Key switch is on break else: # Key switch is off print ('Schakelaar is UIT') # Checks water levels when key switch is off. threshold = 500 boord = 'sb' pumpsb = pumpcontrol(threshold,boord) # Call pumpcontrol; return status of pump as pumpstat sb list = pumpsb # print (list[1]) print (pumpsb) threshold = 500 boord = 'bb' pumpbb = pumpcontrol(threshold,boord) # Call pumpcontrol; return status of pump as pumpstat bb print (pumpbb) time.sleep(2) # Write pump status to file on HD. data = (pumpsb, pumpbb)# write_to_disk(data) # Zet de pomp SB aan of uit door de MCP0 waarde te vergelijken met de waarde. threshold = 500 boord = 'sb' pumpsb = pumpcontrol(threshold,boord) # Call pumpcontrol; return status of sb pump as pumpstat sb print (pumpsb) threshold = 250 boord = 'bb' pumpbb = pumpcontrol(threshold,boord) # Call pumpcontrol; return status of bb pumps as pumpstat bb print (pumpbb) # Write pump status data to HD. # data = (pumpsb,pumpbb) # write_to_disk(data) # Read ds18b20 sensors with function 'read_ds18b20'. temp1 = float(read_ds18b20('28-000009adc801')) # Motor 1 temp2 = float(read_ds18b20('28-000009adc801')) # Motor 2 temp3 = float(read_ds18b20('28-000009adc801')) # Future expansion # REMARK xxxadc801 is tijdelijk de enige digitale sensor. # Read the mcp channels with the function 'read_MCP'. lijst = [] for offset in range(0,8): adcread = read_MCP(offset) # print (adcread) lijst.append(adcread) data = [temp1,temp2,temp3,round(lijst[0],1),round(lijst[1],1), round((((lijst[2]*3.3/1024)-0.52)/0.08),1), round((((lijst[3]*3.3/1024)-0.52)/0.08),1), round(((lijst[4]*330/1024)-50),1)] #========================================================= # # 'temp1' is temparatuur motor SB. # 'temp2' is temperatuur motor BB # 'temp3' is not used # 'lijst[0]' is watersensor SB. # 'lijst[1]' is watersensor BB. # 'lijst[2]' is accustroom SB. # 'lijst[3]' is accustroom BB. # 'lijst[4]' is buiten temperatuur met TMP36. # #========================================================= # blinks temp if > limit # if int(temp1) > 25: # for i in range(1,5): # mylcd1.lcd_display_string('BB motor='+str(temp1)+chr(223)+'C',1) # time.sleep(1) # mylcd1.lcd_clear() # time.sleep(1) mylcd2.lcd_display_string('BB motor='+str(temp1)+chr(223)+'C',1) mylcd1.lcd_display_string('SB motor='+str(temp2)+chr(223)+'C',1) mylcd1.lcd_display_string('Outside='+str(round((lijst[4]*330/1024)-50,1))+chr(223)+'C',3) # print (data) # Write sensor data to HD logdata = (datum, tijd, data) print (logdata) write_to_disk(logdata) time.sleep(1)It also calls "pumpcontrol" to check two water level sensors (bb, port and sb, starboard) and turn on/off two bilge pumps. Pumpcontrol also writes the status of the pumps to disk.
Like the calling program datalog_v26, its runs every few seconds resulting every time in an entry on disk that the pump is (still) on or off which is somewhat useless as i only want to see the transitions.
So in pumpcontrol i added lines 74-76 and 83-85.
#!/usr/bin/env python #=================================================================================== # Function name = pumpcontrol # Version 1.0, date 15/07/2018 # parameters are 'boord' bb or sb and 'threshold' # returns 'pumpstat' pump on or off # Called from datalog.py # Checks waterlevels SB and BB named reading and compares to threshold from calling # program. # Turn on appropriate pump and displays status message. # #=================================================================================== # Import requiredf libraries. import sys import time import csv import os import spidev import RPi.GPIO as GPIO import I2C_LCD_driver_twoLCD # Set variables and GPIO pins. spi = spidev.SpiDev() spi.open(0,0) GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(23,GPIO.OUT) GPIO.setup(24,GPIO.OUT) datum = (time.strftime('%d/%m/%Y')) tijd = (time.strftime('%H:%M:%S')) # Writes data to disk def write_to_disk(writedata): csvfile = "/media/pi/Seagate Portable/testdata.csv" with open (csvfile, 'a') as output: writer = csv.writer(output, delimiter = ',' ,lineterminator = '\n') writer.writerow(writedata) # Function reads MCP3008 channel 'sensorid'. def read_mcp(mcpch): adc = spi.xfer2([1,(8+mcpch)<<4,0],20000) adcread = ((adc[1]&3) << 8) + adc[2] # print ('adcread=',adcread) return adcread def pumpcontrol(threshold,boord): if (boord == 'sb'): mcpch = 0 gpio = 23 displ = I2C_LCD_driver_twoLCD.lcd(0x26) elif (boord == 'bb'): mcpch = 1 gpio = 24 displ = I2C_LCD_driver_twoLCD.lcd(0x27) else: pumpstat = False return 'No valid boord' # Check water sensor SB/BB, channel 0/1 from ADC. reading = read_mcp(mcpch) # Compare 'threshold' with adc reading and turn pump on/off if (threshold < reading): GPIO.output(gpio,GPIO.HIGH) # pump relay SB/BB ON displ.lcd_display_string(boord+' pomp actief',4) pumpstat = (boord+ ' pomp ','ON') print (pumpstat[1]) logdata = (datum, tijd, pumpstat) if prevpumpstat == 'OFF': write_to_disk(logdata) prevpumpstat = 'ON' else: GPIO.output(gpio,GPIO.LOW) # pomp relay SB/BB OFF pumpstat = (boord+ ' pomp ','OFF') print (pumpstat[1]) logdata = (datum, tijd, pumpstat) if prevpumpstat == 'ON': write_to_disk(logdata) prevpumpstat = 'OFF' return pumpstat def _test(): pass if __name__ == '__main__': # This part runs only when this script is the main script, not when imported from other _test()But that does not work for obvious reasons.
"prevpumpstat referenced before assignment" in line 73 or 84.
Question is: how do i prevent the useless disk writes and log only once the transition from on to off or vice versa? I wrecked my brain but my Python knowledge is insufficient.
Thansk for any pointers,
Steffen