1.3.0, nuova gestione con vettori dei dati
This commit is contained in:
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"> 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"> Ferma Scrittura</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user