def gateway(self): post_server='production_server_address' #production server #post_server='development_server_address' #development server logfile=open(self.logfilepath, "a") logfile.close() N=10 #number of channels in CurrentCost EnvirNET i=0 iter=0 #iteration number between 0 and 10000 L1=L2=L3=0 #numbers of elements into the redis tails try: self.redis_DB = redis.StrictRedis(host='localhost', port=6379, db=0) except: log2file("Error while connecting to redis DB", self.logfilepath) time_out=4 #timeout for waiting connection to civis server while True: ack=ack1=ack2=ack3=False iter+=1 print "iteration #", iter if iter==10000: iter=0 self.redis_access_ok() #periodically checks connection to Redis server L1=0 for i in range (0,N): L1=L1+self.redis_DB.llen("cycle_energy"+str(i)) L2=self.redis_DB.llen("Gas_measure_tail") L3=self.redis_DB.llen("OEM_data") L=L1+L2+L3 #total amount of elements into the gateway-related redis tails if L>0: try: print "connected to server: "+post_server+"\n" conn=httplib.HTTPConnection(post_server, timeout=time_out) #-------Section dedicated to CurrentCost measures forwarding try: print "Electricity" for i in range (0,N): L1=self.redis_DB.llen("cycle_energy"+str(i)) #for each Envir channel, checks if the related list print "Lunghezza tail redis: "+str(L1) if L1 != 0: #if REDIS DB is not empty message=self.redis_DB.lpop("cycle_energy"+str(i)) #pops the last element in the selected Redis list print "Il messaggio e': \n"+message try: headers={"Content-Type" : "application/text", "Accept-Charset" : "utf-8", "Accept" : "text/plain"} #connects to server conn.request('POST', '/CivisEnergy/DataParser.svc/postEnvirData', message, headers) #posts string and headers r=conn.getresponse() #gets response print r.read() #time.sleep(1) ack1=True #post_to_server("10.41.5.101:49780/postEnvirData", message) #response=urllib2.urlopen('http://civis.cloud.reply.eu/CivisEnergy/DataParser.svc/postEnvirData', message).read() i+=1 if i==N: #loops among all available Redis lists/channels (N=10: 0-9) i=0 except: #if something goes bad in the POST, message=message[:-2]+"\t0" #the real-time flag is modified self.redis_DB.rpush("cycle_energy"+str(i), message) # and the message is pushed again the element in the tail ack1=False print "Failed to send: "+message print 'Warning: Problems in contacting CIVIS Server while sending electricity data' log2file("Error: problems in contacting CIVIS Server while sending electricity data", self.logfilepath) except: print 'error while forwarding CurrentCost data to server: perhaps network problems?' log2file("Error: while forwarding CurrentCost data to server: perhaps network problems?", self.logfilepath) time.sleep(2) #-------Section dedicated to Gas measures forwarding try: print "Gas" L2=self.redis_DB.llen("Gas_measure_tail") print "Lunghezza tail redis: "+str(L2) #if the gas measures list if L2 != 0: #in REDIS DB is not empty message=self.redis_DB.lpop("Gas_measure_tail") #pops the last element in the selected Redis list print "Il messaggio e': \n"+message try: headers={"Content-Type" : "application/text", "Accept-Charset" : "utf-8", "Accept" : "text/plain"} #connects to server conn.request('POST', '/CivisEnergy/DataParser.svc/postGasData', message, headers) #posts string and headers r=conn.getresponse() #gets response print r.read() #time.sleep(1) ack2=True except: #if something goes bad in the POST, message=message[:-2]+"\t0" #the real-time flag is modified self.redis_DB.rpush("Gas_measure_tail", message) #and the gateway pushes again the element in the list print "Failed to send: "+message ack2=False print 'Warning: Problems in contacting CIVIS Server while sending gas data' log2file("Error: problems in contacting CIVIS Server while sending gas data", self.logfilepath) except: print 'error while forwarding FastForward data to server: perhaps network problems?' log2file("Error: while forwarding FastForward data to server: perhaps network problems?", self.logfilepath) time.sleep(2) #-------Section dedicated to OEM data forwarding try: print "Temperature" print "Lunghezza tail redis: "+str(L3) #checks if the temperature measures list if L3 != 0: #in REDIS DB is not empty message=self.redis_DB.lpop("OEM_data") #pops the last element in the selected Redis list print "Il messaggio e': \n"+message try: headers={"Content-Type" : "application/text", "Accept-Charset" : "utf-8", "Accept" : "text/plain"} #connects to server conn.request('POST', '/CivisEnergy/DataParser.svc/post_OEMData', message, headers) #posts string and headers r=conn.getresponse() #gets response print r.read() #time.sleep(1) ack3=True except: #if something goes bad in the POST, message=message[:-2]+"\t0" #the real-time flag is modified self.redis_DB.rpush("OEM_data", message) #and the gateway pushes again the element in the list print "Failed to send: "+message ack3=False print 'Warning: Problems in contacting CIVIS Server while sending OEM data' log2file("Error: problems in contacting CIVIS Server while sending OEM data", self.logfilepath) except: print 'error while forwarding OEM data to server: perhaps network problems?' log2file("Error: while forwarding OEM data to server: perhaps network problems?", self.logfilepath) time.sleep(2) conn.close() except: print 'Warning: Problems in connection with CIVIS Server... timeout after '+str(time_out)+' seconds.' log2file("Warning: Problems in connection with CIVIS Server... timeout after "+str(time_out)+" seconds.", self.logfilepath) time.sleep(3) ack=(ack1 or ack2 or ack3) print ack if L==0: sleepTime=6 elif L>0 and L<10: if ack: sleepTime=2.5 else: sleepTime=60 elif L>10 and L<50: if ack: sleepTime=1 else: sleepTime=30 else: if ack: sleepTime=0.4 else: sleepTime=30 time.sleep(sleepTime) logfilesize=os.stat(self.logfilepath).st_size if logfilesize>50000000: #clears the log if it reaches 50MB logfile=open(self.logfilepath, "w") logfile.close()
from file_tail import * import redis from getSettings import * from init_time import * from log2file import * envir_logfile="/home/pi/sw/CurrentCost/envir_log.txt" logfile=open(envir_logfile, "a") logfile.close() c= ntplib.NTPClient() #NTP client for periodic synch ot Raspberry time try: apartmentID=getApartmentID() except: log2file("Error during elaborations for validating contract data or accessing config files", envir_logfile) #raise Exception("Error during elaborations for validating contract data or accessing config files") print "Assigned Apartment ID: "+apartmentID redis_connection=False while redis_connection==False: try: print "Connecting to Redis Server" redis_DB = redis.StrictRedis(host='localhost', port=6379, db=0) redis_connection=redis_DB.ping() redis_connection=True print "Connection to Redis Server successful" except:
def _process_post(self, databuffer): """Send data to Redis server""" try: logfilesize=os.stat(self.logfilepath).st_size if logfilesize>50000000: #clears the log if it reaches 50MB logfile=open(self.logfilepath, "w") logfile.close() except: print "Impossible to calculate logfile size and eventually reset it" Redis_conn=False try: self.redis_DB.ping() print "\nRedis is connected\n" Redis_conn=True except: print "\nRedis was not connected... trying to connect again\n" try: os.system('sudo /etc/init.d/redis-server restart') self.redis_DB = redis.StrictRedis(host='localhost', port=6379, db=0) Redis_conn=True except: print "Impossible to connect to Redis DB" log2file("ERROR: Impossible to connect to Redis DB after its restart", self.logfilepath) Redis_conn=False time.sleep(60) if Redis_conn: ApartmentID=self.ApartmentID PositionID=self.PositionID try: #Calculation of timezone offset offset =time.timezone if (time.localtime().tm_isdst==0) else time.altzone offset=-offset/3600.0 rest=int(abs(offset*4)%4) if rest==0: timezone='{:=+#03,d}'.format(int(offset))+":00" elif rest==1: timezone='{:=+#03,d}'.format(int(offset))+":15" elif rest==2: timezone='{:=+#03,d}'.format(int(offset))+":30" elif rest==3: timezone='{:=+#03,d}'.format(int(offset))+":45" print 'Local timezone: '+timezone except: print 'Problems in calculating local timezone offset' timezone="+00:00" print 'Local timezone set to: '+timezone #print databuffer # databuffer is of format: # [[timestamp, nodeid, datavalues][timestamp, nodeid, datavalues]] # [[1399980731, 10, 150, 250 ...]] # time that the request was sent at # sentat = datetime.now() L=len(databuffer) #print L, databuffer try: ntp_synched=self.redis_DB.lindex("ClockFlag",0) if ntp_synched==None: ntp_synched="0" message1="" message2="" for k in range (0,L): #disabled to get the measure only 1 time each len(databuffer). To increase the lenght of databuffer and reduce in this way #the sample time, modify the /boot/emonhub.conf "interval" parameter for CIVIS service (interval=64*desired lenght+2) NodeID=databuffer[k][1] if NodeID==19: SensorNumber="32" IndoorTemp=float(databuffer[k][2])/10.0 message1 = ApartmentID+"\t"+datetime.fromtimestamp(int(databuffer[k][0])).strftime('%Y-%m-%dT%H:%M:%S')+timezone+"\t"+SensorNumber+"\t"+str(IndoorTemp)+"\t"+PositionID+"\t"+ntp_synched+"\t1" elif NodeID==22: SensorNumber="33" OutdoorTemp=float(databuffer[k][2])/10.0 message2 = ApartmentID+"\t"+datetime.fromtimestamp(int(databuffer[k][0])).strftime('%Y-%m-%dT%H:%M:%S')+timezone+"\t"+SensorNumber+"\t"+str(OutdoorTemp)+"\t"+PositionID+"\t"+ntp_synched+"\t1" if message1!="": self.redis_DB.rpush("OEM_data", message1) if message2!="": self.redis_DB.rpush("OEM_data", message2) #print(redis_DB.lrange("OEM_data", 0, -1)) #enables the visualization of the entire tail print message1 print message2 return True except: print 'Error in inserting data into Redis DB' log2file("ERROR: error in inserting data into Redis DB", self.logfilepath) time.sleep(15) return False