abbozzata gestione gauge
This commit is contained in:
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1,178 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import time
|
||||
import datetime
|
||||
import ADS1256
|
||||
import RPi.GPIO as GPIO
|
||||
import redis
|
||||
|
||||
#configurazione per lavorare su server redis locale
|
||||
REDIS_PORT = 6379
|
||||
REDIS_HOST = '127.0.0.1'
|
||||
redSrv0 = redis.Redis(
|
||||
host=REDIS_HOST,
|
||||
port=REDIS_PORT,
|
||||
db=0)
|
||||
|
||||
#funzione per leggere e decodificare da redis
|
||||
def getRedisVal(redisKey):
|
||||
return redSrv0.get(redisKey).decode('utf-8')
|
||||
|
||||
|
||||
redSrv0.set('SETTINGS:LOG:STATUS',0)
|
||||
|
||||
#se non c'è un valore nei campi di redis, popolo il db
|
||||
|
||||
LOG_path = "/home/pi/Flythis/logger/log/"
|
||||
DATA_path = "/home/pi/data/"
|
||||
|
||||
if redSrv0.get('SETTINGS:SELECTED_CH') is None:
|
||||
redSrv0.set('SETTINGS:SELECTED_CH',0)
|
||||
|
||||
for numCh in range(0,8,+1):
|
||||
|
||||
if redSrv0.get('SETTINGS:IN:MAX:'+str(numCh)) is None:
|
||||
redSrv0.set('SETTINGS:IN:MAX:'+str(numCh),100)
|
||||
|
||||
if redSrv0.get('SETTINGS:IN:MIN:'+str(numCh)) is None:
|
||||
redSrv0.set('SETTINGS:IN:MIN:'+str(numCh),0)
|
||||
|
||||
if redSrv0.get('SETTINGS:OUT:MAX:'+str(numCh)) is None:
|
||||
redSrv0.set('SETTINGS:OUT:MAX:'+str(numCh),100)
|
||||
|
||||
if redSrv0.get('SETTINGS:OUT:MIN:'+str(numCh)) is None:
|
||||
redSrv0.set('SETTINGS:OUT:MIN:'+str(numCh),0)
|
||||
|
||||
#intervallo in millisecondi fra un campionamento e il successivo
|
||||
redSampleFreq = 'SETTINGS:LOG:FREQ'
|
||||
startingFreq = 1000
|
||||
redSrv0.set(redSampleFreq,startingFreq)
|
||||
|
||||
try:
|
||||
CH = ADS1256.ADS1256()
|
||||
CH.ADS1256_init()
|
||||
|
||||
#funzione stampa otto valori letti su terminale
|
||||
def videoPrint(CHvalue):
|
||||
for chIndex in range(0,8,+1):
|
||||
print("CH "+str(chIndex)+"= %lf"%(CHvalue[chIndex]*5.0/0x7fffff))
|
||||
|
||||
#funzione salva time+data e otto valori letti su file (SE LOG è 1)
|
||||
def fileSave():
|
||||
csvDataFormat = "%d/%m/%Y %H:%M:%S"
|
||||
dataFileName = getRedisVal('RTDATA:SESSION:NAME')
|
||||
rawLastLog = datetime.datetime.now()
|
||||
lastLog = rawLastLog.strftime(csvDataFormat)
|
||||
try:
|
||||
outFile = open(DATA_path+"/"+dataFileName, "a")
|
||||
except FileNotFoundError:
|
||||
print("Creating new data.csv")
|
||||
outFile = open(DATA_path+"/"+dataFileName, "w+")
|
||||
outFile.write("# LOG started at " + str(lastLog))
|
||||
|
||||
# dichiaro una stringa in cui accumulo i valori
|
||||
csvRow = str(lastLog) +","
|
||||
for chIndex in range(0,2,+1):
|
||||
channelOut = getRedisVal('RTDATA:OUT:'+str(chIndex))
|
||||
csvRow += channelOut+","
|
||||
|
||||
# tolgo ultimo ","
|
||||
l = len(csvRow)
|
||||
csvRow = csvRow[:l-1]
|
||||
# scrivo in blocco la riga dei valori
|
||||
outFile.write(csvRow +"\r\n")
|
||||
outFile.close()
|
||||
|
||||
#funzione salva time+data di log e otto valori su redis
|
||||
def redisSave(CHvalue):
|
||||
redLastLog = 'RTDATA:TIME:LOG'
|
||||
lastLog = datetime.datetime.now()
|
||||
redSrv0.set(redLastLog,str(lastLog))
|
||||
for chIndex in range(0,8,+1):
|
||||
redAreaIn = 'RTDATA:CH:'+str(chIndex)
|
||||
redAreaOut = 'RTDATA:OUT:'+str(chIndex)
|
||||
strValIn = "%.4f" % (CHvalue[chIndex]*5.0/0x7fffff)
|
||||
redSrv0.set(redAreaIn,strValIn)
|
||||
# salvo i valori scalati in OUT
|
||||
strValOut = "%.4f" % scaleVal(CHvalue[chIndex]*5.0/0x7fffff, chIndex)
|
||||
redSrv0.set(redAreaOut,strValOut)
|
||||
|
||||
#funzione di refresh valori scalati
|
||||
def scaleVal(inValue, chIndex):
|
||||
#rileggo da redis i valori min/max secondo chIndex
|
||||
chInMin = float(0)
|
||||
if (redSrv0.get('SETTINGS:IN:MIN:'+str(chIndex)) != 0):
|
||||
chInMin = float(redSrv0.get('SETTINGS:IN:MIN:'+str(chIndex)))
|
||||
|
||||
chInMax = float(3.3)
|
||||
if (redSrv0.get('SETTINGS:IN:MAX:'+str(chIndex)) != 100):
|
||||
chInMax = float(redSrv0.get('SETTINGS:IN:MAX:'+str(chIndex)))
|
||||
|
||||
chOutMin = float(0)
|
||||
if (redSrv0.get('SETTINGS:OUT:MIN:'+str(chIndex)) != 0):
|
||||
chOutMin = float(redSrv0.get('SETTINGS:OUT:MIN:'+str(chIndex)))
|
||||
|
||||
chOutMax = float(1000)
|
||||
if (redSrv0.get('SETTINGS:OUT:MAX:'+str(chIndex)) != 100):
|
||||
chOutMax = float(redSrv0.get('SETTINGS:OUT:MAX:'+str(chIndex)))
|
||||
|
||||
# check denom zero
|
||||
deltaOut = (chOutMax - chOutMin)
|
||||
deltaIn = (chInMax - chInMin)
|
||||
if(deltaIn==0):
|
||||
deltaIn = 1
|
||||
|
||||
# calcolo scalato
|
||||
outVal = chOutMin + ((inValue-chInMin) * (deltaOut / deltaIn))
|
||||
|
||||
return outVal
|
||||
|
||||
#ciclo principale, salva time attuale e se LOG:STATUS è 1 fa il ciclo principale
|
||||
while(1):
|
||||
redTime = 'RTDATA:TIME:SRV'
|
||||
now = datetime.datetime.now()
|
||||
redSrv0.set(redTime,str(now))
|
||||
#print(logStatus)
|
||||
# solo se su redis LOG è 1 eseguo il ciclo principale
|
||||
CHvalue = CH.ADS1256_GetAll()
|
||||
#videoPrint(CHvalue)
|
||||
if(getRedisVal('SETTINGS:LOG:STATUS') == "1"):
|
||||
fileSave()
|
||||
redisSave(CHvalue)
|
||||
# riporto ultima esecuzione ad adesso
|
||||
endExec = datetime.datetime.now()
|
||||
# calcolo il delta dovuto alle esecuzioni
|
||||
delta = endExec - now
|
||||
waitTime = int(redSrv0.get(redSampleFreq)) / 1000 - delta.microseconds/1000000
|
||||
if(waitTime < 0.1):
|
||||
waitTime = 0.1
|
||||
# attesa
|
||||
time.sleep(waitTime)
|
||||
|
||||
#eccezione da ctrl+c in terminale e chiusura
|
||||
except KeyboardInterrupt:
|
||||
GPIO.cleanup()
|
||||
lastLog = datetime.datetime.now()
|
||||
print (str(lastLog)+" Program End. Ctrl+C from user\r\n")
|
||||
try:
|
||||
logFile = open(LOG_path+"PyLog.txt", "a")
|
||||
except FileNotFoundError:
|
||||
print("Creating new PyLog.txt")
|
||||
logFile = open(LOG_path+"PyLog.txt", "w+")
|
||||
logFile.write(str(lastLog)+" Program end. Ctrl+C from user\r\n")
|
||||
logFile.close()
|
||||
exit()
|
||||
|
||||
#eccezione da errore e chiusura
|
||||
except Exception as errorMessage:
|
||||
GPIO.cleanup()
|
||||
lastLog = datetime.datetime.now()
|
||||
print(str(lastLog)+" Caught error " + str(errorMessage)+"\r\n")
|
||||
try:
|
||||
logFile = open(LOG_path+"PyLog.txt", "a")
|
||||
except FileNotFoundError:
|
||||
print("Creating new PyLog.txt")
|
||||
logFile = open(LOG_path+"PyLog.txt", "w+")
|
||||
logFile.write(str(lastLog)+" Caught error: "+str(errorMessage)+"\r\n")
|
||||
logFile.close()
|
||||
exit()
|
||||
@@ -1,178 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import time
|
||||
import datetime
|
||||
import ADS1256
|
||||
import RPi.GPIO as GPIO
|
||||
import redis
|
||||
|
||||
#configurazione per lavorare su server redis locale
|
||||
REDIS_PORT = 6379
|
||||
REDIS_HOST = '127.0.0.1'
|
||||
redSrv0 = redis.Redis(
|
||||
host=REDIS_HOST,
|
||||
port=REDIS_PORT,
|
||||
db=0)
|
||||
|
||||
#funzione per leggere e decodificare da redis
|
||||
def getRedisVal(redisKey):
|
||||
return redSrv0.get(redisKey).decode('utf-8')
|
||||
|
||||
|
||||
redSrv0.set('SETTINGS:LOG:STATUS',0)
|
||||
|
||||
#se non c'è un valore nei campi di redis, popolo il db
|
||||
|
||||
LOG_path = "/home/pi/Flythis/logger/log/"
|
||||
DATA_path = "/home/pi/data/"
|
||||
|
||||
if redSrv0.get('SETTINGS:SELECTED_CH') is None:
|
||||
redSrv0.set('SETTINGS:SELECTED_CH',0)
|
||||
|
||||
for numCh in range(0,8,+1):
|
||||
|
||||
if redSrv0.get('SETTINGS:IN:MAX:'+str(numCh)) is None:
|
||||
redSrv0.set('SETTINGS:IN:MAX:'+str(numCh),100)
|
||||
|
||||
if redSrv0.get('SETTINGS:IN:MIN:'+str(numCh)) is None:
|
||||
redSrv0.set('SETTINGS:IN:MIN:'+str(numCh),0)
|
||||
|
||||
if redSrv0.get('SETTINGS:OUT:MAX:'+str(numCh)) is None:
|
||||
redSrv0.set('SETTINGS:OUT:MAX:'+str(numCh),100)
|
||||
|
||||
if redSrv0.get('SETTINGS:OUT:MIN:'+str(numCh)) is None:
|
||||
redSrv0.set('SETTINGS:OUT:MIN:'+str(numCh),0)
|
||||
|
||||
#intervallo in millisecondi fra un campionamento e il successivo
|
||||
redSampleFreq = 'SETTINGS:LOG:FREQ'
|
||||
startingFreq = 1000
|
||||
redSrv0.set(redSampleFreq,startingFreq)
|
||||
|
||||
try:
|
||||
CH = ADS1256.ADS1256()
|
||||
CH.ADS1256_init()
|
||||
|
||||
#funzione stampa otto valori letti su terminale
|
||||
def videoPrint(CHvalue):
|
||||
for chIndex in range(0,8,+1):
|
||||
print("CH "+str(chIndex)+"= %lf"%(CHvalue[chIndex]*5.0/0x7fffff))
|
||||
|
||||
#funzione salva time+data e otto valori letti su file (SE LOG è 1)
|
||||
def fileSave():
|
||||
csvDataFormat = "%d/%m/%Y %H:%M:%S"
|
||||
dataFileName = getRedisVal('RTDATA:SESSION:NAME')
|
||||
rawLastLog = datetime.datetime.now()
|
||||
lastLog = rawLastLog.strftime(csvDataFormat)
|
||||
try:
|
||||
outFile = open(DATA_path+"/"+dataFileName, "a")
|
||||
except FileNotFoundError:
|
||||
print("Creating new data.csv")
|
||||
outFile = open(DATA_path+"/"+dataFileName, "w+")
|
||||
outFile.write("# LOG started at " + str(lastLog))
|
||||
|
||||
# dichiaro una stringa in cui accumulo i valori
|
||||
csvRow = str(lastLog) +","
|
||||
for chIndex in range(0,2,+1):
|
||||
channelOut = getRedisVal('RTDATA:OUT:'+str(chIndex))
|
||||
csvRow += channelOut+","
|
||||
|
||||
# tolgo ultimo ","
|
||||
l = len(csvRow)
|
||||
csvRow = csvRow[:l-1]
|
||||
# scrivo in blocco la riga dei valori
|
||||
outFile.write(csvRow +"\r\n")
|
||||
outFile.close()
|
||||
|
||||
#funzione salva time+data di log e otto valori su redis
|
||||
def redisSave(CHvalue):
|
||||
redLastLog = 'RTDATA:TIME:LOG'
|
||||
lastLog = datetime.datetime.now()
|
||||
redSrv0.set(redLastLog,str(lastLog))
|
||||
for chIndex in range(0,8,+1):
|
||||
redAreaIn = 'RTDATA:CH:'+str(chIndex)
|
||||
redAreaOut = 'RTDATA:OUT:'+str(chIndex)
|
||||
strValIn = "%.4f" % (CHvalue[chIndex]*5.0/0x7fffff)
|
||||
redSrv0.set(redAreaIn,strValIn)
|
||||
# salvo i valori scalati in OUT
|
||||
strValOut = "%.4f" % scaleVal(CHvalue[chIndex]*5.0/0x7fffff, chIndex)
|
||||
redSrv0.set(redAreaOut,strValOut)
|
||||
|
||||
#funzione di refresh valori scalati
|
||||
def scaleVal(inValue, chIndex):
|
||||
#rileggo da redis i valori min/max secondo chIndex
|
||||
chInMin = float(0)
|
||||
if (redSrv0.get('SETTINGS:IN:MIN:'+str(chIndex)) != 0):
|
||||
chInMin = float(redSrv0.get('SETTINGS:IN:MIN:'+str(chIndex)))
|
||||
|
||||
chInMax = float(3.3)
|
||||
if (redSrv0.get('SETTINGS:IN:MAX:'+str(chIndex)) != 100):
|
||||
chInMax = float(redSrv0.get('SETTINGS:IN:MAX:'+str(chIndex)))
|
||||
|
||||
chOutMin = float(0)
|
||||
if (redSrv0.get('SETTINGS:OUT:MIN:'+str(chIndex)) != 0):
|
||||
chOutMin = float(redSrv0.get('SETTINGS:OUT:MIN:'+str(chIndex)))
|
||||
|
||||
chOutMax = float(1000)
|
||||
if (redSrv0.get('SETTINGS:OUT:MAX:'+str(chIndex)) != 100):
|
||||
chOutMax = float(redSrv0.get('SETTINGS:OUT:MAX:'+str(chIndex)))
|
||||
|
||||
# check denom zero
|
||||
deltaOut = (chOutMax - chOutMin)
|
||||
deltaIn = (chInMax - chInMin)
|
||||
if(deltaIn==0):
|
||||
deltaIn = 1
|
||||
|
||||
# calcolo scalato
|
||||
outVal = chOutMin + ((inValue-chInMin) * (deltaOut / deltaIn))
|
||||
|
||||
return outVal
|
||||
|
||||
#ciclo principale, salva time attuale e se LOG:STATUS è 1 fa il ciclo principale
|
||||
while(1):
|
||||
redTime = 'RTDATA:TIME:SRV'
|
||||
now = datetime.datetime.now()
|
||||
redSrv0.set(redTime,str(now))
|
||||
#print(logStatus)
|
||||
# solo se su redis LOG è 1 eseguo il ciclo principale
|
||||
CHvalue = CH.ADS1256_GetAll()
|
||||
#videoPrint(CHvalue)
|
||||
if(getRedisVal('SETTINGS:LOG:STATUS') == "1"):
|
||||
fileSave()
|
||||
redisSave(CHvalue)
|
||||
# riporto ultima esecuzione ad adesso
|
||||
endExec = datetime.datetime.now()
|
||||
# calcolo il delta dovuto alle esecuzioni
|
||||
delta = endExec - now
|
||||
waitTime = int(redSrv0.get(redSampleFreq)) / 1000 - delta.microseconds/1000000
|
||||
if(waitTime < 0.1):
|
||||
waitTime = 0.1
|
||||
# attesa
|
||||
time.sleep(waitTime)
|
||||
|
||||
#eccezione da ctrl+c in terminale e chiusura
|
||||
except KeyboardInterrupt:
|
||||
GPIO.cleanup()
|
||||
lastLog = datetime.datetime.now()
|
||||
print (str(lastLog)+" Program End. Ctrl+C from user\r\n")
|
||||
try:
|
||||
logFile = open(LOG_path+"PyLog.txt", "a")
|
||||
except FileNotFoundError:
|
||||
print("Creating new PyLog.txt")
|
||||
logFile = open(LOG_path+"PyLog.txt", "w+")
|
||||
logFile.write(str(lastLog)+" Program end. Ctrl+C from user\r\n")
|
||||
logFile.close()
|
||||
exit()
|
||||
|
||||
#eccezione da errore e chiusura
|
||||
except Exception as errorMessage:
|
||||
GPIO.cleanup()
|
||||
lastLog = datetime.datetime.now()
|
||||
print(str(lastLog)+" Caught error " + str(errorMessage)+"\r\n")
|
||||
try:
|
||||
logFile = open(LOG_path+"PyLog.txt", "a")
|
||||
except FileNotFoundError:
|
||||
print("Creating new PyLog.txt")
|
||||
logFile = open(LOG_path+"PyLog.txt", "w+")
|
||||
logFile.write(str(lastLog)+" Caught error: "+str(errorMessage)+"\r\n")
|
||||
logFile.close()
|
||||
exit()
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
FTLogger.py
|
||||
@@ -58,3 +58,6 @@
|
||||
2021-03-30 11:46:56.641430 Program end. Ctrl+C from user
|
||||
2021-03-30 14:19:38.149124 Program end. Ctrl+C from user
|
||||
2021-03-30 14:20:54.350302 Program end. Ctrl+C from user
|
||||
2021-03-30 22:03:03.117436 Program end. Ctrl+C from user
|
||||
2021-03-30 22:12:28.454778 Program end. Ctrl+C from user
|
||||
2021-03-30 22:13:02.315239 Program end. Ctrl+C from user
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
from flask import Flask, render_template, jsonify, request
|
||||
from datetime import datetime
|
||||
from flask.wrappers import Request
|
||||
import redis
|
||||
import socket
|
||||
import os
|
||||
from werkzeug.utils import redirect
|
||||
|
||||
#create a socket object
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
|
||||
#connect to the server on local computer
|
||||
s.connect(("8.8.8.8", 80))
|
||||
|
||||
#assegno a variabile indirizzo ip per usi futuri
|
||||
ipv4 = s.getsockname()[0]
|
||||
s.close()
|
||||
|
||||
#volendo stampo a video IPv4
|
||||
#print("Indirizzo Ipv4 assegnato: ",s.getsockname()[0])
|
||||
|
||||
#configurazione per lavorare su server redis locale
|
||||
REDIS_PORT = 6379
|
||||
REDIS_HOST = '127.0.0.1'
|
||||
redSrv0 = redis.Redis(
|
||||
host=REDIS_HOST,
|
||||
port=REDIS_PORT,
|
||||
db=0)
|
||||
|
||||
#funzione per leggere e decodificare da redis
|
||||
def getRedisVal(redisKey):
|
||||
return redSrv0.get(redisKey).decode('utf-8')
|
||||
|
||||
flaskApp = Flask(__name__)
|
||||
@flaskApp.route("/")
|
||||
#funzione main: passa al template home il titolo
|
||||
def main():
|
||||
channelsData = {
|
||||
'title' : 'Home'
|
||||
}
|
||||
#assegno il template html di riferimento
|
||||
return render_template('home.html', **channelsData)
|
||||
|
||||
@flaskApp.route("/logger")
|
||||
#funzione logger, route a pagina /logger
|
||||
def logger():
|
||||
channelsData = {
|
||||
'title' : 'Logger',
|
||||
'timeSrv' : getRedisVal('RTDATA:TIME:SRV'),
|
||||
'timeLog' : getRedisVal('RTDATA:TIME:LOG'),
|
||||
'Freq' : getRedisVal('SETTINGS:LOG:FREQ'),
|
||||
'Ch0' : getRedisVal('RTDATA:CH:0'),
|
||||
'Ch1' : getRedisVal('RTDATA:CH:1'),
|
||||
'Ch2' : getRedisVal('RTDATA:CH:2'),
|
||||
'Ch3' : getRedisVal('RTDATA:CH:3'),
|
||||
'Ch4' : getRedisVal('RTDATA:CH:4'),
|
||||
'Ch5' : getRedisVal('RTDATA:CH:5'),
|
||||
'Ch6' : getRedisVal('RTDATA:CH:6'),
|
||||
'Ch7' : getRedisVal('RTDATA:CH:7'),
|
||||
'Out0' : getRedisVal('RTDATA:OUT:0'),
|
||||
'Out1' : getRedisVal('RTDATA:OUT:1'),
|
||||
'Out2' : getRedisVal('RTDATA:OUT:2'),
|
||||
'Out3' : getRedisVal('RTDATA:OUT:3'),
|
||||
'Out4' : getRedisVal('RTDATA:OUT:4'),
|
||||
'Out5' : getRedisVal('RTDATA:OUT:5'),
|
||||
'Out6' : getRedisVal('RTDATA:OUT:6'),
|
||||
'Out7' : getRedisVal('RTDATA:OUT:7')
|
||||
}
|
||||
#assegno il template html di riferimento
|
||||
return render_template('logger.html', **channelsData)
|
||||
|
||||
@flaskApp.route("/settings")
|
||||
#funzione setup, route a pagina /setup
|
||||
def setup():
|
||||
channelsData = {
|
||||
'title' : 'Settings',
|
||||
'Freq' : getRedisVal('SETTINGS:LOG:FREQ'),
|
||||
'Ch0' : getRedisVal('RTDATA:CH:0'),
|
||||
'Ch1' : getRedisVal('RTDATA:CH:1'),
|
||||
'Ch2' : getRedisVal('RTDATA:CH:2'),
|
||||
'Ch3' : getRedisVal('RTDATA:CH:3'),
|
||||
'Ch4' : getRedisVal('RTDATA:CH:4'),
|
||||
'Ch5' : getRedisVal('RTDATA:CH:5'),
|
||||
'Ch6' : getRedisVal('RTDATA:CH:6'),
|
||||
'Ch7' : getRedisVal('RTDATA:CH:7'),
|
||||
'Out0' : getRedisVal('RTDATA:OUT:0'),
|
||||
'Out1' : getRedisVal('RTDATA:OUT:1'),
|
||||
'Out2' : getRedisVal('RTDATA:OUT:2'),
|
||||
'Out3' : getRedisVal('RTDATA:OUT:3'),
|
||||
'Out4' : getRedisVal('RTDATA:OUT:4'),
|
||||
'Out5' : getRedisVal('RTDATA:OUT:5'),
|
||||
'Out6' : getRedisVal('RTDATA:OUT:6'),
|
||||
'Out7' : getRedisVal('RTDATA:OUT:7')
|
||||
}
|
||||
#assegno il template html di riferimento
|
||||
return render_template('settings.html', **channelsData)
|
||||
|
||||
@flaskApp.route("/about")
|
||||
#funzione about, route a pagina /about
|
||||
def about():
|
||||
channelsData = {
|
||||
'title' : 'About'
|
||||
}
|
||||
#assegno il template html di riferimento
|
||||
return render_template('about.html', **channelsData)
|
||||
|
||||
# definisco una NUOVA route a cui rispondere su chiamta in metodo GET x restituire dati aggiornati
|
||||
@flaskApp.route("/api/v1/channels/all", methods=['GET'])
|
||||
def api_channels_all():
|
||||
numCh = getRedisVal('SETTINGS:SELECTED_CH')
|
||||
#funzione api_channels_all: legge direttamente da redis, ritorna jsonify
|
||||
channelsData = {
|
||||
'timeSrv' : getRedisVal('RTDATA:TIME:SRV'),
|
||||
'timeLog' : getRedisVal('RTDATA:TIME:LOG'),
|
||||
'Freq' : getRedisVal('SETTINGS:LOG:FREQ'),
|
||||
'Ch0' : getRedisVal('RTDATA:CH:0'),
|
||||
'Ch1' : getRedisVal('RTDATA:CH:1'),
|
||||
'Ch2' : getRedisVal('RTDATA:CH:2'),
|
||||
'Ch3' : getRedisVal('RTDATA:CH:3'),
|
||||
'Ch4' : getRedisVal('RTDATA:CH:4'),
|
||||
'Ch5' : getRedisVal('RTDATA:CH:5'),
|
||||
'Ch6' : getRedisVal('RTDATA:CH:6'),
|
||||
'Ch7' : getRedisVal('RTDATA:CH:7'),
|
||||
'Out0' : getRedisVal('RTDATA:OUT:0'),
|
||||
'Out1' : getRedisVal('RTDATA:OUT:1'),
|
||||
'Out2' : getRedisVal('RTDATA:OUT:2'),
|
||||
'Out3' : getRedisVal('RTDATA:OUT:3'),
|
||||
'Out4' : getRedisVal('RTDATA:OUT:4'),
|
||||
'Out5' : getRedisVal('RTDATA:OUT:5'),
|
||||
'Out6' : getRedisVal('RTDATA:OUT:6'),
|
||||
'Out7' : getRedisVal('RTDATA:OUT:7'),
|
||||
'ChScaleMax' : getRedisVal('SETTINGS:IN:MAX:'+str(numCh)),
|
||||
'ChScaleMin' : getRedisVal('SETTINGS:IN:MIN:'+str(numCh)),
|
||||
'ChRealMax' : getRedisVal('SETTINGS:OUT:MAX:'+str(numCh)),
|
||||
'ChRealMin' : getRedisVal('SETTINGS:OUT:MIN:'+str(numCh)),
|
||||
'LastSessionName' : getRedisVal('RTDATA:SESSION:NAME')
|
||||
}
|
||||
# restituisce in formato json i dati letti da redis
|
||||
return jsonify(channelsData)
|
||||
|
||||
# definisco una NUOVA route a cui rispondere su chiamta in metodo GET x restituire dati aggiornati
|
||||
@flaskApp.route("/api/v1/channels/current", methods=['GET'])
|
||||
def api_channels_current():
|
||||
numCh = getRedisVal('SETTINGS:SELECTED_CH')
|
||||
#funzione api_channels_all: legge direttamente da redis, ritorna jsonify
|
||||
result = {
|
||||
'numCh' : numCh,
|
||||
'timeSrv' : getRedisVal('RTDATA:TIME:SRV'),
|
||||
'timeLog' : getRedisVal('RTDATA:TIME:LOG'),
|
||||
'Freq' : getRedisVal('SETTINGS:LOG:FREQ'),
|
||||
'CurrIn' : getRedisVal('RTDATA:CH:'+str(numCh)),
|
||||
'CurrOut' : getRedisVal('RTDATA:OUT:'+str(numCh)),
|
||||
'MaxOut' : getRedisVal('SETTINGS:OUT:MAX:'+str(numCh)),
|
||||
'MinOut' : getRedisVal('SETTINGS:OUT:MIN:'+str(numCh)),
|
||||
'MaxIn' : getRedisVal('SETTINGS:IN:MAX:'+str(numCh)),
|
||||
'MinIn' : getRedisVal('SETTINGS:IN:MIN:'+str(numCh))
|
||||
}
|
||||
# restituisce in formato json i dati letti da redis
|
||||
return jsonify(result)
|
||||
|
||||
# elenco file nella directory
|
||||
@flaskApp.route("/api/v1/files/list", methods=['GET'])
|
||||
def api_get_files():
|
||||
dataDir='/home/pi/data/'
|
||||
fileList = os.listdir(dataDir)
|
||||
result = {}
|
||||
for item in fileList:
|
||||
result[item]=os.path.getsize(dataDir+item)
|
||||
return jsonify(result)
|
||||
|
||||
# Route di comando x LOG: start e stop
|
||||
@flaskApp.route("/api/v1/log/start", methods=['PUT'])
|
||||
def start_log():
|
||||
#funzione start_log: scrive su redis LOG:STATUS -> 1
|
||||
redSrv0.set('SETTINGS:LOG:STATUS', 1)
|
||||
#data e time ora
|
||||
lastDate = datetime.now()
|
||||
#formato per data e time: dd/mm/YYYY H:M:S
|
||||
format = "%Y%m%d_%H%M%S"
|
||||
#format date e time adando strftime()
|
||||
nameDate = lastDate.strftime(format) + ".csv"
|
||||
redSrv0.set('RTDATA:SESSION:NAME', nameDate)
|
||||
return "OK"
|
||||
|
||||
@flaskApp.route("/api/v1/log/stop", methods=['PUT'])
|
||||
def stop_log():
|
||||
#funzione stop_log: scrive su redis LOG:STATUS -> 0
|
||||
redSrv0.set('SETTINGS:LOG:STATUS', 0)
|
||||
redSrv0.set('RTDATA:SESSION:NAME', "-")
|
||||
return "OK"
|
||||
|
||||
@flaskApp.route("/api/v1/setup/saveInMin", methods=['PUT'])
|
||||
def setupInMin():
|
||||
# devo leggere il channel attualmente selezionato
|
||||
indCh = getRedisVal('SETTINGS:SELECTED_CH')
|
||||
currChVal = redSrv0.get('RTDATA:CH:'+ str(indCh))
|
||||
redSrv0.set('SETTINGS:IN:MIN:'+ str(indCh), currChVal)
|
||||
return redirect("/settings")
|
||||
|
||||
@flaskApp.route("/api/v1/setup/saveInMax", methods=['PUT'])
|
||||
def setupInMax():
|
||||
# devo leggere il channel attualmente selezionato
|
||||
indCh = getRedisVal('SETTINGS:SELECTED_CH')
|
||||
currChVal = redSrv0.get('RTDATA:CH:'+ str(indCh))
|
||||
redSrv0.set('SETTINGS:IN:MAX:'+ str(indCh), currChVal)
|
||||
return redirect("/settings")
|
||||
|
||||
@flaskApp.route("/api/v1/setup/selectChannel/<numCh>", methods=['PUT'])
|
||||
def selectChannel(numCh):
|
||||
print(numCh)
|
||||
# request_data = request.get_json()
|
||||
# # devo leggere il channel attualmente selezionato, x ora cablo a 0...
|
||||
# numCh = request_data['channel']
|
||||
redSrv0.set('SETTINGS:SELECTED_CH', numCh)
|
||||
return "OK"
|
||||
|
||||
@flaskApp.route("/api/v1/frequency", methods=['POST'])
|
||||
def setFrequency():
|
||||
#funzione set frequenza scrive su redis LOG:FREQ prendendolo dall'input in pagina html con nome LogFreq
|
||||
newFrequency = request.form['LogFreq']
|
||||
redSrv0.set('SETTINGS:LOG:FREQ', newFrequency)
|
||||
# rimando in settings
|
||||
return redirect("/settings")
|
||||
|
||||
@flaskApp.route("/api/v1/scaleout", methods=['POST'])
|
||||
def setScale():
|
||||
indexCh = getRedisVal('SETTINGS:SELECTED_CH')
|
||||
scaleMin = request.form['MinOut']
|
||||
redSrv0.set('SETTINGS:OUT:MIN:'+ str(indexCh), scaleMin)
|
||||
scaleMax = request.form['MaxOut']
|
||||
redSrv0.set('SETTINGS:OUT:MAX:'+ str(indexCh), scaleMax)
|
||||
# rimando in settings
|
||||
return redirect("/settings")
|
||||
|
||||
#dichiaro host ipv4 (ottenuto sopra utilizzando il modulo socket)
|
||||
if __name__ == "__main__":
|
||||
flaskApp.run(host=ipv4, port=80, debug=True)
|
||||
@@ -1,239 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
from flask import Flask, render_template, jsonify, request
|
||||
from datetime import datetime
|
||||
from flask.wrappers import Request
|
||||
import redis
|
||||
import socket
|
||||
import os
|
||||
from werkzeug.utils import redirect
|
||||
|
||||
#create a socket object
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
|
||||
#connect to the server on local computer
|
||||
s.connect(("8.8.8.8", 80))
|
||||
|
||||
#assegno a variabile indirizzo ip per usi futuri
|
||||
ipv4 = s.getsockname()[0]
|
||||
s.close()
|
||||
|
||||
#volendo stampo a video IPv4
|
||||
#print("Indirizzo Ipv4 assegnato: ",s.getsockname()[0])
|
||||
|
||||
#configurazione per lavorare su server redis locale
|
||||
REDIS_PORT = 6379
|
||||
REDIS_HOST = '127.0.0.1'
|
||||
redSrv0 = redis.Redis(
|
||||
host=REDIS_HOST,
|
||||
port=REDIS_PORT,
|
||||
db=0)
|
||||
|
||||
#funzione per leggere e decodificare da redis
|
||||
def getRedisVal(redisKey):
|
||||
return redSrv0.get(redisKey).decode('utf-8')
|
||||
|
||||
flaskApp = Flask(__name__)
|
||||
@flaskApp.route("/")
|
||||
#funzione main: passa al template home il titolo
|
||||
def main():
|
||||
channelsData = {
|
||||
'title' : 'Home'
|
||||
}
|
||||
#assegno il template html di riferimento
|
||||
return render_template('home.html', **channelsData)
|
||||
|
||||
@flaskApp.route("/logger")
|
||||
#funzione logger, route a pagina /logger
|
||||
def logger():
|
||||
channelsData = {
|
||||
'title' : 'Logger',
|
||||
'timeSrv' : getRedisVal('RTDATA:TIME:SRV'),
|
||||
'timeLog' : getRedisVal('RTDATA:TIME:LOG'),
|
||||
'Freq' : getRedisVal('SETTINGS:LOG:FREQ'),
|
||||
'Ch0' : getRedisVal('RTDATA:CH:0'),
|
||||
'Ch1' : getRedisVal('RTDATA:CH:1'),
|
||||
'Ch2' : getRedisVal('RTDATA:CH:2'),
|
||||
'Ch3' : getRedisVal('RTDATA:CH:3'),
|
||||
'Ch4' : getRedisVal('RTDATA:CH:4'),
|
||||
'Ch5' : getRedisVal('RTDATA:CH:5'),
|
||||
'Ch6' : getRedisVal('RTDATA:CH:6'),
|
||||
'Ch7' : getRedisVal('RTDATA:CH:7'),
|
||||
'Out0' : getRedisVal('RTDATA:OUT:0'),
|
||||
'Out1' : getRedisVal('RTDATA:OUT:1'),
|
||||
'Out2' : getRedisVal('RTDATA:OUT:2'),
|
||||
'Out3' : getRedisVal('RTDATA:OUT:3'),
|
||||
'Out4' : getRedisVal('RTDATA:OUT:4'),
|
||||
'Out5' : getRedisVal('RTDATA:OUT:5'),
|
||||
'Out6' : getRedisVal('RTDATA:OUT:6'),
|
||||
'Out7' : getRedisVal('RTDATA:OUT:7')
|
||||
}
|
||||
#assegno il template html di riferimento
|
||||
return render_template('logger.html', **channelsData)
|
||||
|
||||
@flaskApp.route("/settings")
|
||||
#funzione setup, route a pagina /setup
|
||||
def setup():
|
||||
channelsData = {
|
||||
'title' : 'Settings',
|
||||
'Freq' : getRedisVal('SETTINGS:LOG:FREQ'),
|
||||
'Ch0' : getRedisVal('RTDATA:CH:0'),
|
||||
'Ch1' : getRedisVal('RTDATA:CH:1'),
|
||||
'Ch2' : getRedisVal('RTDATA:CH:2'),
|
||||
'Ch3' : getRedisVal('RTDATA:CH:3'),
|
||||
'Ch4' : getRedisVal('RTDATA:CH:4'),
|
||||
'Ch5' : getRedisVal('RTDATA:CH:5'),
|
||||
'Ch6' : getRedisVal('RTDATA:CH:6'),
|
||||
'Ch7' : getRedisVal('RTDATA:CH:7'),
|
||||
'Out0' : getRedisVal('RTDATA:OUT:0'),
|
||||
'Out1' : getRedisVal('RTDATA:OUT:1'),
|
||||
'Out2' : getRedisVal('RTDATA:OUT:2'),
|
||||
'Out3' : getRedisVal('RTDATA:OUT:3'),
|
||||
'Out4' : getRedisVal('RTDATA:OUT:4'),
|
||||
'Out5' : getRedisVal('RTDATA:OUT:5'),
|
||||
'Out6' : getRedisVal('RTDATA:OUT:6'),
|
||||
'Out7' : getRedisVal('RTDATA:OUT:7')
|
||||
}
|
||||
#assegno il template html di riferimento
|
||||
return render_template('settings.html', **channelsData)
|
||||
|
||||
@flaskApp.route("/about")
|
||||
#funzione about, route a pagina /about
|
||||
def about():
|
||||
channelsData = {
|
||||
'title' : 'About'
|
||||
}
|
||||
#assegno il template html di riferimento
|
||||
return render_template('about.html', **channelsData)
|
||||
|
||||
# definisco una NUOVA route a cui rispondere su chiamta in metodo GET x restituire dati aggiornati
|
||||
@flaskApp.route("/api/v1/channels/all", methods=['GET'])
|
||||
def api_channels_all():
|
||||
numCh = getRedisVal('SETTINGS:SELECTED_CH')
|
||||
#funzione api_channels_all: legge direttamente da redis, ritorna jsonify
|
||||
channelsData = {
|
||||
'timeSrv' : getRedisVal('RTDATA:TIME:SRV'),
|
||||
'timeLog' : getRedisVal('RTDATA:TIME:LOG'),
|
||||
'Freq' : getRedisVal('SETTINGS:LOG:FREQ'),
|
||||
'Ch0' : getRedisVal('RTDATA:CH:0'),
|
||||
'Ch1' : getRedisVal('RTDATA:CH:1'),
|
||||
'Ch2' : getRedisVal('RTDATA:CH:2'),
|
||||
'Ch3' : getRedisVal('RTDATA:CH:3'),
|
||||
'Ch4' : getRedisVal('RTDATA:CH:4'),
|
||||
'Ch5' : getRedisVal('RTDATA:CH:5'),
|
||||
'Ch6' : getRedisVal('RTDATA:CH:6'),
|
||||
'Ch7' : getRedisVal('RTDATA:CH:7'),
|
||||
'Out0' : getRedisVal('RTDATA:OUT:0'),
|
||||
'Out1' : getRedisVal('RTDATA:OUT:1'),
|
||||
'Out2' : getRedisVal('RTDATA:OUT:2'),
|
||||
'Out3' : getRedisVal('RTDATA:OUT:3'),
|
||||
'Out4' : getRedisVal('RTDATA:OUT:4'),
|
||||
'Out5' : getRedisVal('RTDATA:OUT:5'),
|
||||
'Out6' : getRedisVal('RTDATA:OUT:6'),
|
||||
'Out7' : getRedisVal('RTDATA:OUT:7'),
|
||||
'ChScaleMax' : getRedisVal('SETTINGS:IN:MAX:'+str(numCh)),
|
||||
'ChScaleMin' : getRedisVal('SETTINGS:IN:MIN:'+str(numCh)),
|
||||
'ChRealMax' : getRedisVal('SETTINGS:OUT:MAX:'+str(numCh)),
|
||||
'ChRealMin' : getRedisVal('SETTINGS:OUT:MIN:'+str(numCh)),
|
||||
'LastSessionName' : getRedisVal('RTDATA:SESSION:NAME')
|
||||
}
|
||||
# restituisce in formato json i dati letti da redis
|
||||
return jsonify(channelsData)
|
||||
|
||||
# definisco una NUOVA route a cui rispondere su chiamta in metodo GET x restituire dati aggiornati
|
||||
@flaskApp.route("/api/v1/channels/current", methods=['GET'])
|
||||
def api_channels_current():
|
||||
numCh = getRedisVal('SETTINGS:SELECTED_CH')
|
||||
#funzione api_channels_all: legge direttamente da redis, ritorna jsonify
|
||||
result = {
|
||||
'numCh' : numCh,
|
||||
'timeSrv' : getRedisVal('RTDATA:TIME:SRV'),
|
||||
'timeLog' : getRedisVal('RTDATA:TIME:LOG'),
|
||||
'Freq' : getRedisVal('SETTINGS:LOG:FREQ'),
|
||||
'CurrIn' : getRedisVal('RTDATA:CH:'+str(numCh)),
|
||||
'CurrOut' : getRedisVal('RTDATA:OUT:'+str(numCh)),
|
||||
'MaxOut' : getRedisVal('SETTINGS:OUT:MAX:'+str(numCh)),
|
||||
'MinOut' : getRedisVal('SETTINGS:OUT:MIN:'+str(numCh)),
|
||||
'MaxIn' : getRedisVal('SETTINGS:IN:MAX:'+str(numCh)),
|
||||
'MinIn' : getRedisVal('SETTINGS:IN:MIN:'+str(numCh))
|
||||
}
|
||||
# restituisce in formato json i dati letti da redis
|
||||
return jsonify(result)
|
||||
|
||||
# elenco file nella directory
|
||||
@flaskApp.route("/api/v1/files/list", methods=['GET'])
|
||||
def api_get_files():
|
||||
dataDir='/home/pi/data/'
|
||||
fileList = os.listdir(dataDir)
|
||||
result = {}
|
||||
for item in fileList:
|
||||
result[item]=os.path.getsize(dataDir+item)
|
||||
return jsonify(result)
|
||||
|
||||
# Route di comando x LOG: start e stop
|
||||
@flaskApp.route("/api/v1/log/start", methods=['PUT'])
|
||||
def start_log():
|
||||
#funzione start_log: scrive su redis LOG:STATUS -> 1
|
||||
redSrv0.set('SETTINGS:LOG:STATUS', 1)
|
||||
#data e time ora
|
||||
lastDate = datetime.now()
|
||||
#formato per data e time: dd/mm/YYYY H:M:S
|
||||
format = "%Y%m%d_%H%M%S"
|
||||
#format date e time adando strftime()
|
||||
nameDate = lastDate.strftime(format) + ".csv"
|
||||
redSrv0.set('RTDATA:SESSION:NAME', nameDate)
|
||||
return "OK"
|
||||
|
||||
@flaskApp.route("/api/v1/log/stop", methods=['PUT'])
|
||||
def stop_log():
|
||||
#funzione stop_log: scrive su redis LOG:STATUS -> 0
|
||||
redSrv0.set('SETTINGS:LOG:STATUS', 0)
|
||||
redSrv0.set('RTDATA:SESSION:NAME', "-")
|
||||
return "OK"
|
||||
|
||||
@flaskApp.route("/api/v1/setup/saveInMin", methods=['PUT'])
|
||||
def setupInMin():
|
||||
# devo leggere il channel attualmente selezionato
|
||||
indCh = getRedisVal('SETTINGS:SELECTED_CH')
|
||||
currChVal = redSrv0.get('RTDATA:CH:'+ str(indCh))
|
||||
redSrv0.set('SETTINGS:IN:MIN:'+ str(indCh), currChVal)
|
||||
return redirect("/settings")
|
||||
|
||||
@flaskApp.route("/api/v1/setup/saveInMax", methods=['PUT'])
|
||||
def setupInMax():
|
||||
# devo leggere il channel attualmente selezionato
|
||||
indCh = getRedisVal('SETTINGS:SELECTED_CH')
|
||||
currChVal = redSrv0.get('RTDATA:CH:'+ str(indCh))
|
||||
redSrv0.set('SETTINGS:IN:MAX:'+ str(indCh), currChVal)
|
||||
return redirect("/settings")
|
||||
|
||||
@flaskApp.route("/api/v1/setup/selectChannel/<numCh>", methods=['PUT'])
|
||||
def selectChannel(numCh):
|
||||
print(numCh)
|
||||
# request_data = request.get_json()
|
||||
# # devo leggere il channel attualmente selezionato, x ora cablo a 0...
|
||||
# numCh = request_data['channel']
|
||||
redSrv0.set('SETTINGS:SELECTED_CH', numCh)
|
||||
return "OK"
|
||||
|
||||
@flaskApp.route("/api/v1/frequency", methods=['POST'])
|
||||
def setFrequency():
|
||||
#funzione set frequenza scrive su redis LOG:FREQ prendendolo dall'input in pagina html con nome LogFreq
|
||||
newFrequency = request.form['LogFreq']
|
||||
redSrv0.set('SETTINGS:LOG:FREQ', newFrequency)
|
||||
# rimando in settings
|
||||
return redirect("/settings")
|
||||
|
||||
@flaskApp.route("/api/v1/scaleout", methods=['POST'])
|
||||
def setScale():
|
||||
indexCh = getRedisVal('SETTINGS:SELECTED_CH')
|
||||
scaleMin = request.form['MinOut']
|
||||
redSrv0.set('SETTINGS:OUT:MIN:'+ str(indexCh), scaleMin)
|
||||
scaleMax = request.form['MaxOut']
|
||||
redSrv0.set('SETTINGS:OUT:MAX:'+ str(indexCh), scaleMax)
|
||||
# rimando in settings
|
||||
return redirect("/settings")
|
||||
|
||||
#dichiaro host ipv4 (ottenuto sopra utilizzando il modulo socket)
|
||||
if __name__ == "__main__":
|
||||
flaskApp.run(host=ipv4, port=80, debug=True)
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
FTServer.py
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,8 @@
|
||||
<script src="../static/DataTables/datatables.min.js" type="text/javascript"></script>
|
||||
<script src="../static/js/jquery-3.6.0.min.js"></script>
|
||||
<script src="../static/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="../static/js/pureknob.js" type="text/javascript"></script>
|
||||
|
||||
</head>
|
||||
<body class="sb-nav-fixed">
|
||||
<nav class="navbar navbar-expand-md bg-dark navbar-dark">
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
var intTime=400;
|
||||
// fix visualizzazioni
|
||||
fixDisplay();
|
||||
setGauges();
|
||||
// avvio timer
|
||||
var timeout = setTimeout(dataRefresh, intTime);
|
||||
|
||||
@@ -13,6 +14,48 @@
|
||||
$("#divNewFile").toggle();
|
||||
};
|
||||
|
||||
function setGauges(){
|
||||
// Create knob element, 300 x 300 px in size.
|
||||
const knob = pureknob.createKnob(300, 300);
|
||||
|
||||
// Set properties.
|
||||
knob.setProperty('angleStart', -0.75 * Math.PI);
|
||||
knob.setProperty('angleEnd', 0.75 * Math.PI);
|
||||
knob.setProperty('colorFG', '#88ff88');
|
||||
knob.setProperty('trackWidth', 0.4);
|
||||
knob.setProperty('valMin', 0);
|
||||
knob.setProperty('valMax', 100);
|
||||
|
||||
// Set initial value.
|
||||
knob.setValue(50);
|
||||
|
||||
/*
|
||||
* Event listener.
|
||||
*
|
||||
* Parameter 'knob' is the knob object which was
|
||||
* actuated. Allows you to associate data with
|
||||
* it to discern which of your knobs was actuated.
|
||||
*
|
||||
* Parameter 'value' is the value which was set
|
||||
* by the user.
|
||||
*/
|
||||
const listener = function(knob, value) {
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
knob.addListener(listener);
|
||||
|
||||
// Create element node.
|
||||
const node = knob.node();
|
||||
|
||||
// Add it to the DOM.
|
||||
$("#divCh0").append(node);
|
||||
// const elem0 = document.getElementById('divCh0');
|
||||
// elem0.appendChild(node);
|
||||
// const elem1 = document.getElementById('divCh1');
|
||||
// elem1.appendChild(node);
|
||||
}
|
||||
|
||||
function dataRefresh() {
|
||||
// scarico i dati aggioranti
|
||||
$.ajax({url: "/api/v1/channels/all", success: function(result){
|
||||
@@ -73,6 +116,7 @@
|
||||
Channel 1
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="divCh0"></div>
|
||||
Original: <span id="Chan0"></span>
|
||||
<br>
|
||||
<strong>Scaled: <span id="Output0"></span>
|
||||
@@ -85,6 +129,7 @@
|
||||
Channel 2
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="divCh1"></div>
|
||||
Original: <span id="Chan1"></span>
|
||||
<br>
|
||||
<strong>Scaled: <span id="Output1"></span>
|
||||
|
||||
Reference in New Issue
Block a user