class DHTCollector(AbcCollector): def __init__(self, multipl_address): self.multipl_address = multipl_address self.gpio_functions = GF() self.gpio_functions.set_address(self.multipl_address) def get_time(self): return get_rfc_time() def get_offsetT_H(self, serial): with open("/home/pi/ESpy/ESpy/calibration/offset.txt", "r") as o: lines = o.readlines() for line in lines: l = line.split() if l[0] == serial: return float(l[1]), float(l[2]) return 0.0, 0.0 def read_sensors(self): self.gpio_functions.set_address(self.multipl_address) self.s_id = "DHTmulti{}".format(str(self.multipl_address).zfill(2)) attempts = 8 for i in range(attempts): humidity, temperature = Adafruit_DHT.read(Adafruit_DHT.DHT22, self.gpio_functions.data_pin) if (humidity and temperature) and humidity < 100.0 and humidity > 0.0: return self._format_output(humidity, temperature) else: print time.ctime() + ": reading {} sensors failed at attempt {}".format(self.s_id, i) time.sleep(2) return self._get_db_dict({"error": 1.0}) def _format_output(self, humidity, temperature): offset_T, offset_H = self.get_offsetT_H(self.s_id) fields = { "temperature": float("%.5f" % (temperature - offset_T)), "humidity": float("%.5f" % (humidity - offset_H)), } return self._get_db_dict(fields) def _get_db_dict(self, fields): return [{"measurement": self.s_id, "time": self.get_time(), "fields": fields}]
def __init__(self, multipl_address): self.multipl_address = multipl_address self.gpio_functions = GF() self.gpio_functions.set_address(self.multipl_address) self.fit_param = [] #fit_param: serial, fitA, fitB, air_value, pulse_ampl, pulse_width with open('/home/pi/ESpy/ESpy/calibration/fitparam.txt', 'r') as o: lines = o.readlines() for line in lines: k = line.split() if not k[0][0] == '#': self.fit_param.append(k) try: a = k[0][5] except(IndexError): print "The ESpy/calibration/fitparam.txt does not" \ + "have enough parameters for {}".format(k[0]) base_dir = '/sys/bus/w1/devices/' self.w1_dirs = [ os.path.join(base_dir, self.fit_param[i][0]) for i in range(len(self.fit_param)) ] self.serial_list = [ self.fit_param[i][0] for i in range(len(self.fit_param)) ]
def __init__(self, multipl_address): self.multipl_address = multipl_address self.gpio_functions = GF() self.gpio_functions.set_address(self.multipl_address) self.crc_lookup_table = [ 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53 ]
def __init__(self, multipl_address): self.multipl_address = multipl_address self.gpio_functions = GF() self.gpio_functions.set_address(self.multipl_address)
class ds18b20Collector(AbcCollector): def __init__(self, multipl_address): self.multipl_address = multipl_address self.gpio_functions = GF() self.gpio_functions.set_address(self.multipl_address) def get_time(self): return get_rfc_time() def _get_w1_tree_and_serials(self): base_dir = '/sys/bus/w1/devices/' device_files = glob.glob(base_dir + '28*') device_files.extend(glob.glob(base_dir + '10-*')) device_files = [x+'/w1_slave' for x in device_files] serials_list = [y[len(base_dir):-len('/w1_slave')] for y in device_files] if len(serials_list) <= 0: print 'Didn\'t find ds18b20 on port ' + str(self.multipl_address) return None, None else: return device_files, serials_list def _read_temp(self,filename): with open(filename, 'r') as f: lines = f.readlines() if lines[0].strip()[-3:] != 'YES': temp = None else: equals_pos = lines[1].find('t=') if equals_pos != -1: temp_string = lines[1][equals_pos+2:] temp = float(temp_string) / 1000.0 else: temp = None return temp def get_offset(self,serial): with open('/home/pi/ESpy/ESpy/calibration/offset.txt', 'r') as o: lines = o.readlines() for line in lines: l = line.split() if l[0] == serial: return float(l[1]) return 0.0 def read_sensors(self): os.system('modprobe w1-gpio') os.system('modprobe w1-therm') self.gpio_functions.set_address(self.multipl_address) attempts = 0 while attempts < 7: time.sleep(5) try: self.w1_devices, self.serials_list = self._get_w1_tree_and_serials() if self.w1_devices is not None and self.serials_list is not None: read_success = True break else: read_success = False attempts += 1 except (IOError): print time.ctime() + ": reading temperature sensors failed at attempt " + str(attempts) read_success = False attempts += 1 temp_meas = [] if read_success: for item,sensor in enumerate(self.w1_devices): # raw-reading takes 0.89 seconds for each sensor. # This is also usual when done in the terminal. Dunno why. temp = self._read_temp(sensor) if temp is not None: fields = {'temperature' : temp - self.get_offset(self.serials_list[item])} else: fields = {'error' : 1.} temp_meas.append({'measurement' : self.serials_list[item], 'time' : self.get_time(), 'fields' : fields}) else: print time.ctime() + ": reading temperature sensors failed at all attempts :-(" fields = {'error' : 1.} temp_meas.append({'measurement' : 'ds18b20_read_errors_port_' + str(self.multipl_address), 'time' : self.get_time(), 'fields' : fields}) return temp_meas
class ppp2016Collector(AbcCollector): def __init__(self, multipl_address): self.multipl_address = multipl_address self.gpio_functions = GF() self.gpio_functions.set_address(self.multipl_address) self.fit_param = [] #fit_param: serial, fitA, fitB, air_value, pulse_ampl, pulse_width with open('/home/pi/ESpy/ESpy/calibration/fitparam.txt', 'r') as o: lines = o.readlines() for line in lines: k = line.split() if not k[0][0] == '#': self.fit_param.append(k) try: a = k[0][5] except(IndexError): print "The ESpy/calibration/fitparam.txt does not" \ + "have enough parameters for {}".format(k[0]) base_dir = '/sys/bus/w1/devices/' self.w1_dirs = [ os.path.join(base_dir, self.fit_param[i][0]) for i in range(len(self.fit_param)) ] self.serial_list = [ self.fit_param[i][0] for i in range(len(self.fit_param)) ] def get_time(self): return get_rfc_time() def _read_raw_moisture(self,filename,serial_index): #fit_param: serial, fitA, fitB, air_value, pulse_ampl, pulse_width j = serial_index with open(filename, 'r') as f: lines = f.readlines() if lines[0].strip()[-3:] != 'YES': moisture = None else: equals_pos = lines[1].find('t=') if equals_pos != -1: moisture_string = lines[1][equals_pos+2:] #print "{}: {} moisture: ".format(j,self.fit_param[j][0]) + moisture_string moisture = float(moisture_string) / float(self.fit_param[j][3]) \ * float(self.fit_param[j][4]) * float(self.fit_param[j][5]) else: moisture = None return (moisture if not moisture == 0. else None) def _get_moisture(self,integrated,serial_index): j = serial_index moisture=(np.log(float(self.fit_param[j][2]))-np.log(integrated))/float(self.fit_param[j][1]) #print "integrated: " + str(integrated) + " moisture: " + str(moisture) return moisture if moisture > 0. else 0. def read_sensors(self): self.gpio_functions.set_address(self.multipl_address) os.system('modprobe w1-gpio') os.system('modprobe w1-therm') time.sleep(1) amount_of_read_sensors = 0 moisture_meas = [] for index,sensor_dir in enumerate(self.w1_dirs): if os.path.isdir(sensor_dir): sensor_file = os.path.join(sensor_dir,'w1_slave') raw_moisture = self._read_raw_moisture(sensor_file,index) if raw_moisture is not None: fields = {'Moisture' : self._get_moisture(raw_moisture,index)} else: fields = {'error' : 1.} moisture_meas.append({'measurement' : self.serial_list[index], 'time' : self.get_time(), 'fields' : fields}) amount_of_read_sensors += 1 else: print "omitting {}".format(sensor_dir) if amount_of_read_sensors == 0: print time.ctime() + ": no ppp2016 sensors read!" fields = {'error' : 1.} moisture_meas.append({'measurement' : 'ppp2016_read_errors_port_' + str(self.multipl_address), 'time' : self.get_time(), 'fields' : fields}) return moisture_meas
class ds2438Collector(AbcCollector): def __init__(self, multipl_address): self.multipl_address = multipl_address self.gpio_functions = GF() self.gpio_functions.set_address(self.multipl_address) self.crc_lookup_table = [ 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53 ] def get_time(self): return get_rfc_time() def _get_w1_tree_and_serials(self): base_dir = '/sys/bus/w1/devices/' device_file = glob.glob(base_dir + '26*') device_file = [x+'/rw' for x in device_file] serial_list = [y[len(base_dir):-len('/rw')] for y in device_file] if len(serial_list) <= 0: print 'Didnt find ds2438 on port ' + str(self.multipl_address) return None else: return device_file, serial_list def _get_measurements(self,device): buff = self.read_dev(device, 0x00) if buff is None: return None if len(buff) > 8: return [self.convert_T_bytes(buff[1], buff[2])/8*0.03125, # temperature [bin(buff[2]),bin(buff[1])], self.convert_V_bytes(buff[3], buff[4])/100. , # voltage self.convert_A_bytes(buff[5], buff[6])/(4096.*0.050), # current for a 0.050 Ohm Rsens bin(buff[0])] #status byte else: return None def get_offsetT_param(self,serial): with open('/home/pi/ESpy/ESpy/calibration/offset.txt', 'r') as o: lines = o.readlines() for line in lines: l = line.split() if l[0] == serial and len(l)==4: offset_T = float(l[1]) slope = float(l[2]) yhit = float(l[3]) return offset_T, slope, yhit elif l[0] == serial and len(l)==2: return float([1]), -38.0, 114.6 return 0.0, -38.0, 114.6 def read_sensors(self): self.gpio_functions.set_address(self.multipl_address) os.system('modprobe w1-gpio') attempts = 0 while attempts < 9: time.sleep(2) try: self.w1_devices, self.serial_list = self._get_w1_tree_and_serials() read_success = True break except: print time.ctime() + ": reading ds2438 chips failed at attempt " + str(attempts) read_success = False attempts += 1 T_M_meas = [] if read_success: for item,sensor in enumerate(self.w1_devices): #if self.serial_list[item] == "26-00000014f416": # this is the light sensor device = os.open(sensor, os.O_RDWR) meas = self._get_measurements(device) if meas is not None: T_offset,slope,yhit = self.get_offsetT_param(self.serial_list[item]) moisture = meas[2] #slope*meas[2]+yhit moisture = 0.0 if moisture < 0.0 else moisture moisture = 100.0 if moisture > 100.0 else moisture voltage = 0.0 if meas[2] < 0.0 else meas[2] voltage = 0.0 if meas[2] > 3.3 else meas[2] fields = {'temperature' : meas[0] - T_offset, 'voltage' : voltage} #float('%f' % moisture)} else: fields = {'error' : 1.} T_M_meas.append({'measurement' : self.serial_list[item], 'time' : self.get_time(), 'fields' : fields}) os.close(device) else: print time.ctime() + ": reading ds2438 chips failed at all attempts :-(" fields = {'error' : 1.} T_M_meas.append({'measurement' : 'ds2438_read_errors_port_' + str(self.multipl_address), 'time' : self.get_time(), 'fields' : fields}) return T_M_meas def read_dev(self, device, page): attempts = 1 buff = pack('BBB', 0x4E, page, 0x07) # 4E: write from scratchpad (SP) to eeprom: the 07 -> set IAD, CA, EE flags to 1 and AD to 0 -> use VAD input os.write(device, buff) buff = pack('BB', 0x44, page) # initiate temperature conversion os.write(device, buff) time.sleep(0.02) buff = pack('BB', 0xB4, page) # initiate voltage conversion os.write(device, buff) time.sleep(0.004) buff = pack('BB', 0xB8, page) # recall memory: copy content of eeprom to scratchpad os.write(device, buff) time.sleep(0.01) buff = pack('BB', 0xBE, page) # command to read and tell me scratchpad for idx in range(0, attempts): os.write(device, buff) out = os.read(device, 9) # read 9 chars (first one is the status byte?) out = unpack('BBBBBBBBB', out) #print str(out) if self.check_crc(out, 8) is True: return out else: time.sleep(0.01) pass return None def convert_V_bytes(self, lsb, msb): result = (msb << 8) | lsb # binary operator "<<" shifts left by one position, the "|" adds the lsb without considering overflow (I think... consider 2|1 and 2|2) if result >= 1024: #print "Result: " + str(~result) return -999. else: #print "Less than 32768" return result def convert_A_bytes(self, lsb, msb): result = (msb << 8) | lsb # binary operator "<<" shifts left by one position, the "|" adds the lsb without considering overflow (I think... consider 2|1 and 2|2) if result >= 1024: #print "Result: " + str(~result) return -(( (~result) & 0b1111111111 ) + 1) else: #print "Less than 32768" return result def convert_T_bytes(self, lsb, msb): result = (msb << 8) | lsb # binary operator "<<" shifts left by one position, the "|" adds the lsb without considering overflow (I think... consider 2|1 and 2|2) if result >= 32768: #print "Result: " + str(~result) return -(( (~result) & 0xFFFF ) + 1) else: #print "Less than 32768" return result; def check_crc(self, buff, length): crc = 0 for b in buff[:-1]: crc = self.crc_lookup_table[crc ^ int(b)] if crc == buff[length]: return True else: return False
class ppp40Collector(AbcCollector): def __init__(self, multipl_address): self.multipl_address = multipl_address self.gpio_functions = GF() self.gpio_functions.set_address(self.multipl_address) self.crc_lookup_table = [ 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53 ] def get_time(self): return get_rfc_time() def _get_w1_tree_and_serials(self): base_dir = '/sys/bus/w1/devices/' device_file = glob.glob(base_dir + '40*') device_file = [x+'/rw' for x in device_file] serial_list = [y[len(base_dir):-len('/rw')] for y in device_file] if len(serial_list) <= 0: print 'Didnt find moisture sensor on port ' + str(self.multipl_address) return None else: return device_file, serial_list def _get_measurements(self,device): buff = self.read_dev(device) if buff is None: print "buff is none in _get_measurements" return None if len(buff) > 8: return self.convert_Vs_bytes(buff[0], buff[1]) else: print "buff is <= 8 bytes long" return None def read_sensors(self): self.gpio_functions.set_address(self.multipl_address) os.system('modprobe w1-gpio') attempts = 0 while attempts < 9: print "attempts: " + str(attempts) time.sleep(5) try: self.w1_devices, self.serial_list = self._get_w1_tree_and_serials() read_success = True break except: print time.ctime() + ": reading moisture chips failed at attempt " + str(attempts) read_success = False attempts += 1 T_M_meas = [] if read_success: for item,sensor in enumerate(self.w1_devices): #if self.serial_list[item] == "26-00000014f416": # this is the light sensor device = os.open(sensor, os.O_RDWR) ml = self._get_measurements(device) if ml is not None: ml = 0.0 if ml < 0.0 else ml fields = {'mlPerKg' : ml} #float('%f' % moisture)} else: fields = {'error' : 1.} T_M_meas.append({'measurement' : self.serial_list[item], 'time' : self.get_time(), 'fields' : fields}) os.close(device) else: print time.ctime() + ": reading moisture failed at all attempts :-(" fields = {'error' : 1.} T_M_meas.append({'measurement' : 'moisture_read_errors_port_' + str(self.multipl_address), 'time' : self.get_time(), 'fields' : fields}) return T_M_meas def read_dev(self, device): attempts = 3 buff = pack('B', 0x44) # initiate temperature conversion os.write(device, buff) time.sleep(1) buff = pack('B', 0xBE) # read scratchpad os.write(device, buff) for idx in range(0, attempts): print "attemps idx: " + str(idx) os.write(device, buff) out = os.read(device, 9) # read 9 chars (first one is the status byte?) out = unpack('BBBBBBBBB', out) #print str(out) if self.check_crc(out, 8) is True: return out else: print "crc not true" time.sleep(0.01) pass return None def convert_Vs_bytes(self, lsb, msb): print "msb: " + str(bin(msb)) + " lsb: " + str(bin(lsb)) result = (msb << 8) | lsb # binary operator "<<" shifts left by one position, the "|" adds the lsb without considering overflow (I think... consider 2|1 and 2|2) print result result = 5.*(1.89221e-16*result**4. - 2.27935e-11*result**3. + 5.64079e-07*result**2. - 0.00571806*result + 27.0329) #if result >= 1024: ##print "Result: " + str(~result) #return -999. #else: ##print "Less than 32768" #return result return result #def convert_T_bytes(self, lsb, msb): #result = (msb << 8) | lsb # binary operator "<<" shifts left by one position, the "|" adds the lsb without considering overflow (I think... consider 2|1 and 2|2) #if result >= 32768: ##print "Result: " + str(~result) #return -(( (~result) & 0xFFFF ) + 1) #else: ##print "Less than 32768" #return result; def check_crc(self, buff, length): crc = 0 for b in buff[:-1]: crc = self.crc_lookup_table[crc ^ int(b)] if crc == buff[length]: return True else: return False