5524850eac
- fix condizione invio immediata "secondo dato" x calcolo delta errato - fix log eccezioni
706 lines
25 KiB
Python
706 lines
25 KiB
Python
# -*- coding: utf-8 -*-
|
|
# IOB-WIN-PSER v. 2.8.2
|
|
# - porting versione interpretata su Python2 + XP a Python3
|
|
# - aggiunta classi Redis
|
|
# - compilato con pyInterpreter
|
|
# - single instance timer
|
|
# - invio multiplo x send eventi AccodaEVti
|
|
# - attenzione .. non c'e' la possibilita di definire bit blinking, inversione ecc.
|
|
# - gestione wait se troppi errori in msglen...
|
|
# - 2.8 correzione gestione loghandler x logrotate e scrittura doppia (log + console separate)
|
|
# - 2.8.2 fix gestione eccezioni e log + fix gestione timeout short (SAMPLETIME e non delta x calcolo scadenza)
|
|
#---------------------------------------------------------------
|
|
|
|
import configparser
|
|
import json
|
|
import logging
|
|
import logging.handlers
|
|
import os, sys
|
|
import queue
|
|
import redis
|
|
import serial
|
|
import sys
|
|
import threading
|
|
import time
|
|
import urllib
|
|
|
|
from datetime import datetime
|
|
from array import *
|
|
from logging.handlers import RotatingFileHandler
|
|
from urllib.request import urlopen
|
|
|
|
#--------------------------------------------------------------
|
|
# Setup COSTANTI e variabili globali
|
|
#--------------------------------------------------------------
|
|
# Conf Generale
|
|
PROGRAM_NAME= 'IOB-WIN-PythonSERial v.2.8.2'
|
|
# IOB_NAME='IOB'
|
|
# IOB_CONF='IOB.cfg'
|
|
IOB_NAME='L001'
|
|
IOB_CONF='L001.cfg'
|
|
# gestione folders
|
|
BASE_PATH = 'c:\\Steamware'
|
|
BASE_LOG_PATH = 'c:\\Steamware\\logs'
|
|
# gestione REDIS
|
|
REDIS_HOST = '127.0.0.1'
|
|
REDIS_PORT = 6379
|
|
REDIS_DB = 0
|
|
# Logging
|
|
MAY_LOG_FILE = 30
|
|
LOGFILE = 'logfile.txt'
|
|
LOGLEVEL = 1
|
|
MAX_LOG_SIZE = 1024 * 10
|
|
NUM_LOG_RETAIN = 5
|
|
# parametri per comunicazione Seriale
|
|
MSGLEN = 5
|
|
TIMEOUTSERIALE = 10
|
|
MAXRETRY = 3
|
|
# numero campioni filtraggio segnale ballerino
|
|
MAX_COUNTER_BLINK = 10
|
|
# DA FILE CONF
|
|
idxMacchina = 'L003'
|
|
WAIT_RECONN = 1
|
|
SAMPLETIME = 0.1
|
|
TIMEOUTSHORT = (SAMPLETIME*20)
|
|
TIMEOUTLONG = (SAMPLETIME*600)
|
|
SENDURLTIME = 0.08
|
|
NMAXSEND = 5 # numero massimo di invii per singolo ciclo di svuotamento
|
|
#--------------------------------------------------------------
|
|
|
|
|
|
#--------------------------------------------------------------
|
|
# Setup VARIABILI globali
|
|
#--------------------------------------------------------------
|
|
# appoggio
|
|
to_enable = False
|
|
to_short = TIMEOUTSHORT
|
|
to_long = TIMEOUTLONG
|
|
errormsglen = 0
|
|
# timer x conteggio tempi esecuzione
|
|
last_exe = time.time()
|
|
# contatore: serve x match tra AccodaEV ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 9999
|
|
cont = '0'
|
|
# variabile stato online/offline della macchina
|
|
onLine = '1'
|
|
# variabile stato seinding/waiting x la parte invio URL
|
|
sending = '0'
|
|
# variabile stato timer thread busy
|
|
timer_busy = False
|
|
# Setup array per ingressi filtrati
|
|
i_counters = array ('i',[0,0,0,0,0,0,0,0])
|
|
B_blinking = array ('B',[0,0,0,0,0,0,0,0])
|
|
B_previous = array ('B',[0,0,0,0,0,0,0,0])
|
|
B_input = array ('B',[0,0,0,0,0,0,0,0])
|
|
B_output = array ('B',[0,0,0,0,0,0,0,0])
|
|
B_inverting = array ('B',[0,0,0,0,0,0,0,0])
|
|
B_filter = array ('B',[0,0,0,0,0,0,0,0])
|
|
B_filter_prev = array ('B',[0,0,0,0,0,0,0,0])
|
|
B_temp = array ('B',[0,0,0,0,0,0,0,0])
|
|
i_filter_counters = array ('i',[0,0,0,0,0,0,0,0])
|
|
# Gestione coda (condivisa) x registrazione eventi ed invio URL
|
|
Coda = queue.Queue(0)
|
|
#--------------------------------------------------------------
|
|
|
|
|
|
#--------------------------------------------------------------
|
|
# Classe helper x pubblicazione stato vero IOB-MAN
|
|
#--------------------------------------------------------------
|
|
class IobWinStatus:
|
|
def toJSON(self):
|
|
return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True)
|
|
#stream = 'cse' # Class Variable
|
|
def __init__(self,codIob,iobType):
|
|
self.CodIob = codIob
|
|
self.IobType = iobType
|
|
self.counterIOB = 0
|
|
self.counterMAC = 0
|
|
self.freeNotes = ''
|
|
self.lastDataIn = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
self.lastDataOut = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
self.lastUpdate = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
self.online = False
|
|
self.queueAlLen = 0
|
|
self.queueEvLen = 0
|
|
self.queueFlLen = 0
|
|
self.queueMsLen = 0
|
|
self.queueRawTransfLen = 0
|
|
self.queueUlLen = 0
|
|
self.semIn = 'ND'
|
|
self.semOut = 'ND'
|
|
self.currParams = {}
|
|
self.setupParams = {}
|
|
#--------------------------------------------------------------
|
|
|
|
|
|
#---------------------------------------------------------------
|
|
# Funzione helper x timer thread
|
|
#---------------------------------------------------------------
|
|
def do_every (interval, worker_func, iterations = 0):
|
|
if iterations != 1:
|
|
threading.Timer (
|
|
interval,
|
|
do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1]
|
|
).start ();
|
|
|
|
worker_func ();
|
|
#---------------------------------------------------------------
|
|
|
|
|
|
#--------------------------------------------------------------
|
|
# Seriale: chiusura porta + uscita da programma
|
|
#--------------------------------------------------------------
|
|
def ChiudiSerialeEsci():
|
|
global ser
|
|
|
|
if ser.isOpen():
|
|
ser.close()
|
|
|
|
#--------------------------------------------------------------
|
|
|
|
|
|
#--------------------------------------------------------------
|
|
# Seriale: Gestione Comunicazione lettura
|
|
# - lettura buffer seriale e pulizia caratteri non stampabili
|
|
# - ritorna '00' se non c'è un messaggio buono o il messaggio pulito (due bytes hex)
|
|
# - il messaggio ha il formato xx<ACK>i00 00<CR><LF>xxx CON IL COMANDO $i
|
|
# - il messaggio ha il formato xx<ACK>I00<CR><LF>xxx CON IL COMANDO $I
|
|
#--------------------------------------------------------------
|
|
def ReadSeriale():
|
|
|
|
# global to_serial
|
|
# global to_retry
|
|
# global errormsglen
|
|
global ser
|
|
global redIobMan
|
|
|
|
current = '00'
|
|
# 0x3F se volessimo tagliare ultimi 2 bit...
|
|
# 0xFF se se leggiamo tutti gli 8 bit...
|
|
sigMask = 0x3F
|
|
|
|
try:
|
|
|
|
# se è connesso...
|
|
if (ser.is_open):
|
|
sRaw = ser.read(12).decode()
|
|
if len(sRaw)> 4:
|
|
lAns = sRaw.split('\r')
|
|
rawVal = lAns[1]
|
|
adesso = datetime.now()
|
|
redIobMan.lastDataIn = adesso.strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
current = rawVal[0:2]
|
|
# current = "{0:0>2X}".format(int (current, 16) & 0X3F)
|
|
current = "{0:0>2X}".format(int (current, 16) & sigMask)
|
|
|
|
# richiesta dati ad IOB
|
|
RequestData()
|
|
# n_trials = 0
|
|
# errormsglen = 0
|
|
# b_ok = True # esco dal loop cd
|
|
else:
|
|
logPro.error('Serial closed, no data')
|
|
time.sleep(WAIT_RECONN)
|
|
RiAvviaSeriale()
|
|
time.sleep(WAIT_RECONN)
|
|
RequestData()
|
|
|
|
except Exception as exc:
|
|
logPro.error (f' err. 18 - Serial Port error... --EXIT -- ---> {str(exc)}')
|
|
RiAvviaSeriale()
|
|
# ChiudiSerialeEsci()
|
|
|
|
return current
|
|
#--------------------------------------------------------------
|
|
|
|
|
|
#--------------------------------------------------------------
|
|
# Richiesta dati ad IOB : scrittura su seriale
|
|
#--------------------------------------------------------------
|
|
def RequestData ():
|
|
|
|
global ser
|
|
global redIobMan
|
|
|
|
cmdCall = '$i\r\n'
|
|
serCall = cmdCall.encode()
|
|
|
|
try :
|
|
#$I per vers 1, $i per vers 2 scheda, prima con 6 seconda con 9 char risposta
|
|
|
|
ser.reset_input_buffer()
|
|
ser.write(serCall)
|
|
adesso = datetime.now()
|
|
redIobMan.lastDataOut = adesso.strftime("%Y-%m-%d %H:%M:%S")
|
|
time.sleep(SAMPLETIME)
|
|
|
|
except Exception as exc:
|
|
logPro.error (f'SERIAL: err. 19 - Write / flush \n\n{str(exc)}')
|
|
#--------------------------------------------------------------
|
|
|
|
#--------------------------------------------------------------
|
|
# Funzione di accodamento evento (valore corrente) con try-except
|
|
#--------------------------------------------------------------
|
|
def AccodaEV():
|
|
|
|
try:
|
|
dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3]
|
|
Coda.put(dtEve + '#' + value + '#' + cont)
|
|
|
|
except queue.Full:
|
|
logPro.error(f'Queue full | {dtEve} #{value}#{cont}')
|
|
except Exception as exc:
|
|
logPro.error(f'NETWORK:Errore http-no com rete-timeout | {url}\n\n{str(exc)}')
|
|
#--------------------------------------------------------------
|
|
|
|
#--------------------------------------------------------------
|
|
# Svuotamento coda eventi x invio dati al server
|
|
#--------------------------------------------------------------
|
|
def SvuotaCodaEV():
|
|
|
|
global onLine
|
|
global sending
|
|
global timer_busy
|
|
global NMAXSEND
|
|
|
|
#print('start timer')
|
|
if (timer_busy == False):
|
|
timer_busy = True
|
|
#print('start timer OK')
|
|
try:
|
|
if not Coda.empty():
|
|
#print('coda da svuotare!')
|
|
response = urlopen(URLALIVE)
|
|
answ = response.read().decode()
|
|
if answ == 'OK':
|
|
#print('OK alive')
|
|
response2 = urlopen(URLENABLED + idxMacchina)
|
|
answ2 = response2.read().decode()
|
|
if answ2 == 'OK':
|
|
# aggiorno stato ad online
|
|
if onLine == '0':
|
|
logPro.info('IOB ONLINE!')
|
|
#print('IOB ONLINE')
|
|
onLine = '1' # imposto comunque online
|
|
else:
|
|
if onLine == '1':
|
|
logPro.error('IOB offline')
|
|
#print('IOB offline')
|
|
onLine = '0'
|
|
else:
|
|
if onLine == '1':
|
|
logPro.error('Server offline')
|
|
#print('Server offline')
|
|
onLine = '0'
|
|
|
|
# ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...)
|
|
if onLine == '1':
|
|
if sending == '0':
|
|
#segnalo che sono in sending!
|
|
sending = '1'
|
|
# SAM 2016.12.23: modifica x invio FINO A nMaxSend ELEMENTI ad ogni ciclo di svuotamento
|
|
i = NMAXSEND
|
|
|
|
while i >= 0:
|
|
if not Coda.empty():
|
|
|
|
# formatto dataOra corrente
|
|
dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3]
|
|
#prendo primo elemento dalla coda
|
|
resp = Coda.get()
|
|
# recupero valori da elemento coda!
|
|
dtEve = resp.split('#')[0]
|
|
value = resp.split('#')[1]
|
|
cnt = resp.split('#')[2]
|
|
url = URLBASE + idxMacchina + URLADV1 + value
|
|
url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt
|
|
# CHIAMO URL
|
|
response3 = urlopen (url)
|
|
answ3 = response3.read().decode()
|
|
print(url)
|
|
# log valore inviato!
|
|
logSnd.info(value + ' ['+ cnt +']' + ' R:' + answ3)
|
|
#print('Valore smaltito dalla coda')
|
|
# tolgo 1 al contatore
|
|
i -= 1
|
|
# completato invio, riporto sending a zero!
|
|
sending = '0'
|
|
else:
|
|
logPro.info('WAIT active send to complete')
|
|
else:
|
|
pass
|
|
else:
|
|
pass
|
|
except Exception as exc:
|
|
if onLine == '1':
|
|
logPro.error(f'Server Non raggiungibile | Eccezione in invio dati:{str(exc)}')
|
|
#print('Non raggiungibile')'
|
|
else:
|
|
logPro.err(f'Eccezione in invio dati:{str(exc)}')
|
|
onLine = '0'
|
|
|
|
# in ogni caso
|
|
timer_busy = False
|
|
#print('end timer ok')
|
|
#print('end timer')'
|
|
#---------------------------------------------------------------
|
|
|
|
|
|
#---------------------------------------------------------------
|
|
# Gestione contatore round robin
|
|
#---------------------------------------------------------------
|
|
def CounterDoIncr():
|
|
|
|
try:
|
|
global cont
|
|
ctr = int(cont)
|
|
ctr +=1
|
|
ctr = ctr % 10000 # round robin 10000 eventi x track
|
|
cont = str(ctr)
|
|
except Exception as exc:
|
|
logPro.error('errore incremento contatore')
|
|
logPro.error(str(exc))
|
|
#---------------------------------------------------------------
|
|
|
|
|
|
#---------------------------------------------------------------
|
|
# Gestione avvio porta seriale
|
|
#---------------------------------------------------------------
|
|
def AvviaSeriale():
|
|
|
|
global ser
|
|
|
|
try:
|
|
ser = serial.Serial(
|
|
port = comm_port,
|
|
baudrate = 9600,
|
|
parity = serial.PARITY_NONE,
|
|
stopbits = serial.STOPBITS_ONE,
|
|
bytesize = serial.EIGHTBITS,
|
|
timeout = 1
|
|
)
|
|
|
|
except serial.serialutil.SerialException as exc :
|
|
sys.stdout.write (f'\n{PROGRAM_NAME} | err 11 - opening serial\n\n{str(exc)}\n\n')
|
|
RiAvviaSeriale()
|
|
# ChiudiSerialeEsci()
|
|
|
|
logPro.info(f'\n\n{PROGRAM_NAME} - init ok \n\n')
|
|
#---------------------------------------------------------------
|
|
|
|
|
|
#---------------------------------------------------------------
|
|
# Ri-avvia porta seriale
|
|
#---------------------------------------------------------------
|
|
def RiAvviaSeriale():
|
|
|
|
global ser
|
|
|
|
try:
|
|
if ser.isOpen():
|
|
ser.close()
|
|
time.sleep(WAIT_RECONN)
|
|
|
|
ser = serial.Serial(
|
|
port = comm_port,
|
|
baudrate = 9600,
|
|
parity = serial.PARITY_NONE,
|
|
stopbits = serial.STOPBITS_ONE,
|
|
bytesize = serial.EIGHTBITS,
|
|
timeout = 1
|
|
)
|
|
|
|
except serial.serialutil.SerialException as exc :
|
|
sys.stdout.write (f'\n{PROGRAM_NAME} | err 12 - reopening serial\n\n{str(exc)}\n\n')
|
|
time.sleep(WAIT_RECONN)
|
|
RiAvviaSeriale()
|
|
#---------------------------------------------------------------
|
|
|
|
|
|
#---------------------------------------------------------------
|
|
# funzione WatchDog verso REDIS
|
|
#---------------------------------------------------------------
|
|
def SendWatchDog():
|
|
# invio su redis stato
|
|
adesso = datetime.now()
|
|
redIobMan.lastUpdate = adesso.strftime("%Y-%m-%d %H:%M:%S")
|
|
# verificare sia DAVVERO online verso server...
|
|
redIobMan.online = (onLine == '1')
|
|
rawVal = redIobMan.toJSON()
|
|
redSrv0.set(f'IOB-WIN-PSER:IOB:{IOB_NAME}', rawVal)
|
|
logPro.debug('Invio a REDIS WatchDog')
|
|
#---------------------------------------------------------------
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
# Setup
|
|
#----------------------------------------------------------------------
|
|
try:
|
|
print('----------------------------')
|
|
print('Setup')
|
|
print('----------------------------')
|
|
# inizio con parse dei parametri... se li ho sono in esecuzione interattiva, imposto BASE_PATH di conseguenza
|
|
if len(sys.argv) > 1:
|
|
IOB_NAME = sys.argv[1]
|
|
# calcolo PATH esecuzione x versione COMPILATA
|
|
exe = sys.executable
|
|
BASE_PATH = os.path.dirname(exe) + '\\'
|
|
else:
|
|
# calcolo PATH esecuzione x versione INTERPRETATA
|
|
BASE_PATH = os.path.dirname(__file__) + '\\'
|
|
|
|
print(f'Iob name: {IOB_NAME}')
|
|
# fix config
|
|
IOB_CONF = f'{IOB_NAME}.cfg'
|
|
print(f'BasePath: {BASE_PATH}')
|
|
BASE_LOG_PATH = BASE_PATH + 'logs\\'
|
|
print(f'LogPath: {BASE_LOG_PATH}')
|
|
|
|
config = configparser.ConfigParser()
|
|
confFilePath = os.path.join(BASE_PATH, 'CONF', IOB_CONF)
|
|
config.read(confFilePath)
|
|
|
|
# lettura parametri di base
|
|
LOGFILE = config.get('log','LOGFILE')
|
|
LOGLEVEL = config.getint('log','LOGLEVEL')
|
|
MAX_LOG_SIZE = config.getint('log','MAX_LOG_SIZE')
|
|
NUM_LOG_RETAIN = config.getint('log','NUM_LOG_RETAIN')
|
|
REDIS_HOST = config.get('redis','REDIS_HOST')
|
|
REDIS_PORT = config.getint('redis','REDIS_PORT')
|
|
REDIS_DB = config.getint('redis','REDIS_DB')
|
|
# fix cartella log...
|
|
BASE_LOG_PATH = os.path.join(BASE_PATH, 'logs', IOB_NAME)
|
|
logPath = os.path.join(BASE_LOG_PATH, LOGFILE)
|
|
logDirOk=os.path.exists(logPath)
|
|
# controllo cartella log o la creo
|
|
if(not logDirOk):
|
|
os.makedirs(os.path.dirname(logPath), exist_ok=True)
|
|
print(f'Config file: {confFilePath}')
|
|
# setup redis...
|
|
redSrv0 = redis.Redis(
|
|
host=REDIS_HOST,
|
|
port=REDIS_PORT,
|
|
db=REDIS_DB)
|
|
print(f'REDIS_HOST: {REDIS_HOST}')
|
|
print(f'REDIS_PORT: {REDIS_PORT}')
|
|
print(f'REDIS_DB: {REDIS_DB}')
|
|
# setup oggetto comunicazione redis...
|
|
redIobMan = IobWinStatus(IOB_NAME,'IOB-WIN-PSER')
|
|
|
|
# continuo setup altri parametri specifici IOB
|
|
SAMPLETIME = config.getfloat ('time','SAMPLETIME')
|
|
TIMEOUTSHORT = config.getfloat ('time','TIMEOUTSHORT')
|
|
TIMEOUTLONG = config.getfloat ('time','TIMEOUTLONG')
|
|
SENDURLTIME = config.getfloat ('time','SENDURLTIME')
|
|
WAIT_RECONN = config.getint ('time','WAIT_RECONN')
|
|
NMAXSEND = config.getint ('time','NMAXSEND')
|
|
idxMacchina = config.get ('id','idxMacchina')
|
|
comm_port = config.get ('comm','port')
|
|
URLBASE = config.get ('web','URLBASE')
|
|
URLENABLED = config.get('web', 'URLENABLED')
|
|
URLALIVE = config.get ('web', 'URLALIVE')
|
|
URLADV1 = config.get ('web','URLADV1')
|
|
# setup parametri speciali (blink)
|
|
B_blinking[0] = config.getint ('blink','bit0')
|
|
B_blinking[1] = config.getint ('blink','bit1')
|
|
B_blinking[2] = config.getint ('blink','bit2')
|
|
B_blinking[3] = config.getint ('blink','bit3')
|
|
B_blinking[4] = config.getint ('blink','bit4')
|
|
B_blinking[5] = config.getint ('blink','bit5')
|
|
B_blinking[6] = config.getint ('blink','bit6')
|
|
B_blinking[7] = config.getint ('blink','bit7')
|
|
MAX_COUNTER_BLINK = config.getint ('blink','MAX_COUNTER_BLINK')
|
|
# setup gestione inversione segnali ingresso
|
|
B_inverting[0] = config.getint ('invert','bit0')
|
|
B_inverting[1] = config.getint ('invert','bit1')
|
|
B_inverting[2] = config.getint ('invert','bit2')
|
|
B_inverting[3] = config.getint ('invert','bit3')
|
|
B_inverting[4] = config.getint ('invert','bit4')
|
|
B_inverting[5] = config.getint ('invert','bit5')
|
|
B_inverting[6] = config.getint ('invert','bit6')
|
|
B_inverting[7] = config.getint ('invert','bit7')
|
|
# setup gestione filtraggio segnali brevi (spike)
|
|
B_filter[0] = config.getint ('filter','bit0')
|
|
B_filter[1] = config.getint ('filter','bit1')
|
|
B_filter[2] = config.getint ('filter','bit2')
|
|
B_filter[3] = config.getint ('filter','bit3')
|
|
B_filter[4] = config.getint ('filter','bit4')
|
|
B_filter[5] = config.getint ('filter','bit5')
|
|
B_filter[6] = config.getint ('filter','bit6')
|
|
B_filter[7] = config.getint ('filter','bit7')
|
|
MAX_COUNTER_FILTER = config.getint ('filter','MAX_COUNTER_FILTER')
|
|
|
|
except Exception as exc :
|
|
print (f'{PROGRAM_NAME} - Exception - Error 4 in config file \n\n{str(exc)}\n-- EXIT --')
|
|
#sys.exit(1)
|
|
#--------------------------------------------
|
|
|
|
|
|
#--------------------------------------------
|
|
# Oggetto Logger
|
|
#--------------------------------------------
|
|
try:
|
|
logPath = os.path.join(BASE_LOG_PATH, LOGFILE)
|
|
cLogLevel = logging.DEBUG
|
|
|
|
if LOGLEVEL > 10:
|
|
cLogLevel = logging.WARN
|
|
elif LOGLEVEL > 5:
|
|
cLogLevel = logging.INFO
|
|
|
|
logging.basicConfig(level=cLogLevel)
|
|
|
|
# add a rotating handler
|
|
handler = RotatingFileHandler(logPath,
|
|
maxBytes=MAX_LOG_SIZE,
|
|
backupCount=NUM_LOG_RETAIN
|
|
)
|
|
|
|
# Define a custom formatter
|
|
formatter = logging.Formatter('%(asctime)s %(name)-8s %(levelname)-8s %(message)s')
|
|
handler.setFormatter(formatter)
|
|
|
|
# aggiungo logger specifici (program,queue,send...)
|
|
logQue = logging.getLogger('queue')
|
|
logSnd = logging.getLogger('sendUrl')
|
|
logPro = logging.getLogger('program')
|
|
logQue.addHandler(handler)
|
|
logSnd.addHandler(handler)
|
|
logPro.addHandler(handler)
|
|
|
|
print('Setup completed')
|
|
print('----------------------------')
|
|
|
|
except Exception as exc:
|
|
# manda mail o simili - FARE!!!
|
|
print (f'LOG: Impossibile creare file log con nome {LOGFILE}')
|
|
#--------------------------------------------
|
|
|
|
|
|
#------------------------------------------------------------------------------------------------------------------------------
|
|
# MAIN
|
|
#------------------------------------------------------------------------------------------------------------------------------
|
|
print(f'\n\n {PROGRAM_NAME} \n\n')
|
|
logPro.info("Start " + PROGRAM_NAME)
|
|
|
|
logPro.info(' Iob name = %s' % (IOB_NAME))
|
|
logPro.info(' BasePath = %s' % (BASE_PATH))
|
|
logPro.info(' LogPath = %s' % (BASE_LOG_PATH))
|
|
logPro.info(' comm_port = %s' % (comm_port))
|
|
logPro.info(' idxMacchina = %s' % (idxMacchina))
|
|
logPro.info(' SAMPLETIME = %4.2f' % (SAMPLETIME))
|
|
logPro.info(' TIMEOUTSHORT = %4.2f' % (TIMEOUTSHORT))
|
|
logPro.info(' TIMEOUTLONG = %4.2f' % (TIMEOUTLONG))
|
|
logPro.info(' SENDURLTIME = %4.2f' % (SENDURLTIME))
|
|
logPro.info(' URLBASE = %s' % (URLBASE))
|
|
logPro.info(' URLADV1 = %s' % (URLADV1))
|
|
logPro.info(' LOGFILE = %s' % (LOGFILE))
|
|
logPro.info(' LOGLEVEL = %s' % (LOGLEVEL))
|
|
|
|
to_short = TIMEOUTSHORT
|
|
to_long = TIMEOUTLONG
|
|
|
|
#--------------------------------------------------------------
|
|
# apertura seriale come prima cosa
|
|
AvviaSeriale()
|
|
#--------------------------------------------------------------
|
|
|
|
#--------------------------------------------------------------
|
|
# Qui c'è avvio thread secondari: "svuotaCoda" e check REDIS x invio watchdog
|
|
# svuota coda è molto frequente, tipicamente 0.15 sec
|
|
do_every (SENDURLTIME, SvuotaCodaEV)
|
|
# watchdog redis lo è molto meno, tipicamente ogni 6 sec
|
|
do_every (SENDURLTIME * 40, SendWatchDog )
|
|
#--------------------------------------------------------------
|
|
|
|
#---------------------------------------------------------------
|
|
# inizio con richiesta dati ad IOB
|
|
old = ''
|
|
try:
|
|
RequestData()
|
|
except Exception as exc:
|
|
logPro.error('err 20 - try RequestData -- EXIT --')
|
|
logPro.error(str(exc))
|
|
RiAvviaSeriale()
|
|
# ChiudiSerialeEsci()
|
|
|
|
#print('Avvio ciclo"
|
|
logPro.info('Avvio loop principale')
|
|
|
|
# ciclo forever and ever
|
|
while True :
|
|
|
|
try:
|
|
time.sleep (SAMPLETIME)
|
|
except Exception as e:
|
|
logPro.error('Err 21 -First_SLEEP: errore attesa sampletime')
|
|
logPro.error(str(e))
|
|
|
|
# calcolo tempo trascorso
|
|
adesso = time.time()
|
|
delta = adesso - last_exe
|
|
last_exe = adesso
|
|
|
|
value = ''
|
|
# lettura dati da IOB
|
|
try:
|
|
value = ReadSeriale()
|
|
except Exception as e:
|
|
logPro.error('err 22 - main loop read serial -- EXIT --')
|
|
logPro.error(str(e))
|
|
ChiudiSerialeEsci()
|
|
|
|
if (value != '') :
|
|
if value != old :
|
|
#loggo e invio dati
|
|
try:
|
|
logQue.info(value + ' ['+ cont +']')
|
|
AccodaEV()
|
|
CounterDoIncr()
|
|
except Exception as e:
|
|
logPro.error('err 23 - URLBROWSER: errore registrazione valore e AccodaEV')
|
|
logPro.error(str(e))
|
|
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 - delta
|
|
to_short = to_short - SAMPLETIME
|
|
if to_short <= 0:
|
|
#loggo e invio dati
|
|
try:
|
|
logQue.info('>' + value + ' ['+ cont +']')
|
|
AccodaEV()
|
|
CounterDoIncr()
|
|
except Exception as exc:
|
|
logPro.error('err 24 - URLBROWSER: errore registrazione valore e AccodaEV TO_short')
|
|
logPro.error(str(exc))
|
|
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 - delta
|
|
to_long = to_long - SAMPLETIME
|
|
if to_long <= 0:
|
|
#loggo e invio dati
|
|
try:
|
|
logQue.info('>>' + value + ' ['+ cont +']')
|
|
AccodaEV()
|
|
CounterDoIncr()
|
|
except Exception as exc:
|
|
logPro.error('err 25 - URLBROWSER: errore registrazione valore e AccodaEV TO_long')
|
|
logPro.error(str(exc))
|
|
pass
|
|
to_long = TIMEOUTLONG
|
|
|
|
#------------------------------------------------------------------------------------------------------------------------------
|