#!/usr/bin/python # -*- coding: utf-8 -*- #--------------------------------------------------------------- import serial import time import sys import datetime import urllib import ConfigParser import os, sys #--------------------------------------------------------------- # COSTANTI MSGLEN = 9 TIMEOUTSERIALE = 10 MAXRETRY = 3 # DA FILE CONF idxMacchina = "2001" SAMPLETIME = 0.1 TIMEOUTSHORT = (SAMPLETIME*20) TIMEOUTLONG = (SAMPLETIME*600) # VAR to_enable = False to_short = TIMEOUTSHORT to_long = TIMEOUTLONG to_serial = TIMEOUTSERIALE to_retry = MAXRETRY errormsglen = 0 #--------------------------------------------------------------- # classe logger class Logger: def __init__(self, filename): try: self.filename = filename except: logga("LOGGER: errore try su self.filename") sys.exit(1) def __call__(self, string): try: file = open(self.filename, 'a') file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') file.write(string + '\n') file.close() except: logga("LOGGER: errore try su scrittura") sys.exit(1) #--------------------------------------------------------------- # lettura buffer seriale e pulizia caratteri non stampabili # ritorna '' se non c'è un messaggio buono o il messaggio pulito ( due bytes hex ) # il messaggio ha il formato xxi00 00xxx def readSeriale(): global to_serial global to_retry global errormsglen ret = '' current = '' i = 0 # ritorna '' se non ci sono abbastanza caratteri try: if ser.inWaiting() < MSGLEN : # # to_serial = to_serial - 1 # se non mi risponde, faccio un ' altra richiesta.... # if to_serial <= 0: # try: # requestData () # except: # logga("SERIALE: errore su requestData") # sys.exit(1) # to_serial = TIMEOUTSERIALE # ripristino timer # to_retry = to_retry - 1 # contatore retry # if to_retry <= 0: # logga ( 'IOB not responding' ) # return ret logga("SERIALE: errore msglen < 9 char - Errore no. " + str(errormsglen)) errormsglen = errormsglen +1 avviaSeriale() time.sleep(.2) if errormsglen > 30: sys.exit(1) except: if startstatus == 0: logga ("Porta SERIALE non disponibile - ser.inWaiting error - exit... - Errore no. " + str(errormsglen)) errormsglen = errormsglen +1 avviaSeriale() time.sleep(.2) if errormsglen > 30: sys.exit(1) # finchè c'è robba .. leggi e tieni i buoni to_serial = TIMEOUTSERIALE to_retry = MAXRETRY try: while ser.inWaiting() > 0 : try: c = ser.read(1) except: logga("SERIALE: errore su try ser.read") sys.exit(1) # filtra caratteri non stampabili if c > ' ' : current += c #sys.stdout.write(current + '<<<<\n') # ora il messaggio ha il formato xxxxxi00 00xxx : cerco la 'i' iniziale try: while i < len(current) and current[i] != 'i': i = i + 1 except: logga("SERIALE: errore su ricerca i iniziale") sys.exit(1) # se non ho trovato la 'i' restituisco '' if i == len(current)-1: return ret else: current = current[i+1:i+3] # richiesta dati ad IOB requestData() #sys.stdout.write ( current + '\n') except: if startstatus == 0: logga ('Porta SERIALE non disponibile - ser.inWaiting e filtraggio error...exit') sys.exit(1) return current #--------------------------------------------------------------- # richiesta dati ad IOB : scrittura su seriale def requestData (): try : ser.write ("$i" + '\r\n') ser.flush() except : if startstatus == 0: logga ( "SERIAL: Errore di scrittura/flush") #--------------------------------------------------------------- #Funzione di scrittura su url con try-except def chiamaUrl(): try: url = URLBASE + idxMacchina + URLADV1 + value urllib.urlopen ( url ) except: logga ( "NETWORK:Errore http-no com rete-timeout" + url ) #--------------------------------------------------------------- # Funzione che verifica possibilità di creare log e include testo corrente def logga(message) : try: log(message) except : pass #--------------------------------------------------------------- def avviaSeriale(): global ser try: ser = serial.Serial( port = comm_port , baudrate = 9600 , parity = serial.PARITY_NONE , stopbits = serial.STOPBITS_ONE , bytesize = serial.EIGHTBITS ) startstatus = 0 except serial.serialutil.SerialException , e : try: if startstatus == 0: logga ( "SERIAL:Errore apertura seriale - " + comm_port) except: pass sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) if errormsglen > 30: sys.exit (1) #--------------------------------------------------------------- #--------------------------------------------------------------- # MAIN try: config = ConfigParser.RawConfigParser() config.read ( 'readSeriale.cfg' ) SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) idxMacchina = config.get ( 'id' , 'idxMacchina' ) comm_port = config.get ( 'comm' , 'port' ) URLBASE = config.get ( 'web' , 'URLBASE' ) URLADV1 = config.get ( 'web' , 'URLADV1' ) LOGFILE = config.get ( 'log' , 'LOGFILE' ) LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) except: sys.exit(1) # oggetto Logger try: log = Logger(LOGFILE) except: # manda mail o simili - FARE!!! print "LOG: Impossibile creare file log con nome " print (LOGFILE) print '\n\n Read seriale IOB v.0.2 !!!!\n' global startstatus startstatus = 1 if startstatus == 1: logga("Avvio Programma") # Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza if os.name == 'posix': import unix else: import win logga ( "Start Read seriale IOB v.0.2") # lettura file configurazione # [comm] # port = /dev/ttyS0 # [id] # idxMacchina = 2001 # [time] # SAMPLETIME = 0.1 # TIMEOUTSHORT = 200 # TIMEOUTLONG = 6000 print ( ' comm_port = %s' % ( comm_port ) ) print ( ' idxMacchina = %s' % ( idxMacchina ) ) print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) print ( ' URLBASE = %s' % ( URLBASE ) ) print ( ' URLADV1 = %s' % ( URLADV1 ) ) print ( ' LOGFILE = %s' % ( LOGFILE ) ) print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) # -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') to_short = TIMEOUTSHORT to_long = TIMEOUTLONG #-------------------------------------------------------------- #--------------------------------------------------------------- # apertura seriale avviaSeriale() #try: # ser = serial.Serial( # port = comm_port , # baudrate = 9600 , # parity = serial.PARITY_NONE , # stopbits = serial.STOPBITS_ONE , # bytesize = serial.EIGHTBITS # ) # print "Initialized!" #except serial.serialutil.SerialException , e : # try: # logga ( "SERIAL:Errore apertura seriale - " + comm_port) # except: # pass # sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) # sys.exit (1) #--------------------------------------------------------------- # ciclo forever and ever old = '' # richiesta dati ad IOB try: requestData() except: logga("SERIALE: errore sul try di requestData") sys.exit(1) while 1: try: time.sleep (SAMPLETIME) except: logga("SERIALE_SLEEP: errore attesa sampletime") # lettura dati da IOB try: value = readSeriale() except: if startstatus == 0: logga("errore PRIMA LETTURA SERIALE") sys.exit(1) if ( value != '' ) : if value != old : #loggo e invio dati try: logga ( value ) errormsglen = 0 chiamaUrl() except: logga("URLBROWSER: errore registrazione valore e chiamaUrl") pass #enable e reset timer to_enable = True to_short = TIMEOUTSHORT to_long = TIMEOUTLONG old = value # gestione timeout breve if ( to_enable ) : to_short = to_short - SAMPLETIME if to_short <= 0: #loggo e invio dati try: logga ( '>' + value ) errormsglen = 0 chiamaUrl() except: pass to_short = TIMEOUTSHORT to_enable = False # dopo un colpo il timer breve viene disabilitato to_long = TIMEOUTLONG # gestione timeout lungo to_long = to_long - SAMPLETIME if to_long <= 0: #loggo e invio dati try: logga ( '>>' + value ) errormsglen = 0 chiamaUrl() except: pass to_long = TIMEOUTLONG