From ee90fa861eba5e73214a699180f674367c47f2a6 Mon Sep 17 00:00:00 2001 From: marios8543 Date: Tue, 7 May 2024 18:23:39 +0300 Subject: [PATCH] Add datalogger --- pyren3/data_logger.py | 164 ++++++++++++++++++++---------------- pyren3/index.html | 130 ++++++++++++++++++++++++++++ pyren3/mod_ecu_parameter.py | 2 +- pyren3/mod_ecu_state.py | 2 +- pyren3/rendash_main.py | 18 ++-- 5 files changed, 235 insertions(+), 81 deletions(-) create mode 100644 pyren3/index.html diff --git a/pyren3/data_logger.py b/pyren3/data_logger.py index 6a1471b..e25fec2 100644 --- a/pyren3/data_logger.py +++ b/pyren3/data_logger.py @@ -1,85 +1,103 @@ -from mod_utils import chkDirTree -from mod_db_manager import find_DBs -from mod_elm import ELM -from mod_scan_ecus import ScanEcus -from mod_optfile import optfile -from mod_ecu import ECU -from mod_ply import Calc +from flask import Flask, jsonify, request, send_file +from flask_socketio import SocketIO +from rendash_main import RenDash +from csv import writer, QUOTE_MINIMAL +from datetime import datetime -from pickle import dump, load -from time import sleep +import mod_globals +mod_globals.opt_demo = True -from flask import Flask, make_response, request +dash = RenDash("/dev/tty1") +web = Flask(__name__) +socket = SocketIO(web) -from typing import List +watched_datarefs = [] +watched_ecu = "" +should_log = False +freeze = 0 +running = False -class RenDash: - def __init__(self, - elm_port, - elm_speed=38400, - model_number=58, - rescan=False) -> None: - chkDirTree() - find_DBs() +bg_thread = None - self.elm = ELM(elm_port, elm_speed, "") - self.lang = optfile("Location/DiagOnCAN_GB.bqm", False) - self.ecus: List[ECU] = [] - self.current_ecu = None +def mainloop(): + global running, watched_datarefs, watched_ecu, should_log, freeze + if should_log: + log_filename = f'{datetime.now().strftime("%m/%d/%Y, %H:%M:%S")}.csv' + print("Creating log on file: " + log_filename) + with open(log_filename, "w+") as file: + csv_writer = writer(file,delimiter=' ', quotechar='|', quoting=QUOTE_MINIMAL) + csv_writer.writerow(["freeze"].extend(watched_datarefs)) - self.web = Flask(__name__) + print("Starting data loop") + while running: + frame = [dash.get_ecu_dataref(watched_ecu, dataref) for dataref in watched_datarefs] + socket.emit("frame", {"frame": frame}) + if should_log: + csv_writer.writerow([freeze].extend(frame)) + freeze = 0 + print(frame) - if rescan is False: - try: - self.ecus = load(open("frozen_ecus.p", "rb")) - except Exception as e: - pass - if not self.ecus: - ecu_scanner = ScanEcus(self.elm) - ecu_scanner.chooseModel(model_number) - ecu_scanner.scanAllEcus() - for ecu in ecu_scanner.detectedEcus: - self.ecus.append(ECU(ecu, self.lang.dict)) - dump(self.ecus, open("frozen_ecus.p", "wb+")) +@socket.on("freeze") +def freeze_event(): + global freeze - for ecu in self.ecus: - setattr(ecu, "calc", Calc()) + freeze = 1 - def get_ecu_names(self): - return [ecu.ecudata["doc"] for ecu in self.ecus] +@web.get("/ecus") +def get_ecus(): + ecus = dash.get_ecu_names() + return jsonify(ecus) + +@web.get("/ecus//states") +def get_ecu_states(ecu_doc): + return jsonify(dash.get_ecu_states(ecu_doc)) + +@web.get("/ecus//parameters") +def get_ecu_parameters(ecu_doc): + return jsonify(dash.get_ecu_parameters(ecu_doc)) + +@web.post("/ecus//watch") +def ecu_watch(ecu_doc): + global watched_ecu, watched_datarefs + + datarefs = request.get_json() + watched_datarefs = [] + for dataref in datarefs: + if dataref in dash.get_ecu_parameters(ecu_doc) \ + or dataref in dash.get_ecu_states(ecu_doc): + watched_datarefs.append(dataref) + else: + watched_datarefs = [] + raise ValueError("Invalid dataref") + watched_ecu = ecu_doc + + return jsonify({"ecu": watched_ecu, "datarefs": watched_datarefs}) + +@web.get("/start") +def start(): + global should_log, bg_thread, running + + log = request.args.get("log") + if log == "true": + should_log = True + else: + should_log = False - def get_ecu_by_doc(self, doc): - for ecu in self.ecus: - if ecu.ecudata["doc"] == doc: - if self.current_ecu is not ecu: - ecu.initELM(self.elm) - self.current_ecu = ecu - return ecu - - def get_ecu_states(self, doc): - ecu = self.get_ecu_by_doc(doc) - return ecu.Parameters - - def get_ecu_state(self, doc, state): - ecu = self.get_ecu_by_doc(doc) - datastr = ecu.get_st(state) - return datastr - - def get_ecu_param(self, doc, param): - ecu = self.get_ecu_by_doc(doc) - datastr = ecu.get_pr(param) - return datastr + running = True + bg_thread = socket.start_background_task(mainloop) + return jsonify({"success": True}) + +@web.get("/stop") +def stop(): + global bg_thread, running + + running = False + bg_thread.join() + return jsonify({"success": True}) + +@web.get("/") +def index(): + return send_file("index.html") if __name__ == "__main__": - rd = RenDash("/dev/tty0") - while True: - clearScreen() - for ecu_doc, values in REQUIRED_ECU_STATES.items(): - for val in values: - if val.startswith("E"): - print(rd.get_ecu_state(ecu_doc, val)) - elif val.startswith("P"): - print(rd.get_ecu_param(ecu_doc, val)) - sleep(0.1) - - \ No newline at end of file + socket.run(web, "0.0.0.0", 5000) \ No newline at end of file diff --git a/pyren3/index.html b/pyren3/index.html new file mode 100644 index 0000000..0612b4c --- /dev/null +++ b/pyren3/index.html @@ -0,0 +1,130 @@ + + + + + + Ecu Watcher + + + + +
+

Ecu Watcher

+
+

Select ECU

+ +
+
+

Selected ECU: {{ selectedEcu }}

+
+

States and Parameters

+
+ {{ + text }} +
+ +
+
+
+

Watching

+
+ {{ statesAndParams[item] }}: {{ itemValues[item] }} +
+ + + +
+
+ + + + diff --git a/pyren3/mod_ecu_parameter.py b/pyren3/mod_ecu_parameter.py index 050f2a3..7d6a39f 100755 --- a/pyren3/mod_ecu_parameter.py +++ b/pyren3/mod_ecu_parameter.py @@ -42,7 +42,7 @@ def get_parameter( pr, mn, se, elm, calc, dataids = {} ): tmpmin = '' tmpmax = '' - return "%-6s %-50s %5s %10s %-10s %-5s"%(pr.codeMR,pr.label,tmpmin,pr.value,pr.unit,tmpmax), pr.helps, csv_data + return "%5s %10s %-10s %-5s"%(tmpmin,pr.value,pr.unit,tmpmax), pr.helps, csv_data class ecu_parameter: diff --git a/pyren3/mod_ecu_state.py b/pyren3/mod_ecu_state.py index bfa68a1..a076c83 100644 --- a/pyren3/mod_ecu_state.py +++ b/pyren3/mod_ecu_state.py @@ -29,7 +29,7 @@ def get_state( st, mn, se, elm, calc, dataids = {} ): csv_val = str(st.value) st.value = " "*(16-len(st.value)//2) + str(st.value) - return "%-6s %-50s %-20s"%(st.codeMR,st.label,st.value), st.helps, csv_val + return "%-20s"%(st.value), st.helps, csv_val class ecu_state: diff --git a/pyren3/rendash_main.py b/pyren3/rendash_main.py index 6bc2813..a12630f 100644 --- a/pyren3/rendash_main.py +++ b/pyren3/rendash_main.py @@ -64,21 +64,27 @@ class RenDash: def get_ecu_states(self, doc): ecu = self.get_ecu_by_doc(doc) - return ecu.States + return {key: value.label for key,value in ecu.States.items()} def get_ecu_parameters(self, doc): ecu = self.get_ecu_by_doc(doc) - return ecu.Parameters + return {key: value.label for key,value in ecu.Parameters.items()} def get_ecu_state(self, doc, state): ecu = self.get_ecu_by_doc(doc) - datastr, help, csvd = get_state(ecu.States[state], ecu.Mnemonics, ecu.Services, self.elm, ecu.calc) - return datastr + return ecu.get_st(state) def get_ecu_param(self, doc, param): ecu = self.get_ecu_by_doc(doc) - datastr, help, csvd = get_parameter(ecu.Parameters[param], ecu.Mnemonics, ecu.Services, self.elm, ecu.calc) - return datastr + return ecu.get_pr(param) + + def get_ecu_dataref(self, doc, dataref: str): + if dataref.startswith("E"): + return self.get_ecu_state(doc, dataref) + elif dataref.startswith("P"): + return self.get_ecu_param(doc, dataref) + else: + raise ValueError("Invalid dataref") if __name__ == "__main__": rd = RenDash("/dev/ttyS5")