1.3.0, nuova gestione con vettori dei dati

This commit is contained in:
Marco Locatelli
2021-06-18 16:44:30 +02:00
parent 3a302fae04
commit eff044934c
5 changed files with 124 additions and 114 deletions
+9
View File
@@ -39,6 +39,7 @@ redSrv0.set(redWriteFreq,startingWriteFreq)
redisTime = 'RTDATA:TIME:SRV'
redSrv0.set('SETTINGS:LOG:STATUS',0)
redSrv0.set('SETTINGS:POWER:OFF',0)
redSrv0.set('SETTINGS:LOG:CRONO', "00:00:00")
if redSrv0.get('SETTINGS:LOG:WAITIME') is None:
redSrv0.set('SETTINGS:LOG:WAITIME', 2)
if redSrv0.get('SETTINGS:SELECTED_CH') is None:
@@ -88,16 +89,24 @@ def fileSave():
outFile.write(csvRow +"\r\n")
outFile.close()
#ciclo principale, salva time attuale e se LOG:STATUS è 1 fa fileSave()
while(1):
now = datetime.datetime.now()
# solo se su redis LOG è 1 eseguo il ciclo principale
if(getRedisVal('SETTINGS:LOG:STATUS') == "1"):
redSrv0.set('SETTINGS:LOG:CRONO', "00:00:00")
#attendo 2 secondi all'avvio della registrazione
if(getRedisVal('SETTINGS:LOG:WAITER') == "0"):
time.sleep(int(getRedisVal('SETTINGS:LOG:WAITIME')))
#salvo startTime per inizio cronometro registrazione
startTime = time.perf_counter()
#FTL.FTLog.Write("FTLogger: " + str(start_time))
redSrv0.set('SETTINGS:LOG:WAITER', 1)
fileSave()
#a ogni fileSave() misuro tempo trascorso da inizio registrazione e lo mostro
crono = time.strftime('%H:%M:%S', time.gmtime(int(time.perf_counter() - startTime)))
redSrv0.set('SETTINGS:LOG:CRONO',crono)
# riporto ultima esecuzione ad adesso
endExec = datetime.datetime.now()
# calcolo il delta dovuto alle esecuzioni
+74 -88
View File
@@ -1,5 +1,6 @@
#!/usr/bin/python
from array import *
import os
import math
import time
@@ -7,6 +8,7 @@ import datetime
import ADS1256
import redis
import FTL.FTLog
import numpy as np
FTL.FTLog.Write(" FTSampler started")
@@ -25,45 +27,15 @@ def getRedisVal(redisKey):
else:
return redSrv0.get(redisKey).decode('utf-8')
def echoList(redisKey, numVal):
currList = redSrv0.lrange(redisKey, 0, numVal)
currString = ''
for curVal in range(0,numVal,+1):
currString = currString + ' ' + str(curVal) + ': ' + str((float)(currList[curVal].decode('utf-8'))) + ' | '
print(currString)
def putRedisListVal(redisKey, value, maxLen):
#echoList(redisKey, maxLen)
redSrv0.lpush(redisKey, value)
# se supero lunghezza --> rimuovo
redSrv0.ltrim(redisKey, 0, maxLen)
#echoList(redisKey, maxLen)
def getRmsVal(redisKey, numVal):
# leggo lista da redis
currList = redSrv0.lrange(redisKey, 0, numVal)
numVal= len(currList)
sumSquare=0
# per ogni elemento calcolo quadrato
for curVal in range(0,numVal,+1):
sumSquare = sumSquare + (float)(currList[curVal].decode('utf-8'))*(float)(currList[curVal].decode('utf-8'))
# divido e faccio radice quadrata
rmsVal = math.sqrt(sumSquare / numVal)
return rmsVal
#intervallo in millisecondi fra un campionamento e il successivo
redSampleFreq = 'SETTINGS:LOG:FREQ'
redSrv0.set(redSampleFreq,100)
#definizioni variabili
redRmsList ='RTDATA:RMSLIST'
redSamPer='SETTINGS:LOG:EXETIME'
redSampleFreq = 'SETTINGS:LOG:FREQ'
#se non c'è un valore nei campi di redis, popolo il db
redSrv0.set('SETTINGS:LOG:STATUS',0)
redSrv0.set('SETTINGS:POWER:OFF',0)
if redSrv0.get('SETTINGS:LOG:FREQ') is None:
redSrv0.set('SETTINGS:LOG:FREQ', 50)
if redSrv0.get('SETTINGS:DECIMALS:COUNT') is None:
redSrv0.set('SETTINGS:DECIMALS:COUNT',1)
if redSrv0.get('RTDATA:VALUE:K1CONST') is None:
@@ -119,11 +91,27 @@ for numCh in range(0,8,+1):
if redSrv0.get('RTDATA:OUT:'+str(numCh)) is None:
redSrv0.set('RTDATA:OUT:'+str(numCh),1)
#funzione salva time+data di log e otto valori su redis
def redisSave(CHvalue):
decimalsCount = int(getRedisVal('SETTINGS:DECIMALS:COUNT'))
# calcola la media (colonna x colonna) dei valori ricevuti
def calcMean(dataArray):
outValues = [0.0] * 8
smoothFunction= int(getRedisVal('SETTINGS:SMOOTHING:FUNCTION'))
smoothFact= int(getRedisVal('SETTINGS:SMOOTHING:FACTOR'))
# verifico il TIPO di Smoothing richiesto: 0 none, 1 media semplice, 2 RMS
if (smoothFunction == 1):
# effettuo calcolo media mobile
outValues = np.sum(dataArray, axis=0) / smoothFact
elif (smoothFunction == 2):
# calcolo i quadrati
outValues = np.sqrt(np.sum(np.square(dataArray), axis=0) / smoothFact)
else:
# nessuno smooting, passa il primo dei sample acquisiti
outValues = dataArray[0]
# restituisco valori calcolati
return outValues
#funzione salva time+data di log e otto valori su redis
def redisSave(CHvalues):
decimalsCount = int(getRedisVal('SETTINGS:DECIMALS:COUNT'))
redLastLog = 'RTDATA:TIME:LOG'
dateFormat ="%d/%m/%Y %H:%M:%S"
rawLastLog = datetime.datetime.now()
@@ -132,30 +120,11 @@ def redisSave(CHvalue):
for chIndex in range(0,8,+1):
redAreaIn = 'RTDATA:CH:'+str(chIndex)
redAreaOut = 'RTDATA:OUT:'+str(chIndex)
redRmsArea = redRmsList+':'+str(chIndex)
innovazione = float("%.4f" % (CHvalue[chIndex]*5.0/0x7fffff))
strValIn = innovazione
# verifico il TIPO di Smoothing richiesto: 0 none, 1 EWMA, 2 RMS
if (smoothFunction == 1):
# EWMA: RILEGGO DA REDIS vecchio valore
oldVal = float(redSrv0.get(redAreaIn))
# effettuo smoothing valore
strValIn = (innovazione/smoothFact) + (oldVal * (smoothFact-1) / smoothFact)
elif (smoothFunction == 2):
# accodo innovazioni
putRedisListVal(redRmsArea, innovazione, smoothFact)
# calcolo valore RMS
strValIn = getRmsVal(redRmsArea, smoothFact)
else:
# nessuno smooting
strValIn = innovazione
strValIn = float("%.4f" % (CHvalues[chIndex]))
#salvo valore IN filtrato
redSrv0.set(redAreaIn,round(strValIn,8))
redSrv0.set(redAreaIn,round(strValIn,decimalsCount))
# salvo i valori scalati in OUT
roundedOut = round(scaleVal(CHvalue[chIndex]*5.0/0x7fffff, chIndex), decimalsCount)
roundedOut = round(scaleVal(CHvalues[chIndex], chIndex), decimalsCount)
redSrv0.set(redAreaOut,roundedOut)
#funzione di refresh valori scalati
@@ -207,9 +176,9 @@ def calculateValue():
k1 = getRedisVal('RTDATA:VALUE:K1CONST')
k2 = getRedisVal('RTDATA:VALUE:K2CONST')
offset = getRedisVal('RTDATA:VALUE:OFFSET')
den = (float(v1)-float(v2))
if(den < 0.001):
den = 0.001
den = abs(float(v1)-float(v2))
if(den < 0.01):
den = 0.01
XVal = (float(v2)/float(den))
newValue = (float(k1)*float(XVal)*float(XVal))+(float(k2)*float(XVal))+float(offset)
redSrv0.set('RTDATA:VALUE:REAL',round(newValue,decimalsCount))
@@ -225,38 +194,55 @@ def calculateValue():
strValIn = (newValue/eFact) + (oldVal * (eFact-1) / eFact)
redSrv0.set('RTDATA:VALUE:SMOOTHED',round(strValIn,decimalsCount))
# init oggetto lettura da
# init array
smoothFact= int(getRedisVal('SETTINGS:SMOOTHING:FACTOR'))
initArray = [0.0] * 8
meanValues = [0.0] * 8
dataBox = np.array([initArray] * smoothFact)
redisTime = 'RTDATA:TIME:SRV'
# init oggetto lettura Digital Analog
try:
CH = ADS1256.ADS1256()
CH.ADS1256_init()
#ciclo principale
while(1):
redisTime = 'RTDATA:TIME:SRV'
now = datetime.datetime.now()
dateFormat ="%d/%m/%Y %H:%M:%S"
lastLog = now.strftime(dateFormat)
redSrv0.set(redisTime,str(lastLog))
CHvalue = CH.ADS1256_GetAll()
# salvo valori
redisSave(CHvalue)
# controllo soglia spegnimento
checkPowerOff()
#calcolo il valore k*[V2/(V1-V2)] + offset
calculateValue()
# riporto ultima esecuzione ad adesso
endExec = datetime.datetime.now()
# calcolo il delta time dovuto alle esecuzioni
delta = endExec - now
redSrv0.set('SETTINGS:EXE:TIME',str(delta))
oldSPeriod=float(getRedisVal(redSamPer))
newSPeriod=0.5*oldSPeriod+0.5*(float(delta.microseconds/1000))
redSrv0.set(redSamPer,newSPeriod)
waitTime = int(getRedisVal(redSampleFreq)) / 1000 - delta.microseconds/1000000
if(waitTime < 0.01):
waitTime = 0.01
# attesa
time.sleep(waitTime)
# update freq campionamento da redis
sampleFreq = getRedisVal(redSampleFreq)
smoothFact= int(getRedisVal('SETTINGS:SMOOTHING:FACTOR'))
dataBox = np.array([initArray] * smoothFact)
for counter in range(0,smoothFact,+1):
now = datetime.datetime.now()
dateFormat ="%d/%m/%Y %H:%M:%S"
lastLog = now.strftime(dateFormat)
redSrv0.set(redisTime,str(lastLog))
# leggo gli 8 valori
CHvalue = CH.ADS1256_GetAll()
floatArray = np.array(CHvalue, dtype=np.float)
dataBox[counter] = floatArray*float(5.0/0x7fffff)
# calcolo e scrittura ogni NUM PERIOD cicli
if counter == (smoothFact-1):
# faccio gli smoothing colonna x colonna
meanValues = calcMean(dataBox)
#salvo valori
redisSave(meanValues)
# controllo soglia spegnimento
checkPowerOff()
# calcolo il valore k*[V2/(V1-V2)] + offset
calculateValue()
# riporto ultima esecuzione ad adesso
endExec = datetime.datetime.now()
# calcolo il delta time dovuto alle esecuzioni
delta = endExec - now
# attesa viene fatta sempre
waitTime = int(sampleFreq) / 1000 - delta.microseconds/1000000
if(waitTime < 0.01):
#FTL.FTLog.Write("delta: " + str(delta.microseconds/1000) + " | wait: " + str(waitTime*1000))
waitTime = 0.01
#FTL.FTLog.Write("delta: " + str(delta.microseconds/1000) + " | wait: " + str(waitTime*1000))
# vera attesa
time.sleep(waitTime)
#eccezione da ctrl+c in terminale e chiusura
except KeyboardInterrupt:
+4 -2
View File
@@ -17,6 +17,7 @@ import logging
FTL.FTLog.Write(" FTServer started")
#silenzio i logger
logging.getLogger('werkzeug').disabled = True
os.environ['WERKZEUG_RUN_MAIN'] = 'true'
@@ -123,7 +124,8 @@ def api_channels_all():
'SelPowerChannel' : getRedisVal('SETTINGS:POWER:CH'),
'SelProcessing' : getRedisVal('SETTINGS:SMOOTHING:FUNCTION'),
'ResultValue' : getRedisVal('RTDATA:VALUE:SMOOTHED'),
'RealValue' : getRedisVal('RTDATA:VALUE:REAL')
'RealValue' : getRedisVal('RTDATA:VALUE:REAL'),
'Crono' : getRedisVal('SETTINGS:LOG:CRONO')
}
# restituisce in formato json i dati letti da redis
return jsonify(channelsData)
@@ -497,5 +499,5 @@ def FTShutdown():
#dichiaro host ipv4 (ottenuto sopra utilizzando il modulo socket)
if __name__ == "__main__":
FTL.FTLog.Write(" FTServer starting Flask Host!")
FTL.FTLog.Write(" FTServer starting Flask Hosting!")
flaskApp.run(host=ipv4, port=80, debug=True)
+1 -1
View File
@@ -29,7 +29,7 @@
<br>
Software di lettura e scrittura per canali analogici e digitali
<br>
V 1.2.1
V 1.3.0
</div>
</div>
</main>
+36 -23
View File
@@ -44,6 +44,7 @@
$("#CurrentFolder").html(result.CurrentWorkFolder);
$("#ResultValue").html(result.ResultValue);
$("#RealValue").html(result.RealValue);
$("#Crono").html(result.Crono);
if(result.GateOpen == "0")
{
@@ -304,9 +305,9 @@
</div>
<div class="row my-2">
<div class="col-12 col-xl-6">
<div class="row my-2">
<div class="row mb-2">
<div class="col-6 pr-0">
<div class="card text-center">
<div class="card text-center mr-1">
<div class="card-header">
<strong>Canale A: <span id="SelChannelA"></span></strong>
</div>
@@ -314,15 +315,15 @@
<div id="divChA"></div>
<div class="row">
<div class="col-12">
<span class="h3" id="OutputA"></span>
<span class="h3" id="UniMisuA"></span>
<span class="h4" id="OutputA"></span>
<span class="h4" id="UniMisuA"></span>
</div>
</div>
</div>
</div>
</div>
<div class="col-6 pl-0">
<div class="card text-center">
<div class="card text-center ml-1">
<div class="card-header">
<strong>Canale B: <span id="SelChannelB"></span></strong>
</div>
@@ -330,41 +331,53 @@
<div id="divChB"></div>
<div class="row">
<div class="col-12">
<span class="h3" id="OutputB"></span>
<span class="h3" id="UniMisuB"></span>
<span class="h4" id="OutputB"></span>
<span class="h4" id="UniMisuB"></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card text-center">
<div class="card-header">
<strong>Risultante = k*[B/(A-B)]+offset </strong>
</div>
<div class="card-body">
<div class="row">
<div class="col-6">
<strong>Istant: </strong><span class="h4" id="RealValue"></span>
<span class="h4" id="CalcMeasure1"></span>
</div>
<div class="col-6">
<strong>Media: </strong><span class="h4" id="ResultValue"></span>
<span class="h4" id="CalcMeasure2"></span>
<div class="card text-center">
<div class="card-header text-center">
<div class="row">
<div class="col-3"></div>
<div class="col-6">
<strong>Risultante B/(A-B) </strong>
</div>
<div class="col-3"></div>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-1"></div>
<div class="col-5">
<strong>Istant: </strong><span class="h5" id="RealValue"></span>
<span class="h5" id="CalcMeasure1"></span>
</div>
<div class="col-5">
<strong>Media: </strong><span class="h5" id="ResultValue"></span>
<span class="h5" id="CalcMeasure2"></span>
</div>
<div class="col-1"></div>
</div>
</div>
</div>
</div>
</div>
<div class="col-12 col-xl-6">
<div class="card my-2">
<div id="Div7" class="card-header">
<div class="row">
<div class="col-6">
<div class="col-5">
<button id="btnStart" type="button" class="btn btn-success btn-block" style="font-size: 110%" onclick="startLog()">
<img src="../static/img/play-fill.svg" height="24" width="24">&nbsp; Inizia Scrittura</button>
</div>
<div class="col-6">
<div class="col-2 badge badge-dark text-light text-center">
<em><span class="h5" id="Crono"></span></em>
</div>
<div class="col-5">
<button id="btnStop" type="button" class="btn btn-danger btn-block" style="font-size: 110%" onclick="stopLog()">
<img src="../static/img/stop-fill.svg" height="24" width="24">&nbsp; Ferma Scrittura</button>
</div>