Merge branch 'logger' of https://github.com/adq/kiln-controller into adq-logger

pull/52/head
jbruce 2021-10-28 11:32:35 -04:00
commit 13f5493d15
3 zmienionych plików z 122 dodań i 0 usunięć

102
kiln-logger.py 100755
Wyświetl plik

@ -0,0 +1,102 @@
#!/usr/bin/env python
import websocket
import json
import time
import csv
import argparse
import sys
STD_HEADER = [
'stamp',
'runtime',
'temperature',
'target',
'state',
'heat',
'totaltime',
'profile',
]
PID_HEADER = [
'pid_time',
'pid_timeDelta',
'pid_setpoint',
'pid_ispoint',
'pid_err',
'pid_errDelta',
'pid_p',
'pid_i',
'pid_d',
'pid_kp',
'pid_ki',
'pid_kd',
'pid_pid',
'pid_out',
]
def logger(hostname, csvfile, noprofilestats, pidstats, stdout):
status_ws = websocket.WebSocket()
csv_fields = []
if not noprofilestats:
csv_fields += STD_HEADER
if pidstats:
csv_fields += PID_HEADER
out = open(csvfile, 'w')
csv_out = csv.DictWriter(out, csv_fields, extrasaction='ignore')
csv_out.writeheader()
if stdout:
csv_stdout = csv.DictWriter(sys.stdout, csv_fields, extrasaction='ignore', delimiter='\t')
csv_stdout.writeheader()
else:
csv_stdout = None
while True:
try:
msg = json.loads(status_ws.recv())
except websocket.WebSocketException:
try:
status_ws.connect(f'ws://{hostname}/status')
except Exception:
time.sleep(5)
continue
if msg.get('type') == 'backlog':
continue
if not noprofilestats:
msg['stamp'] = time.time()
if pidstats and 'pidstats' in msg:
for k, v in msg.get('pidstats', {}).items():
msg[f"pid_{k}"] = v
csv_out.writerow(msg)
out.flush()
if stdout:
for k in list(msg.keys()):
v = msg[k]
if isinstance(v, float):
msg[k] = '{:5.3f}'.format(v)
csv_stdout.writerow(msg)
sys.stdout.flush()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Log kiln data for analysis.')
parser.add_argument('--hostname', type=str, default="localhost:8081", help="The kiln-controller hostname:port")
parser.add_argument('--csvfile', type=str, default="/tmp/kilnstats.csv", help="Where to write the kiln stats to")
parser.add_argument('--pidstats', action='store_true', help="Include PID stats")
parser.add_argument('--noprofilestats', action='store_true', help="Do not store profile stats (default is to store them)")
parser.add_argument('--stdout', action='store_true', help="Also print to stdout")
args = parser.parse_args()
logger(args.hostname, args.csvfile, args.noprofilestats, args.pidstats, args.stdout)

Wyświetl plik

@ -273,6 +273,7 @@ class Oven(threading.Thread):
'kwh_rate': config.kwh_rate, 'kwh_rate': config.kwh_rate,
'currency_type': config.currency_type, 'currency_type': config.currency_type,
'profile': self.profile.name if self.profile else None, 'profile': self.profile.name if self.profile else None,
'pidstats': self.pid.pidstats,
} }
return state return state
@ -462,6 +463,7 @@ class PID():
self.lastNow = datetime.datetime.now() self.lastNow = datetime.datetime.now()
self.iterm = 0 self.iterm = 0
self.lastErr = 0 self.lastErr = 0
self.pidstats = {}
# FIX - this was using a really small window where the PID control # FIX - this was using a really small window where the PID control
# takes effect from -1 to 1. I changed this to various numbers and # takes effect from -1 to 1. I changed this to various numbers and
@ -496,6 +498,23 @@ class PID():
output = float(output / window_size) output = float(output / window_size)
self.pidstats = {
'time': time.mktime(now.timetuple()),
'timeDelta': timeDelta,
'setpoint': setpoint,
'ispoint': ispoint,
'err': error,
'errDelta': dErr,
'p': self.kp * error,
'i': self.iterm,
'd': self.kd * dErr,
'kp': self.kp,
'ki': self.ki,
'kd': self.kd,
'pid': out4logs,
'out': output,
}
if out4logs > 0: if out4logs > 0:
# log.info("pid percents pid=%0.2f p=%0.2f i=%0.2f d=%0.2f" % (out4logs, # log.info("pid percents pid=%0.2f p=%0.2f i=%0.2f d=%0.2f" % (out4logs,
# ((self.kp * error)/out4logs)*100, # ((self.kp * error)/out4logs)*100,

Wyświetl plik

@ -6,3 +6,4 @@ gevent-websocket
RPi.GPIO RPi.GPIO
Adafruit-MAX31855 Adafruit-MAX31855
Adafruit-GPIO Adafruit-GPIO
websocket-client