diff --git a/IOB-PI/IOB.cfg b/IOB-PI/IOB.cfg new file mode 100644 index 0000000..9cfc458 --- /dev/null +++ b/IOB-PI/IOB.cfg @@ -0,0 +1,72 @@ +[id] +idxMacchina = 0001 +#idxMacchina = SIMUL_01 +#numParams=8 +numParams=12 + +[web] +URLBASE = http://10.74.82.218/MP/RIOC/api/IOB/input/ +URLALIVE = http://10.74.82.218/MP/RIOC/api/IOB +URLENABLED = http://10.74.82.218/MP/RIOC/api/IOB/enabled/ +URLADV1 = ?valore= +URLREBO = http://10.74.82.218/MP/IOC/api/IOB/sendReboot/ +URLINFO = http://10.74.82.218/MP/RIOC/api/IOB/setM2IOB/ + +[time] +SAMPLETIME = 0.05 +TIMEOUTSHORT = 0.50 +TIMEOUTLONG = 80 +SENDURLTIME = 0.15 +NMAXSEND = 5 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 + +[blink] +MAX_COUNTER_BLINK = 30 +bit0 = 0 +bit1 = 0 +bit2 = 0 +bit3 = 0 +bit4 = 0 +bit5 = 0 +bit6 = 0 +bit7 = 0 +bit8 = 0 +bit9 = 0 +bit10 = 0 +bit11 = 0 + +[invert] +bit0 = 0 +bit1 = 0 +bit2 = 0 +bit3 = 0 +bit4 = 0 +bit5 = 0 +bit6 = 0 +bit7 = 0 +bit8 = 0 +bit9 = 0 +bit10 = 0 +bit11 = 0 + +[filter] +MAX_COUNTER_FILTER = 8 +bit0 = 0 +bit1 = 0 +bit2 = 0 +bit3 = 0 +bit4 = 0 +bit5 = 0 +bit6 = 0 +bit7 = 0 +bit8 = 0 +bit9 = 0 +bit10 = 0 +bit11 = 0 diff --git a/IOB-PI/README.md b/IOB-PI/README.md index d8bf2af..4be98b8 100644 --- a/IOB-PI/README.md +++ b/IOB-PI/README.md @@ -8,20 +8,87 @@ Se il minion è taggato come iop-pi bast dare state apply, poiché dallo stato t * iob-pi.sls * iob-setup.sls +altrimenti meglio dare +* iob-pi-install +* iob-pi-upgrade -## approfondimenti +va poi controllato il numero di inputs e va specificato all'inizio del file IOB.cfg a seconda che abbia 8 o 12 inputs + + + #numParams=8 + + numParams=12 + + + +## Approfondimenti Valutato python-rq x gestione code con redis tramite esecuzione workers python gestiti in autonomia: + https://python-rq.org/ + https://python-rq.org/docs/workers/ + Testato ma al momento non è rispondente ai requisiti del programma per cui si rischia un blocco inf ase di invio se server non OK, per ora implementata copia "manuale" della coda verso redis per salvaguardare dati accumulati (vers 2.6.x) + ## MD5 zip## creazione MD5: da powershell Get-FileHash .\Mapo.zip -Algorithm MD5 - \ No newline at end of file + + + +## ReadParallela IOB-PI + +### Panoramica +`readParallela.py` è uno script di acquisizione dati ad alta frequenza progettato per Raspberry Pi. Interfaccia una scheda GPIO personalizzata per leggere 12 ingressi digitali paralleli, applica vari filtri di elaborazione del segnale e mette in coda gli eventi per la trasmissione asincrona a un server remoto tramite Redis e HTTP. + +### Funzionalità Principali + +#### 1. Acquisizione e Elaborazione Segnali +Lo script interroga 12 pin GPIO a un intervallo configurabile (`SAMPLETIME`). Per ogni ingresso, applica una pipeline di elaborazione a tre stadi: +* **Inversione:** Inverte la logica del segnale se configurata per un bit specifico. +* **Filtraggio Segnali Brevi (Debounce):** Filtra i picchi elettrici o il rumore richiedendo che il segnale rimanga stabile per un numero specifico di cicli (`MAX_COUNTER_FILTER`). +* **Gestione Blinking:** Rileva e gestisce segnali "blinking", permettendo il rilevamento di eventi basati su timing specifici. + +#### 2. Impacchettamento Dati +Una volta elaborati, i 12 bit vengono aggregati in un unico valore intero e convertiti in una stringa Esadecimale. + +#### 3. Code e Trasmissione Eventi +Per garantire che la lettura ad alta velocità non sia interrotta dalla latenza di rete: +* **Coda Redis:** Le variazioni rilevate (e gli eventi di timeout) vengono datate e inserite in una lista Redis (`IOB`). +* **Invio Asincrono:** Un thread dedicato in background (`svuotaCoda`) estrae periodicamente gli elementi dalla coda Redis e esegue richieste HTTP a un server centrale. +* **Affidabilità:** Lo script implementa un meccanismo di "retry" e monitora la disponibilità del server (`URLALIVE`) per gestire i periodi offline. + +#### 4. Gestione Timeout +Lo script monitora due tipi di timeout: +* **Timeout Breve:** Assicura che lo stato di un segnale venga registrato anche se cambia rapidamente. +* **Timeout Lungo:** Fornisce un sistema di fallback per garantire la coerenza dello stato su periodi più lunghi. + +### Dettagli di Implementazione (Versione Refactored) +Lo script è stato modernizzato con i seguenti miglioramenti: +* **Design Orientato agli Oggetti:** La logica è incapsulata all'interno della classe `ReadParallelaIOB`, eliminando la dipendenza da variabili globali pericolose. +* **Operazioni Bitwise Efficienti:** Sostituzione dei controlli manuali `if` con operatori bitwise per una ricostruzione dei bit più veloce e ottimizzazione dell'accesso agli attributi nelle loop critiche. +* **Networking Moderno:** Sostituzione di `urllib` con la libreria `requests` per una comunicazione HTTP più robusta e leggibile. +* **Configurazione Ottimizzata:** Utilizzo di cicli per caricare le impostazioni per singolo bit dal file di configurazione. + +### Configurazione +Le impostazioni sono gestite tramite `IOB.cfg`, tra cui: +* `[time]`: Frequenze di campionamento e timeout. +* `[id]`: Identificativo macchina. +* `[web]`: URL per la trasmissione dati e controlli di connettività. +* `[blink]`, `[invert]`, `[filter]`: Configurazione per singolo bit per l'elaborazione dei segnali. +* `[log]`: Livello di logging e percorsi dei file. + +### Dipendenze +* `RPi.GPIO`: Per l'interfacciamento hardware. +* `redis`: Per la gestione della coda locale. +* `requests`: Per la comunicazione web. +* `configparser`: Per la gestione della configurazione. + + diff --git a/IOB-PI/README.pdf b/IOB-PI/README.pdf index 1e9593a..0de3a55 100644 Binary files a/IOB-PI/README.pdf and b/IOB-PI/README.pdf differ diff --git a/IOB-PI/readParallela.py b/IOB-PI/readParallela.py index 5ad263e..1b48912 100644 --- a/IOB-PI/readParallela.py +++ b/IOB-PI/readParallela.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -# readParallela v. 2.6.1 12 Ingressi +# readParallela v. 3.1.2 12 Ingressi # - single instance timer # - invio multiplo x send eventi accodati # - gestione segnali BLINKING @@ -16,773 +16,420 @@ # - (2.5.3) Fix gestione stringhe e print x python 3.11 in debian 12 / raspberry OS 2025 # - (2.6.0) Aggiunto gestione Redis x code salvate ogni minuto e ricaricate all'avvio 2025.04.17 # - (2.6.1) Cleanup generale vecchia queue post test vari +# - (2.6.2) Fix in global di to_retry in send_coda per evitare problemi +# - (3.0.0) Prima versione code-assisted: riformulazione e ottimizzazione globale programma +# - (3.1.2) Ottimizzazione gestione letture GPIO (sempre code-assisted) + import time import sys - - -from datetime import datetime - -import urllib -import urllib.request -import configparser -import os, sys - +import os import logging import logging.handlers import threading +import configparser +from datetime import datetime, timezone +from array import array + import redis +import requests +import urllib3 -from array import * - -#-------------------------------------------------------------- -# COSTANTI -MSGLEN = 9 -TIMEOUTSERIALE = 10 -MAXRETRY = 10 - -# numero campioni filtraggio segnale ballerino -MAX_COUNTER_BLINK = 10 - -PROGRAM_NAME ="ReadPar IOB-pi v.2.6.1" - -# DA FILE CONF -idxMacchina = "1001" -SAMPLETIME = 0.1 -TIMEOUTSHORT = (SAMPLETIME*20) -TIMEOUTLONG = (SAMPLETIME*600) -SENDURLTIME = 0.08 -NMAXSEND = 5 # numero massimo di invii per singolo ciclo di svuotamento - -# VAR -to_enable = False -to_short = TIMEOUTSHORT -to_long = TIMEOUTLONG -to_serial = TIMEOUTSERIALE -to_retry = MAXRETRY -errormsglen = 0 - -# VAR - -out_0 = 24 -out_1 = 26 - -in_0 = 11 -in_1 = 12 -in_2 = 13 -in_3 = 15 -in_4 = 16 -in_5 = 18 -in_6 = 22 -in_7 = 7 -in_8 = 29 -in_9 = 31 -in_10 = 32 -in_11 = 36 - -# contatore: serve x match tra accoda 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 - -# -# array per ingressi filtrati -i_counters = array ( 'i',[0,0,0,0,0,0,0,0,0,0,0,0]) -B_blinking = array ( 'B',[0,0,0,0,0,0,0,0,0,0,0,0]) -B_previous = array ( 'B',[0,0,0,0,0,0,0,0,0,0,0,0]) -B_input = array ( 'B',[0,0,0,0,0,0,0,0,0,0,0,0]) -B_output = array ( 'B',[0,0,0,0,0,0,0,0,0,0,0,0]) - -B_inverting = array ( 'B',[0,0,0,0,0,0,0,0,0,0,0,0]) - -B_filter = array ( 'B',[0,0,0,0,0,0,0,0,0,0,0,0]) -B_filter_prev = array ( 'B',[0,0,0,0,0,0,0,0,0,0,0,0]) -B_temp = array ( 'B',[0,0,0,0,0,0,0,0,0,0,0,0]) -i_filter_counters = array ( 'i',[0,0,0,0,0,0,0,0,0,0,0,0]) - -#-------------------------------------------------------------- -# Gestione coda (condivisa) su Redis x registrazione eventi ed invio URL -CodaR = redis.Redis(host='localhost', port=6379, db=0, password='24068Seriate') -queue_name = 'IOB' - -#----------------------------------- -# Gestione code REDIS (sost. coda in ram) - -# Function to add an item to the queue (enqueue) -def rqEnqueue(item): - CodaR.rpush(queue_name, item) - #logQue.info(f"Enqueued: {item}") - -# Function to remove an item from the queue (dequeue) -def rqDequeue(): - item = CodaR.lpop(queue_name) - if item: - #logQue.info(f"Dequeued: {item.decode('utf-8')}") - return item.decode('utf-8') - else: - logQue.info("Queue is empty, nothing to retrieve!") - -# Function to count queue actual lenght in Redis -def rqLen(): - cLen = CodaR.llen(queue_name) - if cLen: - #logQue.info(f"Queue len: {cLen}") - return cLen - else: - #logQue.info("Queue is empty") - return 0 - -#--------------------------------------------------------------- -# lettura parallela -# ritorna il byte letto pulito ( due char hex ) - -def readParallelaFiltrata(): - - global in_0 - global in_1 - global in_2 - global in_3 - global in_4 - global in_5 - global in_6 - global in_7 - - global in_8 - global in_9 - global in_10 - global in_11 - - - global GPIO - - current = '' - - - try: - - if GPIO.input(in_0): - B_input[0] = 0 - else: - B_input[0] = 1 - - if GPIO.input(in_1): - B_input[1] = 0 - else: - B_input[1] = 1 - - if GPIO.input(in_2): - B_input[2] = 0 - else: - B_input[2] = 1 - - if GPIO.input(in_3): - B_input[3] = 0 - else: - B_input[3] = 1 - - if GPIO.input(in_4): - B_input[4] = 0 - else: - B_input[4] = 1 - - if GPIO.input(in_5): - B_input[5] = 0 - else: - B_input[5] = 1 - - if GPIO.input(in_6): - B_input[6] = 0 - else: - B_input[6] = 1 - - if GPIO.input(in_7): - B_input[7] = 0 - else: - B_input[7] = 1 - - if GPIO.input(in_8): - B_input[8] = 0 - else: - B_input[8] = 1 - - if GPIO.input(in_9): - B_input[9] = 0 - else: - B_input[9] = 1 - - if GPIO.input(in_10): - B_input[10] = 0 - else: - B_input[10] = 1 - - if GPIO.input(in_11): - B_input[11] = 0 - else: - B_input[11] = 1 - - - - #ciclo per ogni segnale - for i in range(12) : - #print (i) - - # v2.1 gestione inversione bit ingresso - - if ( B_inverting[i] == 1 ) : - if ( B_input[i] == 0 ) : - B_input[i] = 1 - else : - B_input[i] = 0 - - # v2.2 gestione filtro segnali brevi - - if ( B_filter[i] == 1 ) : - - # fronte 0 -> 1 - if ( B_input[i] == 1 ) and ( B_filter_prev [i] == 0 ) : - if ( i_filter_counters[i] == 0 ) : - # vero fronte 0 -> 1 - i_filter_counters[i] = MAX_COUNTER_FILTER - B_temp[i] = 0 # tengo l' ingresso a 0 - #logPro.info("START spike 0->1 on bit " + str(i) ) - else : - # fine disturbo breve di uno stato 1 - i_filter_counters[i] = 0 - B_temp[i] = 1 # tengo l' ingresso a 1 - logPro.info("END spike 0->1 on bit " + str(i) ) - - # stabile 1 -> 1 - if ( B_input[i] == 1 ) and ( B_filter_prev [i] == 1 ) : - if ( i_filter_counters[i] == 0 ) : - # segnale stabile a 1 - B_temp[i] = 1 # tengo l' ingresso a 1 - else : - # poco dopo il fronte - i_filter_counters[i] = i_filter_counters[i] - 1 - B_temp[i] = 0 # tengo l' ingresso a 0 - - # fronte 1 -> 0 - if ( B_input[i] == 0 ) and ( B_filter_prev [i] == 1 ) : - if ( i_filter_counters[i] == 0 ) : - # vero fronte 1 -> 0 - i_filter_counters[i] = MAX_COUNTER_FILTER - B_temp[i] = 1 # tengo l' ingresso a 1 - #logPro.info("START spike 1->0 on bit " + str(i) ) - else : - # fine disturbo breve di uno stato 0 - i_filter_counters[i] = 0 - B_temp[i] = 0 # tengo l' ingresso a 0 - logPro.info("END spike 1->0 on bit " + str(i) ) - - # stabile 0 -> 0 - if ( B_input[i] == 0 ) and ( B_filter_prev [i] == 0 ) : - if ( i_filter_counters[i] == 0 ) : - # segnale stabile a 0 - B_temp[i] = 0 # tengo l' ingresso a 0 - else : - # poco dopo il fronte - i_filter_counters[i] = i_filter_counters[i] - 1 - B_temp[i] = 1 # tengo l' ingresso a 1 - - B_filter_prev [i] = B_input[i] - B_input[i] = B_temp[i] - - # fine gestione filtro segnali brevi - - - # se non blinking, copia ingresso - if ( B_blinking[i] == 0 ) : - B_output[i] = B_input[i] - else: - # gestione segnale blinking - # se fronte del segnale - if ( B_previous[i] != B_input[i] ) : - B_previous[i] = B_input[i] - # se fronte di salita - if ( B_input[i] == 1 ) : - # subito uscita = 1 - B_output[i] = 1 - i_counters[i] = MAX_COUNTER_BLINK - #else : - # # loggo che ho rilevato un blink... - # logPro.info("Blink down on bit " + str(i)) - else: - # no , segnale eguale a prima - # se input a 0 - if ( B_input[i] == 0 ) : - # E CONTEGGIO IN CORSO - if ( i_counters[i] > 0 ) : - i_counters[i] = i_counters[i] -1 - if ( i_counters[i] == 0 ) : - B_output[i] = 0 - logPro.info("END Blink on bit " + str(i) ) - - #Rimettiamo insieme i bit - new_value = 0 - - if ( B_output[0] == 1 ) : - new_value = new_value + 1 - if ( B_output[1] == 1 ) : - new_value = new_value + 2 - if ( B_output[2] == 1 ) : - new_value = new_value + 4 - if ( B_output[3] == 1 ) : - new_value = new_value + 8 - if ( B_output[4] == 1 ) : - new_value = new_value + 16 - if ( B_output[5] == 1 ) : - new_value = new_value + 32 - if ( B_output[6] == 1 ) : - new_value = new_value + 64 - if ( B_output[7] == 1 ) : - new_value = new_value + 128 - if ( B_output[8] == 1 ) : - new_value = new_value + 256 - if ( B_output[9] == 1 ) : - new_value = new_value + 512 - if ( B_output[10] == 1 ) : - new_value = new_value + 1024 - if ( B_output[11] == 1 ) : - new_value = new_value + 2048 - - current = hex( new_value ).replace ( "0x" , "" ).upper() - - except Exception as e: - print ("Errore in readParallelaFiltrata \n\n") - print (str(e)) - pass - - return current - -#--------------------------------------------------------------- -#Funzione di scrittura su coda con try-except - -def accoda(): - - try: - dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] - rqEnqueue(dtEve + '#' + value + '#' + cont) - except Exception as e: - logPro.error( "QUEUE:Errore coda \n\n" ) - logPro.error(str(e)) - -#-------------------------------------------------------------- -# svuotaCoda x invio dati al server -def svuotaCoda(): - - global onLine - global sending - global timer_busy - global NMAXSEND - - #logPro.info ("start timer ") - if ( timer_busy == False ): - timer_busy = True - #logPro.info ("start timer ok ") - - try: - if not rqLen() == 0: - #logPro.info ("coda da svuotare!") - response = urllib.request.urlopen(URLALIVE) - answ = response.read().decode('utf-8') - #logPro.info(answ) - if answ == 'OK': - #logPro.info ("OK alive") - response2 = urllib.request.urlopen(URLENABLED + idxMacchina) - answ2 = response2.read().decode('utf-8') - if answ2 == 'OK': - # aggiorno stato ad online - if onLine == '0': - logPro.info("IOB ONLINE!") - - onLine = '1' # imposto comunque online - else: - if onLine == '1': - logPro.error("IOB offline") - - onLine = '0' - else: - if onLine == '1': - logPro.error("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 rqLen() == 0: - - # formatto dataOra corrente - dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] - - #prendo primo elemento dalla coda - resp = rqDequeue() - - # 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 = urllib.request.urlopen ( url ) - answ3 = response3.read().decode('utf-8') - #logSnd.info(url) - - # log valore inviato! - logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) - #logSnd.info ("Valore smaltito dalla coda") - - # tolgo 1 al contatore - i -= 1 - - # completato invio, riporto sending a zero! - sending = '0' - else: - if to_retry > 0: - to_retry -= 1 - logPro.info("WAIT active send to complete") - else: - sending = '0' - to_retry = MAXRETRY - logPro.info("END WAIT, reset to_retry var") - - else: - pass - - else: - pass - - except Exception as e: - if onLine == '1': - logPro.error("Server Non raggiungibile") - logPro.error(str(e)) - - onLine = '0' - - # in ogni caso - - timer_busy = False - #print ("end timer ok") - - #print ("end timer ") - -#--------------------------------------------------------------- -# funzione 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 (); - -#--------------------------------------------------------------- -# gestione contatore -#--------------------------------------------------------------- -def contatore(): - - try: - global cont - ctr = int(cont) - ctr +=1 - ctr = ctr % 10000 # round robin 10000 eventi x track - cont = str(ctr) - except Exception as e: - print("errore incremento contatore \n\n") - print(str(e)) - -#--------------------------------------------------------------- -# avvia porta parallela -#--------------------------------------------------------------- -def avviaParallela(): - - global in_0 - global in_1 - global in_2 - global in_3 - global in_4 - global in_5 - global in_6 - global in_7 - global in_8 - global in_9 - global in_10 - global in_11 - - global GPIO - - try: - - GPIO.setmode(GPIO.BOARD) - - GPIO.setwarnings(False) - - #GPIO.setup(out_0, GPIO.OUT) # output 0 - #GPIO.setup(out_1, GPIO.OUT) # output 1 - - GPIO.setup(in_0, GPIO.IN) # input 0 - GPIO.setup(in_1, GPIO.IN) # input 1 - GPIO.setup(in_2, GPIO.IN) # input 2 - GPIO.setup(in_3, GPIO.IN) # input 3 - GPIO.setup(in_4, GPIO.IN) # input 4 - GPIO.setup(in_5, GPIO.IN) # input 5 - GPIO.setup(in_6, GPIO.IN) # input 6 - GPIO.setup(in_7, GPIO.IN) # input 7 - GPIO.setup(in_8, GPIO.IN) # input 8 - GPIO.setup(in_9, GPIO.IN) # input 9 - GPIO.setup(in_10, GPIO.IN) # input 10 - GPIO.setup(in_11, GPIO.IN) # input 11 - - except Exception as e: - print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") - print (str(e)) - sys.exit(1) - - - print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") - - -#--------------------------------------------------------------- -#--------------------------------------------------------------- -# MAIN - -try: - config = configparser.RawConfigParser() - config.read ( 'IOB.cfg' ) - - SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) - TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) - TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) - SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) - NMAXSEND = config.getint ( 'time' , 'NMAXSEND' ) - - idxMacchina = config.get ( 'id' , 'idxMacchina' ) - - - URLBASE = config.get ( 'web' , 'URLBASE' ) - URLENABLED = config.get('web' , 'URLENABLED') - URLALIVE = config.get ('web' , 'URLALIVE') - URLADV1 = config.get ( 'web' , 'URLADV1' ) - - LOGFILE = config.get ( 'log' , 'LOGFILE' ) - LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) - - 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' ) - B_blinking[8] = config.getint ( 'blink' , 'bit8' ) - B_blinking[9] = config.getint ( 'blink' , 'bit9' ) - B_blinking[10] = config.getint ( 'blink' , 'bit10' ) - B_blinking[11] = config.getint ( 'blink' , 'bit11' ) - - MAX_COUNTER_BLINK = config.getint ( 'blink' , 'MAX_COUNTER_BLINK' ) - - # cv 2.1 se bit = 1 allora inverto segnale in 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' ) - B_inverting[8] = config.getint ( 'invert' , 'bit8' ) - B_inverting[9] = config.getint ( 'invert' , 'bit9' ) - B_inverting[10] = config.getint ( 'invert' , 'bit10' ) - B_inverting[11] = config.getint ( 'invert' , 'bit11' ) - - # cv 2.2 se bit = 1 allora filtro segnali brevi ... - 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' ) - B_filter[8] = config.getint ( 'filter' , 'bit8' ) - B_filter[9] = config.getint ( 'filter' , 'bit9' ) - B_filter[10] = config.getint ( 'filter' , 'bit10' ) - B_filter[11] = config.getint ( 'filter' , 'bit11' ) - - MAX_COUNTER_FILTER = config.getint ( 'filter' , 'MAX_COUNTER_FILTER' ) - - -except Exception as e: - print ("\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg') - print (str(e)) - sys.exit(1) - -#-------------------------------------------- -# oggetto Logger -#-------------------------------------------- -try: - logging.basicConfig(level=logging.DEBUG, - format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', - datefmt='%Y-%m-%d %H:%M:%S', - filename=LOGFILE, - filemode='a' - ) - - # aggiungo 2 logger specifici x queue e send... - logQue = logging.getLogger('queue') - logSnd = logging.getLogger('sendUrl') - logPro = logging.getLogger('program') - -except Exception as e: - # manda mail o simili - FARE!!! - print ("LOG: Impossibile creare file log con nome") - print (LOGFILE) - print ("\n\n") - print (str(e)) -#-------------------------------------------- - - -print ("\n\n" + PROGRAM_NAME + "\n\n") - -global startstatus -startstatus = 1 - -if startstatus == 1: - logPro.info("Avvio Programma" + PROGRAM_NAME) - -## 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 - -logPro.info( "Start " + PROGRAM_NAME ) - - -# lettura file configurazione -print ( ' idxMacchina = %s' % ( idxMacchina ) ) -print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) -print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) -print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) -print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) -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 parallela +# Disable urllib3 debug logging to keep application logs clean +urllib3.disable_warnings() +logging.getLogger("urllib3").setLevel(logging.WARNING) +# Note: RPi.GPIO is imported inside the class or at runtime to prevent errors on non-Pi systems try: import RPi.GPIO as GPIO -except RuntimeError: - print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") -except Exception as e: - print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") - print (str(e)) - sys.exit(1) +except ImportError: + GPIO = None +class ReadParallelaIOB: + def __init__(self, config_path='IOB.cfg'): + self.PROGRAM_NAME = "ReadPar IOB-pi v.3.1.2 (2026)" + self.MAXRETRY = 10 + self.MAX_COUNTER_BLINK = 10 + + # Configuration and State + self.config = configparser + + # Hardware Pin Maps + self._PINS_8 = [11, 12, 13, 15, 16, 18, 22, 7] + self._PINS_12 = [11, 12, 13, 15, 16, 18, 22, 7, 29, 31, 32, 36] + + # Default configuration (will be overwritten by load_config) + self.num_params = 12 + self.input_pins = self._PINS_12 + + # Internal State Arrays + self.i_counters = array('i', [0] * 12) + self.B_blinking = array('B', [0] * 12) + self.B_previous = array('B', [0] * 12) + self.B_input = array('B', [0] * 12) + self.B_output = array('B', [0] * 12) + self.B_inverting = array('B', [0] * 12) + self.B_filter = array('B', [0] * 12) + self.B_filter_prev = array('B', [0] * 12) + self.B_temp = array('B', [0] * 12) + self.i_filter_counters = array('i', [0] * 12) -avviaParallela() + # Load configuration after arrays are initialized + self.load_config(config_path) + + # Control Variables + self.cont = 0 + self.onLine = '1' + self.sending = False + self.timer_busy = False + self.to_enable = False + self.to_short = self.TIMEOUTSHORT + self.to_long = self.TIMEOUTLONG + self.to_retry = self.MAXRETRY + + # Redis + self.CodaR = redis.Redis(host='localhost', port=6379, db=0, password='24068Seriate') + self.queue_name = 'IOB' + + # Logging + self.setup_logging() + def load_config(self, path): + """ + Loads configuration parameters from the specified .cfg file. + Sets up timing, URL, logging, and bit-specific settings (blinking, inversion, filtering). + """ + config = configparser.RawConfigParser() + if not os.path.exists(path): + print(f"Error: Config file {path} not found.") + sys.exit(1) + config.read(path) -#-------------------------------------------------------------- -# Qui avvio thread periodico di "svuotaCoda" - -#print ("Avvia svuota coda") -do_every ( SENDURLTIME , svuotaCoda ); - -#--------------------------------------------------------------- -# ciclo forever and ever - -old = '' - -#print ("Avvio ciclo") -logPro.info("Avvio loop principale") -while 1: - - try: - time.sleep (SAMPLETIME) - except Exception as e: - logPro.info("First_SLEEP: errore attesa sampletime") - logPro.error(str(e)) - - # lettura dati da IOB - value = readParallelaFiltrata() - - if ( value != '' ) : - if value != old : - #loggo e invio dati - try: - logQue.info( value + ' ['+ cont +']') - errormsglen = 0 - accoda() - contatore() - except Exception as e: - logPro.error("URLBROWSER: errore registrazione valore e accoda") - 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 - SAMPLETIME - if to_short <= 0: - #loggo e invio dati - try: - logQue.info( '>' + value + ' ['+ cont +']') - errormsglen = 0 - accoda() - contatore() - except Exception as e: - logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") - logPro.error(str(e)) - 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 + # 1. Determine number of parameters try: - logQue.info( '>>' + value + ' ['+ cont +']') - errormsglen = 0 - accoda() - contatore() + val = config.getint('id', 'numParams', fallback=12) + if val in [8, 12]: + self.num_params = val + else: + self.num_params = 12 + except ValueError: + self.num_params = 12 + + # 2. Update hardware pins and arrays based on num_params + if self.num_params == 8: + self.input_pins = self._PINS_8 + else: + self.input_pins = self._PINS_12 + + self.i_counters = array('i', [0] * self.num_params) + self.B_blinking = array('B', [0] * self.num_params) + self.B_previous = array('B', [0] * self.num_params) + self.B_input = array('B', [0] * self.num_params) + self.B_output = array('B', [0] * self.num_params) + self.B_inverting = array('B', [0] * self.num_params) + self.B_filter = array('B', [0] * self.num_params) + self.B_filter_prev = array('B', [0] * self.num_params) + self.B_temp = array('B', [0] * self.num_params) + self.i_filter_counters = array('i', [0] * self.num_params) + + # 3. Load other parameters + self.idxMacchina = config.get('id', 'idxMacchina') + self.SAMPLETIME = config.getfloat('time', 'SAMPLETIME') + self.TIMEOUTSHORT = config.getfloat('time', 'TIMEOUTSHORT') + self.TIMEOUTLONG = config.getfloat('time', 'TIMEOUTLONG') + self.SENDURLTIME = config.getfloat('time', 'SENDURLTIME') + self.NMAXSEND = config.getint('time', 'NMAXSEND') + + self.URLBASE = config.get('web', 'URLBASE') + self.URLENABLED = config.get('web', 'URLENABLED') + self.URLALIVE = config.get('web', 'URLALIVE') + self.URLADV1 = config.get('web', 'URLADV1') + + self.LOGFILE = config.get('log', 'LOGFILE') + self.LOGLEVEL = config.get('log', 'LOGLEVEL') + + # 4. Load bit settings using loops + for i in range(self.num_params): + self.B_blinking[i] = config.getint('blink', f'bit{i}') + self.MAX_COUNTER_BLINK = config.getint('blink', 'MAX_COUNTER_BLINK') + + for i in range(self.num_params): + self.B_inverting[i] = config.getint('invert', f'bit{i}') + self.B_filter[i] = config.getint('filter', f'bit{i}') + self.MAX_COUNTER_FILTER = config.getint('filter', 'MAX_COUNTER_FILTER') + + def setup_logging(self): + """ + Configures the logging system. + """ + logging.basicConfig( + level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=self.LOGFILE, + filemode='a' + ) + self.logQue = logging.getLogger('queue') + self.logSnd = logging.getLogger('sendUrl') + self.logPro = logging.getLogger('program') + + def setup_gpio(self): + """ + Initializes the GPIO pins for input. + """ + if GPIO is None: + self.logPro.error("GPIO library not found. Are you on a Raspberry Pi?") + sys.exit(1) + try: + GPIO.setmode(GPIO.BOARD) + GPIO.setwarnings(False) + for pin in self.input_pins: + GPIO.setup(pin, GPIO.IN) + self.logPro.info("GPIO initialized successfully.") except Exception as e: - logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") - logPro.error(str(e)) - pass - to_long = TIMEOUTLONG + self.logPro.error(f"GPIO Setup Error: {e}") + sys.exit(1) + + def rqEnqueue(self, item): + """ + Adds an item to the Redis queue. + """ + self.CodaR.rpush(self.queue_name, item) + + def rqDequeue(self): + """ + Removes and returns an item from the Redis queue. + """ + item = self.CodaR.lpop(self.queue_name) + return item.decode('utf-8') if item else None + + def rqLen(self): + """ + Returns the current length of the Redis queue. + """ + return self.CodaR.llen(self.queue_name) + + def readParallelaFiltrata(self): + """ + Performs the core logic: reads GPIO, applies inversion, filtering, + and blinking, then reconstructs the value as a hex string. + """ + try: + # 1. Efficient GPIO Read + # Using a local reference for speed in loops + gpio_input = GPIO.input + pins = self.input_pins + inverting = self.B_inverting + input_arr = self.B_input + + for i in range(self.num_params): + # Read and invert logic immediately if required + raw_val = 0 if gpio_input(pins[i]) else 1 + if inverting[i]: + raw_val = 1 - raw_val + input_arr[i] = raw_val + + # 2. Processing Loop (Filtering & Blinking) + # Pre-caching references to reduce attribute lookups in tight loops + filter_arr = self.B_filter + filter_prev = self.B_filter_prev + filter_counters = self.i_filter_counters + max_filter = self.MAX_COUNTER_FILTER + + blinking = self.B_blinking + previous = self.B_previous + output_arr = self.B_output + blink_counters = self.i_counters + + for i in range(self.num_params): + # Debounce / Filter logic + if filter_arr[i]: + curr_in = input_arr[i] + prev_in = filter_prev[i] + + if curr_in != prev_in: + # State change detected + if curr_in == 1: + filter_counters[i] = max_filter if filter_counters[i] == 0 else 0 + self.B_temp[i] = 0 if filter_counters[i] == max_filter else 1 + else: + filter_counters[i] = max_filter if filter_counters[i] == 0 else 0 + self.B_temp[i] = 1 if filter_counters[i] == max_filter else 0 + + filter_prev[i] = curr_in + input_arr[i] = self.B_temp[i] + else: + # No state change, maintain or decrement counter + if filter_counters[i] > 0: + filter_counters[i] -= 1 + self.B_temp[i] = 0 if curr_in == 1 else 1 + else: + self.B_temp[i] = 1 if curr_in == 1 else 0 + + # Update the actual input array with the filtered value + input_arr[i] = self.B_temp[i] + + # Blinking Logic + if blinking[i] == 0: + output_arr[i] = input_arr[i] + else: + if previous[i] != input_arr[i]: + previous[i] = input_arr[i] + if input_arr[i] == 1: + output_arr[i] = 1 + blink_counters[i] = self.MAX_COUNTER_BLINK + else: + if input_arr[i] == 0 and blink_counters[i] > 0: + blink_counters[i] -= 1 + if blink_counters[i] == 0: + output_arr[i] = 0 + + # 3. Optimized Bitwise Reconstruction + new_value = 0 + for i in range(self.num_params): + if output_arr[i]: + new_value |= (1 << i) + + if self.num_params == 8: + return f"{new_value:02X}" + else: + # For 12 bits, we want to ensure we don't have leading 0s if not needed, + # but the user's log showed F83, which is a 3-digit hex. + # hex(new_value)[2:].upper() is fine. + return hex(new_value)[2:].upper() + + except Exception as e: + self.logPro.error(f"Error in readParallelaFiltrata: {e}") + return '' + + def accoda(self, value): + try: + dt_eve = datetime.now(timezone.utc).strftime('%Y%m%d%H%M%S%f')[:-3] + self.rqEnqueue(f"{dt_eve}#{value}#{self.cont}") + except Exception as e: + self.logPro.error(f"QUEUE ERROR: {e}") + + def svuotaCoda(self): + if self.timer_busy: + return + + self.timer_busy = True + try: + if self.rqLen() > 0: + # Check connectivity using requests + try: + res_alive = requests.get(self.URLALIVE, timeout=5) + if res_alive.text == 'OK': + res_enabled = requests.get(self.URLENABLED + self.idxMacchina, timeout=5) + if res_enabled.text == 'OK': + if self.onLine == '0': + self.logPro.info("IOB ONLINE!") + self.onLine = '1' + else: + self.onLine = '0' + else: + self.onLine = '0' + except Exception as e: + self.logPro.error(f"Server Connection Error: {e}") + self.onLine = '0' + + if self.onLine == '1' and not self.sending: + self.sending = True + for _ in range(self.NMAXSEND): + if self.rqLen() == 0: + break + + resp = self.rqDequeue() + if not resp: break + + parts = resp.split("#") + dt_eve, val, cnt = parts[0], parts[1], parts[2] + dt_curr = datetime.now(timezone.utc).strftime('%Y%m%d%H%M%S%f')[:-3] + + url = f"{self.URLBASE}{self.idxMacchina}{self.URLADV1}{val}&dtCurr={dt_curr}&dtEve={dt_eve}&cnt={cnt}" + + try: + r = requests.get(url, timeout=5) + self.logSnd.info(f"{val} [{cnt}] R:{r.text}") + except Exception as e: + self.logSnd.error(f"Send Error: {e}") + + self.sending = False + elif self.sending: + if self.to_retry > 0: + self.to_retry -= 1 + self.logPro.info("WAIT active send to complete") + else: + self.sending = False + self.to_retry = self.MAXRETRY + self.logPro.info("END WAIT, reset to_retry") + except Exception as e: + self.logPro.error(f"svuotaCoda Error: {e}") + finally: + self.timer_busy = False + + def run(self): + """ + Starts the main execution loop: + 1. Initializes GPIO. + 2. Spawns a background daemon thread to empty the Redis queue. + 3. Enters a loop to sample GPIO inputs, apply filters/blinking, and queue changes. + """ + self.logPro.info("-----------------------------") + self.logPro.info(self.PROGRAM_NAME) + self.logPro.info("-----------------------------") + + self.setup_gpio() + + # Start background thread for queue emptying + def timer_worker(): + while True: + self.svuotaCoda() + time.sleep(self.SENDURLTIME) + + threading.Thread(target=timer_worker, daemon=True).start() + + old_value = '' + self.logPro.info("Starting main loop") + + while True: + try: + time.sleep(self.SAMPLETIME) + value = self.readParallelaFiltrata() + + if value != '': + if value != old_value: + self.logQue.info(f"{value} [{self.cont}]") + self.accoda(value) + self.cont = (self.cont + 1) % 10000 + + self.to_enable = True + self.to_short = self.TIMEOUTSHORT + self.to_long = self.TIMEOUTLONG + old_value = value + + # Handle Timeouts + if self.to_enable: + self.to_short -= self.SAMPLETIME + if self.to_short <= 0: + self.logQue.info(f">{value} [{self.cont}]") + self.accoda(value) + self.to_short = self.TIMEOUTSHORT + self.to_enable = False + self.to_long = self.TIMEOUTLONG + + self.to_long -= self.SAMPLETIME + if self.to_long <= 0: + self.logQue.info(f">>{value} [{self.cont}]") + self.accoda(value) + self.to_long = self.TIMEOUTLONG + + except KeyboardInterrupt: + self.logPro.info("Keyboard interrupt received. Exiting...") + break + except Exception as e: + self.logPro.error(f"Main loop error: {e}") + +if __name__ == "__main__": + app = ReadParallelaIOB() + app.run() diff --git a/IOB-PI/readParallela_12.py b/IOB-PI/readParallela_12.py index 5ad263e..0982a23 100644 --- a/IOB-PI/readParallela_12.py +++ b/IOB-PI/readParallela_12.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -# readParallela v. 2.6.1 12 Ingressi +# readParallela v. 2.6.2 12 Ingressi # - single instance timer # - invio multiplo x send eventi accodati # - gestione segnali BLINKING @@ -16,23 +16,20 @@ # - (2.5.3) Fix gestione stringhe e print x python 3.11 in debian 12 / raspberry OS 2025 # - (2.6.0) Aggiunto gestione Redis x code salvate ogni minuto e ricaricate all'avvio 2025.04.17 # - (2.6.1) Cleanup generale vecchia queue post test vari +# - (2.6.2) Fix in global di to_retry in send_coda per evitare problemi + import time import sys - - from datetime import datetime - import urllib import urllib.request import configparser import os, sys - import logging import logging.handlers import threading import redis - from array import * #-------------------------------------------------------------- @@ -44,7 +41,7 @@ MAXRETRY = 10 # numero campioni filtraggio segnale ballerino MAX_COUNTER_BLINK = 10 -PROGRAM_NAME ="ReadPar IOB-pi v.2.6.1" +PROGRAM_NAME ="ReadPar IOB-pi v.2.6.2" # DA FILE CONF idxMacchina = "1001" @@ -380,6 +377,7 @@ def svuotaCoda(): global onLine global sending global timer_busy + global to_retry global NMAXSEND #logPro.info ("start timer ") @@ -473,10 +471,11 @@ def svuotaCoda(): logPro.error(str(e)) onLine = '0' + + finally: + # in ogni caso + timer_busy = False - # in ogni caso - - timer_busy = False #print ("end timer ok") #print ("end timer ") diff --git a/IOB-PI/readParallela_8.py b/IOB-PI/readParallela_8.py index ab67aee..895cde1 100644 --- a/IOB-PI/readParallela_8.py +++ b/IOB-PI/readParallela_8.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -# readParallela v. 2.6.1 8 Ingressi +# readParallela v. 2.6.2 8 Ingressi # - single instance timer # - invio multiplo x send eventi accodati # - gestione segnali BLINKING @@ -16,6 +16,8 @@ # - (2.5.3) Fix gestione stringhe e print x python 3.11 in debian 12 / raspberry OS 2025 # - (2.6.0) Aggiunto gestione Redis x code salvate ogni minuto e ricaricate all'avvio 2025.04.17 # - (2.6.1) Cleanup generale vecchia queue post test vari +# - (2.6.2) Fix in global di to_retry in send_coda per evitare problemi + import time import sys @@ -44,7 +46,7 @@ MAXRETRY = 10 # numero campioni filtraggio segnale ballerino MAX_COUNTER_BLINK = 10 -PROGRAM_NAME ="ReadPar IOB-pi v.2.6.1" +PROGRAM_NAME ="ReadPar IOB-pi v.2.6.2" # DA FILE CONF idxMacchina = "1001" @@ -343,6 +345,7 @@ def svuotaCoda(): global onLine global sending global timer_busy + global to_retry global NMAXSEND #logPro.info ("start timer ") @@ -436,10 +439,11 @@ def svuotaCoda(): logPro.error(str(e)) onLine = '0' + + finally: + # in ogni caso + timer_busy = False - # in ogni caso - - timer_busy = False #print ("end timer ok") #print ("end timer ") diff --git a/IOB-PI/std_vers/MapoIOB.service b/IOB-PI/std_vers/MapoIOB.service index 8f86fdb..7803ccc 100644 --- a/IOB-PI/std_vers/MapoIOB.service +++ b/IOB-PI/std_vers/MapoIOB.service @@ -8,13 +8,15 @@ Conflicts=shutdown.target [Service] Type=forking -Restart=no +Restart=on-failure +RestartSec=5 TimeoutSec=5min IgnoreSIGPIPE=no KillMode=process GuessMainPID=no RemainAfterExit=yes SysVStartPriority=1 +ExecStartPre=/bin/sleep 5 ExecStart=/etc/init.d/MapoIOB start ExecStop=/etc/init.d/MapoIOB stop diff --git a/IOB-PI/vers2.5 12bit/MapoIOB.service b/IOB-PI/vers2.5 12bit/MapoIOB.service index 8f86fdb..7803ccc 100644 --- a/IOB-PI/vers2.5 12bit/MapoIOB.service +++ b/IOB-PI/vers2.5 12bit/MapoIOB.service @@ -8,13 +8,15 @@ Conflicts=shutdown.target [Service] Type=forking -Restart=no +Restart=on-failure +RestartSec=5 TimeoutSec=5min IgnoreSIGPIPE=no KillMode=process GuessMainPID=no RemainAfterExit=yes SysVStartPriority=1 +ExecStartPre=/bin/sleep 5 ExecStart=/etc/init.d/MapoIOB start ExecStop=/etc/init.d/MapoIOB stop diff --git a/IOB-PI/vers2.5 8bit/MapoIOB.service b/IOB-PI/vers2.5 8bit/MapoIOB.service index 8f86fdb..7803ccc 100644 --- a/IOB-PI/vers2.5 8bit/MapoIOB.service +++ b/IOB-PI/vers2.5 8bit/MapoIOB.service @@ -8,13 +8,15 @@ Conflicts=shutdown.target [Service] Type=forking -Restart=no +Restart=on-failure +RestartSec=5 TimeoutSec=5min IgnoreSIGPIPE=no KillMode=process GuessMainPID=no RemainAfterExit=yes SysVStartPriority=1 +ExecStartPre=/bin/sleep 5 ExecStart=/etc/init.d/MapoIOB start ExecStop=/etc/init.d/MapoIOB stop diff --git a/StateMachineStati/1_BARCODE_MANUALE - NEW.csv b/StateMachineStati/1_BARCODE_MANUALE - NEW.csv index e30fcfd..7e05209 100644 --- a/StateMachineStati/1_BARCODE_MANUALE - NEW.csv +++ b/StateMachineStati/1_BARCODE_MANUALE - NEW.csv @@ -31,6 +31,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;0;61;61 1;0;62;62 1;0;63;63 +1;0;64;64 1;2;0;0 1;2;1;13 1;2;3;3 @@ -63,6 +64,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;2;61;61 1;2;62;62 1;2;63;63 +1;2;64;64 1;3;0;0 1;3;1;13 1;3;2;2 @@ -95,6 +97,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;3;61;61 1;3;62;62 1;3;63;63 +1;3;64;64 1;4;0;0 1;4;1;13 1;4;2;2 @@ -127,6 +130,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;4;61;61 1;4;62;62 1;4;63;63 +1;4;64;64 1;5;0;0 1;5;1;13 1;5;2;2 @@ -159,6 +163,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;5;61;61 1;5;62;62 1;5;63;63 +1;5;64;64 1;6;0;0 1;6;1;13 1;6;2;2 @@ -191,6 +196,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;6;61;61 1;6;62;62 1;6;63;63 +1;6;64;64 1;7;0;0 1;7;1;13 1;7;2;2 @@ -223,6 +229,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;7;61;61 1;7;62;62 1;7;63;63 +1;7;64;64 1;8;0;0 1;8;1;13 1;8;2;2 @@ -255,6 +262,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;8;61;61 1;8;62;62 1;8;63;63 +1;8;64;64 1;9;0;0 1;9;1;13 1;9;2;2 @@ -287,6 +295,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;9;61;61 1;9;62;62 1;9;63;63 +1;9;64;64 1;10;0;0 1;10;1;13 1;10;2;2 @@ -319,6 +328,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;10;61;61 1;10;62;62 1;10;63;63 +1;10;64;64 1;11;0;0 1;11;1;13 1;11;2;2 @@ -351,6 +361,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;11;61;61 1;11;62;62 1;11;63;63 +1;11;64;64 1;13;0;0 1;13;2;2 1;13;3;3 @@ -383,6 +394,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;13;61;61 1;13;62;62 1;13;63;63 +1;13;64;64 1;27;0;0 1;27;1;13 1;27;2;2 @@ -415,6 +427,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;27;61;61 1;27;62;62 1;27;63;63 +1;27;64;64 1;30;0;0 1;30;1;13 1;30;2;2 @@ -447,6 +460,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;30;61;61 1;30;62;62 1;30;63;63 +1;30;64;64 1;31;0;0 1;31;1;13 1;31;2;2 @@ -479,6 +493,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;31;61;61 1;31;62;62 1;31;63;63 +1;31;64;64 1;32;0;0 1;32;1;13 1;32;2;2 @@ -511,6 +526,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;32;61;61 1;32;62;62 1;32;63;63 +1;32;64;64 1;33;0;0 1;33;1;13 1;33;2;2 @@ -543,6 +559,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;33;61;61 1;33;62;62 1;33;63;63 +1;33;64;64 1;34;0;0 1;34;1;13 1;34;2;2 @@ -575,6 +592,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;34;61;61 1;34;62;62 1;34;63;63 +1;34;64;64 1;35;0;0 1;35;1;13 1;35;2;2 @@ -607,6 +625,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;35;61;61 1;35;62;62 1;35;63;63 +1;35;64;64 1;49;0;0 1;49;1;13 1;49;2;2 @@ -639,6 +658,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;49;61;61 1;49;62;62 1;49;63;63 +1;49;64;64 1;50;0;0 1;50;1;13 1;50;2;2 @@ -671,6 +691,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;50;61;61 1;50;62;62 1;50;63;63 +1;50;64;64 1;51;0;0 1;51;1;13 1;51;2;2 @@ -703,6 +724,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;51;61;61 1;51;62;62 1;51;63;63 +1;51;64;64 1;52;0;0 1;52;1;13 1;52;2;2 @@ -735,6 +757,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;52;61;61 1;52;62;62 1;52;63;63 +1;52;64;64 1;54;0;0 1;54;1;13 1;54;2;2 @@ -767,6 +790,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;54;61;61 1;54;62;62 1;54;63;63 +1;54;64;64 1;55;0;0 1;55;1;13 1;55;2;2 @@ -799,6 +823,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;55;61;61 1;55;62;62 1;55;63;63 +1;55;64;64 1;56;0;0 1;56;1;13 1;56;2;2 @@ -831,6 +856,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;56;61;61 1;56;62;62 1;56;63;63 +1;56;64;64 1;57;0;0 1;57;1;13 1;57;2;2 @@ -863,6 +889,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;57;61;61 1;57;62;62 1;57;63;63 +1;57;64;64 1;58;0;0 1;58;1;13 1;58;2;2 @@ -895,6 +922,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;58;61;61 1;58;62;62 1;58;63;63 +1;58;64;64 1;59;0;0 1;59;1;13 1;59;2;2 @@ -927,6 +955,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;59;61;61 1;59;62;62 1;59;63;63 +1;59;64;64 1;60;0;0 1;60;1;13 1;60;2;2 @@ -959,6 +988,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;60;61;61 1;60;62;62 1;60;63;63 +1;60;64;64 1;61;0;0 1;61;1;13 1;61;2;2 @@ -991,6 +1021,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;61;60;60 1;61;62;62 1;61;63;63 +1;61;64;64 1;62;0;0 1;62;1;13 1;62;2;2 @@ -1023,6 +1054,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;62;60;60 1;62;61;61 1;62;63;63 +1;62;64;64 1;63;0;0 1;63;1;13 1;63;2;2 @@ -1055,3 +1087,37 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 1;63;60;60 1;63;61;61 1;63;62;62 +1;63;64;64 +1;64;0;0 +1;64;1;13 +1;64;2;2 +1;64;3;3 +1;64;4;4 +1;64;5;5 +1;64;6;6 +1;64;7;7 +1;64;8;8 +1;64;9;9 +1;64;10;10 +1;64;12;11 +1;64;19;30 +1;64;26;27 +1;64;31;31 +1;64;32;32 +1;64;37;33 +1;64;38;34 +1;64;39;35 +1;64;49;49 +1;64;50;50 +1;64;51;51 +1;64;52;52 +1;64;54;54 +1;64;55;55 +1;64;56;56 +1;64;57;57 +1;64;58;58 +1;64;59;59 +1;64;60;60 +1;64;61;61 +1;64;62;62 +1;64;63;63 diff --git a/StateMachineStati/1_BARCODE_MANUALE - NEW.rul b/StateMachineStati/1_BARCODE_MANUALE - NEW.rul index e0156da..4e00cbd 100644 --- a/StateMachineStati/1_BARCODE_MANUALE - NEW.rul +++ b/StateMachineStati/1_BARCODE_MANUALE - NEW.rul @@ -1,4 +1,4 @@ -# +# # Macchine MANUALE/Barcode di partenza # # @@ -9,6 +9,7 @@ # 2024.01.18 Aggiunto barcode Rottura Utensile - 59 - ColCom # 2024.02.23 Aggiunto barcode Pausa - 60 - Fluitek # 2024.07.17 Aggiunti Barcode Lvf - 61 62 63 +# 2026.03.27 Aggiunti Barcode Fluitek - 64 $DEFINITIONS @@ -53,6 +54,7 @@ $STATE : 60 : Pausa $STATE : 61 : Manutenzione_Straordinaria $STATE : 62 : Manutenzione_Ordinaria $STATE : 63 : Problemi_di_Lavorazione +$STATE : 64 : Prototipi # definizione eventi : obbligatorio iniziare da 0 --> select * from AnagraficaEventi # NOTE @@ -90,6 +92,7 @@ $EVENT : 60 : Barcode_Pausa $EVENT : 61 : Barcode_Manutenzione_Straordinaria $EVENT : 62 : Barcode_Manutenzione_Ordinaria $EVENT : 63 : Barcode_Problemi_di_Lavorazione +$EVENT : 64 : Barcode_Prototipi $RULES @@ -130,6 +133,7 @@ ALL_STATES : Barcode_Pausa : Paus ALL_STATES : Barcode_Manutenzione_Straordinaria : Manutenzione_Straordinaria # 61 ALL_STATES : Barcode_Manutenzione_Ordinaria : Manutenzione_Ordinaria # 62 ALL_STATES : Barcode_Problemi_di_Lavorazione : Problemi_di_Lavorazione # 63 +ALL_STATES : Barcode_Prototipi : Prototipi # 64 #-------------------------------------------------------------------------- $DO diff --git a/StateMachineStati/ELENCO_EVENTI_E_STATI_MASTER_NEW.rul b/StateMachineStati/ELENCO_EVENTI_E_STATI_MASTER_NEW.rul index 415fdf2..4be0578 100644 --- a/StateMachineStati/ELENCO_EVENTI_E_STATI_MASTER_NEW.rul +++ b/StateMachineStati/ELENCO_EVENTI_E_STATI_MASTER_NEW.rul @@ -10,6 +10,7 @@ # 2024.02.23 Aggiunto Barcode Pausa - 60 - Fluitek # 2024.07.17 Aggiunti Barcode Lvf - 61 62 63 # 2025.01.28 Aggiunto Stato 40 HW_Riscaldam +# 2026.03.27 Aggiunti Barcode Fluitek - 64 # ELENCO STATI E EVENTI DI BASE @@ -65,6 +66,7 @@ $STATE : 60 : Pausa $STATE : 61 : Manutenzione_Straordinaria $STATE : 62 : Manutenzione_Ordinaria $STATE : 63 : Problemi_di_Lavorazione +$STATE : 64 : Prototipi #definizione eventi : obbligatorio iniziare da 0 --> select * from AnagraficaEventi # NOTE @@ -145,6 +147,7 @@ $EVENT : 60 : Barcode_Pausa $EVENT : 61 : Barcode_Manutenzione_Straordinaria $EVENT : 62 : Barcode_Manutenzione_Ordinaria $EVENT : 63 : Barcode_Problemi_di_Lavorazione +$EVENT : 64 : Barcode_Prototipi $RULES @@ -187,5 +190,6 @@ ALL_STATES : Barcode_Pausa : Pausa # 60 ALL_STATES : Barcode_Manutenzione_Straordinaria : Manutenzione_Straordinaria # 61 ALL_STATES : Barcode_Manutenzione_Ordinaria : Manutenzione_Ordinaria # 62 ALL_STATES : Barcode_Problemi_di_Lavorazione : Problemi_di_Lavorazione # 63 +ALL_STATES : Barcode_Prototipi : Prototipi # 64 ALL_STATES : HW_power_off : Macchina_Spenta # 14 diff --git a/StateMachineStati/Jetco/12_FAMIGLIA_JETCO_NEW.csv b/StateMachineStati/Jetco/12_FAMIGLIA_JETCO_NEW.csv index 91b9998..b8a4b7c 100644 --- a/StateMachineStati/Jetco/12_FAMIGLIA_JETCO_NEW.csv +++ b/StateMachineStati/Jetco/12_FAMIGLIA_JETCO_NEW.csv @@ -32,6 +32,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;0;61;61 12;0;62;62 12;0;63;63 +12;0;64;64 12;2;0;0 12;2;1;13 12;2;3;3 @@ -66,6 +67,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;2;61;61 12;2;62;62 12;2;63;63 +12;2;64;64 12;3;0;0 12;3;1;13 12;3;2;2 @@ -100,6 +102,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;3;61;61 12;3;62;62 12;3;63;63 +12;3;64;64 12;4;0;0 12;4;1;13 12;4;2;2 @@ -134,6 +137,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;4;61;61 12;4;62;62 12;4;63;63 +12;4;64;64 12;5;0;0 12;5;1;13 12;5;2;2 @@ -168,6 +172,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;5;61;61 12;5;62;62 12;5;63;63 +12;5;64;64 12;6;0;0 12;6;1;13 12;6;2;2 @@ -202,6 +207,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;6;61;61 12;6;62;62 12;6;63;63 +12;6;64;64 12;7;0;0 12;7;1;13 12;7;2;2 @@ -236,6 +242,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;7;61;61 12;7;62;62 12;7;63;63 +12;7;64;64 12;8;0;0 12;8;1;13 12;8;2;2 @@ -270,6 +277,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;8;61;61 12;8;62;62 12;8;63;63 +12;8;64;64 12;9;0;0 12;9;1;13 12;9;2;2 @@ -304,6 +312,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;9;61;61 12;9;62;62 12;9;63;63 +12;9;64;64 12;10;0;0 12;10;1;13 12;10;2;2 @@ -338,6 +347,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;10;61;61 12;10;62;62 12;10;63;63 +12;10;64;64 12;11;0;0 12;11;1;13 12;11;2;2 @@ -385,6 +395,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;11;61;61 12;11;62;62 12;11;63;63 +12;11;64;64 12;12;0;0 12;12;1;13 12;12;2;2 @@ -430,6 +441,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;12;61;61 12;12;62;62 12;12;63;63 +12;12;64;64 12;13;0;0 12;13;2;2 12;13;3;3 @@ -474,6 +486,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;13;61;61 12;13;62;62 12;13;63;63 +12;13;64;64 12;14;0;0 12;14;1;13 12;14;2;2 @@ -520,6 +533,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;14;61;61 12;14;62;62 12;14;63;63 +12;14;64;64 12;15;0;0 12;15;1;13 12;15;2;2 @@ -564,6 +578,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;15;61;61 12;15;62;62 12;15;63;63 +12;15;64;64 12;23;0;0 12;23;1;13 12;23;2;2 @@ -613,6 +628,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;23;61;61 12;23;62;62 12;23;63;63 +12;23;64;64 12;24;0;0 12;24;1;13 12;24;2;2 @@ -658,6 +674,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;24;61;61 12;24;62;62 12;24;63;63 +12;24;64;64 12;25;0;0 12;25;1;13 12;25;2;2 @@ -706,6 +723,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;25;61;61 12;25;62;62 12;25;63;63 +12;25;64;64 12;26;0;0 12;26;1;13 12;26;2;2 @@ -755,6 +773,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;26;61;61 12;26;62;62 12;26;63;63 +12;26;64;64 12;27;0;0 12;27;1;13 12;27;2;2 @@ -789,6 +808,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;27;61;61 12;27;62;62 12;27;63;63 +12;27;64;64 12;28;0;0 12;28;1;13 12;28;2;2 @@ -825,6 +845,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;28;61;61 12;28;62;62 12;28;63;63 +12;28;64;64 12;29;0;0 12;29;1;13 12;29;2;2 @@ -863,6 +884,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;29;61;61 12;29;62;62 12;29;63;63 +12;29;64;64 12;30;0;0 12;30;1;13 12;30;2;2 @@ -896,6 +918,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;30;61;61 12;30;62;62 12;30;63;63 +12;30;64;64 12;31;0;0 12;31;1;13 12;31;2;2 @@ -930,6 +953,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;31;61;61 12;31;62;62 12;31;63;63 +12;31;64;64 12;32;0;0 12;32;1;13 12;32;2;2 @@ -964,6 +988,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;32;61;61 12;32;62;62 12;32;63;63 +12;32;64;64 12;33;0;0 12;33;1;13 12;33;2;2 @@ -998,6 +1023,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;33;61;61 12;33;62;62 12;33;63;63 +12;33;64;64 12;34;0;0 12;34;1;13 12;34;2;2 @@ -1031,6 +1057,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;34;61;61 12;34;62;62 12;34;63;63 +12;34;64;64 12;35;0;0 12;35;1;13 12;35;2;2 @@ -1065,6 +1092,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;35;61;61 12;35;62;62 12;35;63;63 +12;35;64;64 12;40;0;0 12;40;1;13 12;40;2;2 @@ -1103,6 +1131,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;40;61;61 12;40;62;62 12;40;63;63 +12;40;64;64 12;49;0;0 12;49;1;13 12;49;2;2 @@ -1137,6 +1166,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;49;61;61 12;49;62;62 12;49;63;63 +12;49;64;64 12;50;0;0 12;50;1;13 12;50;2;2 @@ -1171,6 +1201,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;50;61;61 12;50;62;62 12;50;63;63 +12;50;64;64 12;51;0;0 12;51;1;13 12;51;2;2 @@ -1204,6 +1235,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;51;61;61 12;51;62;62 12;51;63;63 +12;51;64;64 12;52;0;0 12;52;1;13 12;52;2;2 @@ -1237,6 +1269,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;52;61;61 12;52;62;62 12;52;63;63 +12;52;64;64 12;54;0;0 12;54;1;13 12;54;2;2 @@ -1270,6 +1303,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;54;61;61 12;54;62;62 12;54;63;63 +12;54;64;64 12;55;0;0 12;55;1;13 12;55;2;2 @@ -1303,6 +1337,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;55;61;61 12;55;62;62 12;55;63;63 +12;55;64;64 12;56;0;0 12;56;1;13 12;56;2;2 @@ -1336,6 +1371,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;56;61;61 12;56;62;62 12;56;63;63 +12;56;64;64 12;57;0;0 12;57;1;13 12;57;2;2 @@ -1369,6 +1405,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;57;61;61 12;57;62;62 12;57;63;63 +12;57;64;64 12;58;0;0 12;58;1;13 12;58;2;2 @@ -1402,6 +1439,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;58;61;61 12;58;62;62 12;58;63;63 +12;58;64;64 12;59;0;0 12;59;1;13 12;59;2;2 @@ -1435,6 +1473,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;59;61;61 12;59;62;62 12;59;63;63 +12;59;64;64 12;60;0;0 12;60;1;13 12;60;2;2 @@ -1468,6 +1507,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;60;61;61 12;60;62;62 12;60;63;63 +12;60;64;64 12;61;0;0 12;61;1;13 12;61;2;2 @@ -1501,6 +1541,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;61;60;60 12;61;62;62 12;61;63;63 +12;61;64;64 12;62;0;0 12;62;1;13 12;62;2;2 @@ -1534,6 +1575,7 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;62;60;60 12;62;61;61 12;62;63;63 +12;62;64;64 12;63;0;0 12;63;1;13 12;63;2;2 @@ -1567,3 +1609,38 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 12;63;60;60 12;63;61;61 12;63;62;62 +12;63;64;64 +12;64;0;0 +12;64;1;13 +12;64;2;2 +12;64;3;3 +12;64;4;4 +12;64;5;5 +12;64;6;6 +12;64;7;7 +12;64;8;8 +12;64;9;9 +12;64;10;10 +12;64;12;11 +12;64;14;11 +12;64;19;30 +12;64;26;27 +12;64;31;31 +12;64;32;32 +12;64;37;33 +12;64;38;34 +12;64;39;35 +12;64;49;49 +12;64;50;50 +12;64;51;51 +12;64;52;52 +12;64;54;54 +12;64;55;55 +12;64;56;56 +12;64;57;57 +12;64;58;58 +12;64;59;59 +12;64;60;60 +12;64;61;61 +12;64;62;62 +12;64;63;63 diff --git a/StateMachineStati/Jetco/12_FAMIGLIA_JETCO_NEW.rul b/StateMachineStati/Jetco/12_FAMIGLIA_JETCO_NEW.rul index 812b017..9f78035 100644 --- a/StateMachineStati/Jetco/12_FAMIGLIA_JETCO_NEW.rul +++ b/StateMachineStati/Jetco/12_FAMIGLIA_JETCO_NEW.rul @@ -13,6 +13,7 @@ # 2024.03.27 Sistemazione allineamento e Intestazione + TEST # 2024.10.08 Agg. uscita Emergenza con HW_Power_On # 2025.01.28 Creato Stato Riscaldam_Autom Riscaldamento da HW + Mod. Rule + Barcode Nuovi - Adesso il Risc. da Barcode esce solo con altri Barcode +# 2026.03.27 Aggiunti Barcode Fluitek - 64 # $DEFINITIONS @@ -67,6 +68,7 @@ $STATE : 60 : Pausa $STATE : 61 : Manutenzione_Straordinaria $STATE : 62 : Manutenzione_Ordinaria $STATE : 63 : Problemi_di_Lavorazione +$STATE : 64 : Prototipi #definizione eventi : obbligatorio iniziare da 0 --> select * from AnagraficaEventi @@ -134,6 +136,7 @@ $EVENT : 60 : Barcode_Pausa $EVENT : 61 : Barcode_Manutenzione_Straordinaria $EVENT : 62 : Barcode_Manutenzione_Ordinaria $EVENT : 63 : Barcode_Problemi_di_Lavorazione +$EVENT : 64 : Barcode_Prototipi $RULES @@ -176,6 +179,7 @@ ALL_STATES : Barcode_Pausa : Paus ALL_STATES : Barcode_Manutenzione_Straordinaria : Manutenzione_Straordinaria # 61 ALL_STATES : Barcode_Manutenzione_Ordinaria : Manutenzione_Ordinaria # 62 ALL_STATES : Barcode_Problemi_di_Lavorazione : Problemi_di_Lavorazione # 63 +ALL_STATES : Barcode_Prototipi : Prototipi # 64 ALL_STATES : HW_Power_Off : Macchina_Spenta # 14 diff --git a/StateMachineStati/Jetco/15_FAMIGLIA_JETCO_NEW.csv b/StateMachineStati/Jetco/15_FAMIGLIA_JETCO_NEW.csv index f67733d..1b8d90e 100644 --- a/StateMachineStati/Jetco/15_FAMIGLIA_JETCO_NEW.csv +++ b/StateMachineStati/Jetco/15_FAMIGLIA_JETCO_NEW.csv @@ -2,42 +2,56 @@ IdxFamiglia;IdxStato;IdxTipo;next_IdxStato 15;0;14;11 15;0;15;1 15;0;18;15 +15;0;30;29 15;0;44;39 15;0;45;38 15;0;46;37 15;1;0;0 15;1;14;11 15;1;18;15 +15;1;30;29 15;1;44;39 15;1;45;38 15;1;46;37 15;11;0;0 15;11;15;1 15;11;18;15 +15;11;30;29 15;11;44;39 15;11;45;38 15;11;46;37 15;15;0;0 15;15;14;11 15;15;15;1 +15;15;30;29 15;15;44;39 15;15;45;38 15;15;46;37 +15;29;0;0 +15;29;14;11 +15;29;15;1 +15;29;18;15 +15;29;44;39 +15;29;45;38 +15;29;46;37 15;37;0;0 15;37;14;11 15;37;15;1 15;37;18;15 +15;37;30;29 15;37;44;39 15;37;45;38 15;38;0;0 15;38;14;11 15;38;15;1 15;38;18;15 +15;38;30;29 15;38;44;39 15;38;46;37 15;39;0;0 15;39;14;11 15;39;15;1 15;39;18;15 +15;39;30;29 15;39;45;38 15;39;46;37 diff --git a/StateMachineStati/Jetco/15_FAMIGLIA_JETCO_NEW.rul b/StateMachineStati/Jetco/15_FAMIGLIA_JETCO_NEW.rul index 9c6eb6b..81efc79 100644 --- a/StateMachineStati/Jetco/15_FAMIGLIA_JETCO_NEW.rul +++ b/StateMachineStati/Jetco/15_FAMIGLIA_JETCO_NEW.rul @@ -7,6 +7,7 @@ # 2023.08.11 Nomi PowerOn # 2023.08.27 Sistemazione Descrizioni # 2024.03.27 Sistemazione allineamento e Intestazione +# 2025.11.25 Aggiunta Emergenza # $DEFINITIONS @@ -20,6 +21,7 @@ $STATE : 0 : ND $STATE : 1 : Macchina_Pronta $STATE : 11 : Macchina_Spenta $STATE : 15 : Allarme_CN +$STATE : 29 : Emergenza $STATE : 37 : Carico $STATE : 38 : Riserva $STATE : 39 : A_Vuoto @@ -30,6 +32,7 @@ $EVENT : 00 : EMPTY $EVENT : 14 : HW_Power_Off $EVENT : 15 : HW_Power_On $EVENT : 18 : HW_Error +$EVENT : 30 : HW_Emergenza $EVENT : 44 : HW_Warn_a_Vuoto $EVENT : 45 : HW_Warn_Riserva $EVENT : 46 : HW_Carico @@ -42,6 +45,7 @@ ALL_STATES : EMPTY : ND ALL_STATES : HW_Power_Off : Macchina_Spenta # 14 ALL_STATES : HW_Power_On : Macchina_Pronta # 15 ALL_STATES : HW_Error : Allarme_CN # 18 +ALL_STATES : HW_Emergenza : Emergenza # 21 ALL_STATES : HW_Warn_a_Vuoto : A_Vuoto # 44 in quella Originale andava a Riserva ALL_STATES : HW_Warn_Riserva : Riserva # 45 in quella Originale andava a A_Vuoto ALL_STATES : HW_Carico : Carico # 56