updated CodeGeneration
This commit is contained in:
parent
ac28ab21d4
commit
157d59963c
3
Software/.gitignore
vendored
3
Software/.gitignore
vendored
@ -4,4 +4,5 @@ data/
|
|||||||
.vscode/c_cpp_properties.json
|
.vscode/c_cpp_properties.json
|
||||||
.vscode/launch.json
|
.vscode/launch.json
|
||||||
.vscode/ipch
|
.vscode/ipch
|
||||||
wifi_credentials.ini
|
wifi_credentials.ini
|
||||||
|
__pycache__
|
@ -1,127 +0,0 @@
|
|||||||
Import("env") # pylint: disable=undefined-variable
|
|
||||||
env.Execute("\"$PYTHONEXE\" -m pip install jinja2")
|
|
||||||
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
from jinja2 import Environment, FileSystemLoader
|
|
||||||
import json
|
|
||||||
|
|
||||||
# Pfad zur Eingabedatei und Ausgabedatei
|
|
||||||
input_file = "src/dtc_defs.txt"
|
|
||||||
output_file = "include/dtc_defs.h"
|
|
||||||
json_output_file = "data_src/static/dtc_table.json"
|
|
||||||
|
|
||||||
# Überprüfen, ob das Verzeichnis existiert, andernfalls erstellen
|
|
||||||
json_output_dir = os.path.dirname(json_output_file)
|
|
||||||
if not os.path.exists(json_output_dir):
|
|
||||||
os.makedirs(json_output_dir)
|
|
||||||
|
|
||||||
# Mehrdimensionales Array zum Speichern der Zeilen aus der Eingabedatei
|
|
||||||
dtc_lines = []
|
|
||||||
|
|
||||||
# Lesen und analysieren der Eingabedatei
|
|
||||||
with open(input_file, "r", encoding="utf-8") as f:
|
|
||||||
for line in f:
|
|
||||||
line = line.strip()
|
|
||||||
if not line or line.startswith("#"):
|
|
||||||
continue
|
|
||||||
|
|
||||||
parts = line.split(";")
|
|
||||||
if len(parts) == 5:
|
|
||||||
num, dtc_name, dtc_severity, title, description = [part.strip() for part in parts]
|
|
||||||
dtc_lines.append([int(num), dtc_name, dtc_severity, title, description])
|
|
||||||
|
|
||||||
# Überprüfen auf Duplikate in den DTC-Nummern und DTC-Namen
|
|
||||||
num_set = set()
|
|
||||||
dtc_name_set = set()
|
|
||||||
duplicates = []
|
|
||||||
|
|
||||||
for line in dtc_lines:
|
|
||||||
num, dtc_name, _, _, _ = line
|
|
||||||
if num in num_set:
|
|
||||||
duplicates.append(f"DTC-Nummer {num} ist ein Duplikat.")
|
|
||||||
else:
|
|
||||||
num_set.add(num)
|
|
||||||
|
|
||||||
if dtc_name in dtc_name_set:
|
|
||||||
duplicates.append(f"DTC-Name '{dtc_name}' ist ein Duplikat.")
|
|
||||||
else:
|
|
||||||
dtc_name_set.add(dtc_name)
|
|
||||||
|
|
||||||
if duplicates:
|
|
||||||
for duplicate in duplicates:
|
|
||||||
print(f"Fehler: {duplicate}")
|
|
||||||
raise ValueError("Duplicate DTC Data detected")
|
|
||||||
|
|
||||||
# Suchen nach DTC_NO_DTC und DTC_LAST_DTC
|
|
||||||
dtc_no_dtc_added = False
|
|
||||||
dtc_last_dtc_line = None
|
|
||||||
|
|
||||||
for line in dtc_lines:
|
|
||||||
_, dtc_name, _, _, _ = line
|
|
||||||
if dtc_name == "DTC_NO_DTC":
|
|
||||||
dtc_no_dtc_added = True
|
|
||||||
elif dtc_name == "DTC_LAST_DTC":
|
|
||||||
dtc_last_dtc_line = line
|
|
||||||
|
|
||||||
# Einen DTC für DTC_NO_DTC hinzufügen (wenn nicht vorhanden)
|
|
||||||
if not dtc_no_dtc_added:
|
|
||||||
dtc_lines.insert(0, [0, "DTC_NO_DTC", "DTC_NONE", "No Error", "No Error"])
|
|
||||||
|
|
||||||
# Falls DTC_LAST_DTC existiert, lösche es
|
|
||||||
if dtc_last_dtc_line:
|
|
||||||
dtc_lines.remove(dtc_last_dtc_line)
|
|
||||||
|
|
||||||
# Einen DTC für DTC_LAST_DTC hinzufügen (mit der höchsten Nummer)
|
|
||||||
if dtc_lines:
|
|
||||||
highest_num = max([line[0] for line in dtc_lines])
|
|
||||||
else:
|
|
||||||
highest_num = 0
|
|
||||||
|
|
||||||
dtc_lines.append([highest_num + 1, "DTC_LAST_DTC", "DTC_NONE", "Last Error", "Last Error"])
|
|
||||||
|
|
||||||
# Sortieren der Zeilen nach der Nummer aufsteigend
|
|
||||||
dtc_lines.sort(key=lambda x: x[0])
|
|
||||||
|
|
||||||
# DTC_NAME_CONSTANT-Makros initialisieren
|
|
||||||
dtc_macros = []
|
|
||||||
dtc_structs = []
|
|
||||||
dtc_table_data = []
|
|
||||||
|
|
||||||
# Verarbeiten der sortierten Zeilen
|
|
||||||
for i, line in enumerate(dtc_lines):
|
|
||||||
num, dtc_name, dtc_severity, title, description = line
|
|
||||||
dtc_macros.append(f"#define {dtc_name:<30} {num}")
|
|
||||||
comma = "," if i < len(dtc_lines) - 1 else " "
|
|
||||||
dtc_structs.append(f" {{ {dtc_name:<30}, {dtc_severity:<12} }}{comma} // {description}")
|
|
||||||
dtc_table_data.append({"num": num, "title": title, "description": description})
|
|
||||||
|
|
||||||
# Unix-Zeitstempel hinzufügen
|
|
||||||
timestamp = int(time.time())
|
|
||||||
|
|
||||||
env = Environment(loader=FileSystemLoader('include', encoding='utf-8'))
|
|
||||||
# Lade das Jinja2-Template aus der Datei
|
|
||||||
template = env.get_template('dtc_defs.h.j2')
|
|
||||||
|
|
||||||
# Erstelle ein Context-Dictionary mit den erforderlichen Daten
|
|
||||||
context = {
|
|
||||||
'timestamp_unix': timestamp,
|
|
||||||
'timestamp' : time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp)),
|
|
||||||
'dtc_macros': dtc_macros, # Übergebe die dtc_macros-Liste direkt
|
|
||||||
'dtc_structs': dtc_structs, # Übergebe die dtc_structs-Liste direkt
|
|
||||||
}
|
|
||||||
|
|
||||||
# Rendere das Template mit den Werten und erhalte den Header-Text
|
|
||||||
header_text = template.render(context)
|
|
||||||
|
|
||||||
# Schreibe den generierten Header-Text in die Header-Datei
|
|
||||||
with open(output_file, "w", encoding='utf-8') as f:
|
|
||||||
f.write(header_text)
|
|
||||||
|
|
||||||
print(f"Header-Datei wurde erstellt: {output_file}")
|
|
||||||
|
|
||||||
# JSON-Datei mit UTF-8-Zeichencodierung erstellen
|
|
||||||
with open(json_output_file, 'w', encoding='utf-8') as json_f:
|
|
||||||
json.dump(dtc_table_data, json_f, ensure_ascii=False, indent=4, separators=(',', ': '))
|
|
||||||
|
|
||||||
print(f"JSON-Datei wurde erstellt: {json_output_file}")
|
|
127
Software/codegen/dtcs.py
Normal file
127
Software/codegen/dtcs.py
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
import os
|
||||||
|
import time
|
||||||
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
import json
|
||||||
|
|
||||||
|
def build_dtcs():
|
||||||
|
# Pfad zur Eingabedatei und Ausgabedatei
|
||||||
|
input_file = "src/dtc_defs.txt"
|
||||||
|
output_file = "include/dtc_defs.h"
|
||||||
|
json_output_file = "data_src/static/dtc_table.json"
|
||||||
|
|
||||||
|
# Überprüfen, ob das Verzeichnis existiert, andernfalls erstellen
|
||||||
|
json_output_dir = os.path.dirname(json_output_file)
|
||||||
|
if not os.path.exists(json_output_dir):
|
||||||
|
os.makedirs(json_output_dir)
|
||||||
|
|
||||||
|
# Mehrdimensionales Array zum Speichern der Zeilen aus der Eingabedatei
|
||||||
|
dtc_lines = []
|
||||||
|
|
||||||
|
# Lesen und analysieren der Eingabedatei
|
||||||
|
with open(input_file, "r", encoding="utf-8") as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if not line or line.startswith("#"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
parts = line.split(";")
|
||||||
|
if len(parts) == 5:
|
||||||
|
num, dtc_name, dtc_severity, title, description = [part.strip() for part in parts]
|
||||||
|
dtc_lines.append([int(num), dtc_name, dtc_severity, title, description])
|
||||||
|
|
||||||
|
# Überprüfen auf Duplikate in den DTC-Nummern und DTC-Namen
|
||||||
|
num_set = set()
|
||||||
|
dtc_name_set = set()
|
||||||
|
duplicates = []
|
||||||
|
|
||||||
|
for line in dtc_lines:
|
||||||
|
num, dtc_name, _, _, _ = line
|
||||||
|
if num in num_set:
|
||||||
|
duplicates.append(f"DTC-Nummer {num} ist ein Duplikat.")
|
||||||
|
else:
|
||||||
|
num_set.add(num)
|
||||||
|
|
||||||
|
if dtc_name in dtc_name_set:
|
||||||
|
duplicates.append(f"DTC-Name '{dtc_name}' ist ein Duplikat.")
|
||||||
|
else:
|
||||||
|
dtc_name_set.add(dtc_name)
|
||||||
|
|
||||||
|
if duplicates:
|
||||||
|
for duplicate in duplicates:
|
||||||
|
print(f"Fehler: {duplicate}")
|
||||||
|
raise ValueError("Duplicate DTC Data detected")
|
||||||
|
|
||||||
|
# Suchen nach DTC_NO_DTC und DTC_LAST_DTC
|
||||||
|
dtc_no_dtc_added = False
|
||||||
|
dtc_last_dtc_line = None
|
||||||
|
|
||||||
|
for line in dtc_lines:
|
||||||
|
_, dtc_name, _, _, _ = line
|
||||||
|
if dtc_name == "DTC_NO_DTC":
|
||||||
|
dtc_no_dtc_added = True
|
||||||
|
elif dtc_name == "DTC_LAST_DTC":
|
||||||
|
dtc_last_dtc_line = line
|
||||||
|
|
||||||
|
# Einen DTC für DTC_NO_DTC hinzufügen (wenn nicht vorhanden)
|
||||||
|
if not dtc_no_dtc_added:
|
||||||
|
dtc_lines.insert(0, [0, "DTC_NO_DTC", "DTC_NONE", "No Error", "No Error"])
|
||||||
|
|
||||||
|
# Falls DTC_LAST_DTC existiert, lösche es
|
||||||
|
if dtc_last_dtc_line:
|
||||||
|
dtc_lines.remove(dtc_last_dtc_line)
|
||||||
|
|
||||||
|
# Einen DTC für DTC_LAST_DTC hinzufügen (mit der höchsten Nummer)
|
||||||
|
if dtc_lines:
|
||||||
|
highest_num = max([line[0] for line in dtc_lines])
|
||||||
|
else:
|
||||||
|
highest_num = 0
|
||||||
|
|
||||||
|
dtc_lines.append([highest_num + 1, "DTC_LAST_DTC", "DTC_NONE", "Last Error", "Last Error"])
|
||||||
|
|
||||||
|
# Sortieren der Zeilen nach der Nummer aufsteigend
|
||||||
|
dtc_lines.sort(key=lambda x: x[0])
|
||||||
|
|
||||||
|
# DTC_NAME_CONSTANT-Makros initialisieren
|
||||||
|
dtc_macros = []
|
||||||
|
dtc_structs = []
|
||||||
|
dtc_table_data = []
|
||||||
|
|
||||||
|
# Verarbeiten der sortierten Zeilen
|
||||||
|
for i, line in enumerate(dtc_lines):
|
||||||
|
num, dtc_name, dtc_severity, title, description = line
|
||||||
|
dtc_macros.append(f"#define {dtc_name:<30} {num}")
|
||||||
|
comma = "," if i < len(dtc_lines) - 1 else " "
|
||||||
|
dtc_structs.append(f" {{ {dtc_name:<30}, {dtc_severity:<12} }}{comma} // {description}")
|
||||||
|
dtc_table_data.append({"num": num, "title": title, "description": description})
|
||||||
|
|
||||||
|
# Unix-Zeitstempel hinzufügen
|
||||||
|
timestamp = int(time.time())
|
||||||
|
|
||||||
|
env = Environment(loader=FileSystemLoader('codegen/templates', encoding='utf-8'))
|
||||||
|
# Lade das Jinja2-Template aus der Datei
|
||||||
|
template = env.get_template('dtc_defs.h.j2')
|
||||||
|
|
||||||
|
# Erstelle ein Context-Dictionary mit den erforderlichen Daten
|
||||||
|
context = {
|
||||||
|
'timestamp_unix': timestamp,
|
||||||
|
'timestamp' : time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp)),
|
||||||
|
'date' : time.strftime('%d.%m.%Y', time.localtime(timestamp)),
|
||||||
|
'dtc_macros': dtc_macros, # Übergebe die dtc_macros-Liste direkt
|
||||||
|
'dtc_structs': dtc_structs, # Übergebe die dtc_structs-Liste direkt
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rendere das Template mit den Werten und erhalte den Header-Text
|
||||||
|
header_text = template.render(context)
|
||||||
|
|
||||||
|
# Schreibe den generierten Header-Text in die Header-Datei
|
||||||
|
with open(output_file, "w", encoding='utf-8') as f:
|
||||||
|
f.write(header_text)
|
||||||
|
|
||||||
|
print(f"Header-Datei wurde erstellt: {output_file}")
|
||||||
|
|
||||||
|
# JSON-Datei mit UTF-8-Zeichencodierung erstellen
|
||||||
|
with open(json_output_file, 'w', encoding='utf-8') as json_f:
|
||||||
|
json.dump(dtc_table_data, json_f, ensure_ascii=False, indent=4, separators=(',', ': '))
|
||||||
|
|
||||||
|
print(f"JSON-Datei wurde erstellt: {json_output_file}")
|
||||||
|
|
9
Software/codegen/run_pre.py
Normal file
9
Software/codegen/run_pre.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
Import("env") # pylint: disable=undefined-variable
|
||||||
|
env.Execute("\"$PYTHONEXE\" -m pip install jinja2")
|
||||||
|
env.Replace(PROGNAME="firmware_pcb_1.%s.fw" % env.GetProjectOption("custom_pcb_revision"))
|
||||||
|
|
||||||
|
import struct2json
|
||||||
|
import dtcs
|
||||||
|
|
||||||
|
struct2json.struct2json()
|
||||||
|
dtcs.build_dtcs()
|
93
Software/codegen/struct2json.py
Normal file
93
Software/codegen/struct2json.py
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import os
|
||||||
|
import time
|
||||||
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
import re
|
||||||
|
|
||||||
|
# Pfad zur Eingabedatei und Ausgabedatei
|
||||||
|
input_file = "include/config.h"
|
||||||
|
output_sourcefile = "src/struct2json.cpp"
|
||||||
|
output_headerfile = "include/struct2json.h"
|
||||||
|
# Liste der zu suchenden Variablen/Structs
|
||||||
|
variable_names = ['LubeConfig', 'PersistenceData']
|
||||||
|
|
||||||
|
def get_types(file_content, variable_names):
|
||||||
|
result = {}
|
||||||
|
|
||||||
|
# Entferne Kommentare, um unerwünschte Störungen zu vermeiden
|
||||||
|
file_content = re.sub(r'\/\*.*?\*\/', '', file_content, flags=re.DOTALL)
|
||||||
|
file_content = re.sub(r'\/\/.*', '', file_content)
|
||||||
|
|
||||||
|
for var_name in variable_names:
|
||||||
|
# Erstelle ein reguläres Ausdrucksmuster, um den Typ der Variable zu extrahieren
|
||||||
|
pattern = re.compile(r'\b(?:extern\s+)?(\w+)\s+' + re.escape(var_name) + r'\s*;')
|
||||||
|
match = pattern.search(file_content)
|
||||||
|
|
||||||
|
if match:
|
||||||
|
# Extrahiere den Typ aus dem Treffer
|
||||||
|
type_match = match.group(1)
|
||||||
|
result[var_name] = type_match
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def extract_struct_fields(file_content, variable_types):
|
||||||
|
result = {}
|
||||||
|
|
||||||
|
# Entferne Kommentare, um unerwünschte Störungen zu vermeiden
|
||||||
|
file_content = re.sub(r'\/\*.*?\*\/', '', file_content, flags=re.DOTALL)
|
||||||
|
file_content = re.sub(r'\/\/.*', '', file_content)
|
||||||
|
|
||||||
|
for var_name, var_type in variable_types.items():
|
||||||
|
# Erstelle ein reguläres Ausdrucksmuster, um das Strukturfeld zu extrahieren
|
||||||
|
pattern = re.compile(r'typedef\s+struct\s*{([^}]*)}\s*' + re.escape(var_type) + r'\s*;')
|
||||||
|
match = pattern.search(file_content)
|
||||||
|
|
||||||
|
if match:
|
||||||
|
# Extrahiere die Felder aus dem Treffer
|
||||||
|
fields_match = re.findall(r'\b(\w+)\s+(\w+)\s*;', match.group(1))
|
||||||
|
if fields_match:
|
||||||
|
result[var_name] = {'type': var_type, 'fields': {field_name: field_type for field_type, field_name in fields_match}}
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def struct2json():
|
||||||
|
# Überprüfen, ob die Verzeichnisse existieren, andernfalls erstellen
|
||||||
|
output_dir_source = os.path.dirname(output_sourcefile)
|
||||||
|
if not os.path.exists(output_dir_source):
|
||||||
|
os.makedirs(output_dir_source)
|
||||||
|
output_dir_header = os.path.dirname(output_headerfile)
|
||||||
|
if not os.path.exists(output_dir_header):
|
||||||
|
os.makedirs(output_dir_header)
|
||||||
|
|
||||||
|
# Unix-Zeitstempel hinzufügen
|
||||||
|
timestamp = int(time.time())
|
||||||
|
|
||||||
|
# Parse structs
|
||||||
|
with open(input_file, 'r') as file:
|
||||||
|
content = file.read()
|
||||||
|
|
||||||
|
variable_types = get_types(content, variable_names)
|
||||||
|
structs = extract_struct_fields(content, variable_types)
|
||||||
|
|
||||||
|
env = Environment(loader=FileSystemLoader('codegen/templates', encoding='utf-8'))
|
||||||
|
# Lade das Jinja2-Template aus der Datei
|
||||||
|
template_c = env.get_template('struct2json.cpp.j2')
|
||||||
|
template_h = env.get_template('struct2json.h.j2')
|
||||||
|
|
||||||
|
# Erstelle ein Context-Dictionary mit den erforderlichen Daten
|
||||||
|
context = {
|
||||||
|
'timestamp_unix': timestamp,
|
||||||
|
'timestamp' : time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp)),
|
||||||
|
'date' : time.strftime('%d.%m.%Y', time.localtime(timestamp)),
|
||||||
|
'structs': structs, # Übergebe die foo-Liste direkt
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rendere das Template mit den Werten und erhalte den Source-Text
|
||||||
|
source_text = template_c.render(context)
|
||||||
|
header_text = template_h.render(context)
|
||||||
|
|
||||||
|
# Schreibe den generierten Source-Text in die Source-Dateien
|
||||||
|
with open(output_sourcefile, "w", encoding='utf-8') as f:
|
||||||
|
f.write(source_text)
|
||||||
|
with open(output_headerfile, "w", encoding='utf-8') as f:
|
||||||
|
f.write(header_text)
|
||||||
|
print(f"Source-Dateien wurde erstellt: {output_sourcefile}, {output_headerfile}")
|
@ -10,7 +10,7 @@
|
|||||||
* @note This file is auto-generated by a script on {{ timestamp }}.
|
* @note This file is auto-generated by a script on {{ timestamp }}.
|
||||||
*
|
*
|
||||||
* @author Marcel Peterkau
|
* @author Marcel Peterkau
|
||||||
* @date 09.01.2024
|
* @date {{ date }}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DTC_DEFS_H
|
#ifndef DTC_DEFS_H
|
23
Software/codegen/templates/struct2json.cpp.j2
Normal file
23
Software/codegen/templates/struct2json.cpp.j2
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* @file struct2json.cpp
|
||||||
|
*
|
||||||
|
* @brief Implementation file for converting structs to JSON objects.
|
||||||
|
*
|
||||||
|
* @note This file is auto-generated by a script on {{ timestamp }}.
|
||||||
|
*
|
||||||
|
* @author Marcel Peterkau
|
||||||
|
* @date {{ date }}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "struct2json.h"
|
||||||
|
|
||||||
|
{% for var_name, var_info in structs.items() -%}
|
||||||
|
void generateJsonObject_{{ var_name }}(JsonObject& data)
|
||||||
|
{
|
||||||
|
{% for field_name, field_type in var_info['fields'].items() -%}
|
||||||
|
data["{{ field_name }}"] = {{ var_name }}.{{ field_name }};
|
||||||
|
{% endfor -%}
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endfor %}
|
24
Software/codegen/templates/struct2json.h.j2
Normal file
24
Software/codegen/templates/struct2json.h.j2
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* @file struct2json.h
|
||||||
|
*
|
||||||
|
* @brief Header file for converting structs to JSON objects.
|
||||||
|
*
|
||||||
|
* @note This file is auto-generated by a script on {{ timestamp }}.
|
||||||
|
*
|
||||||
|
* @author Marcel Peterkau
|
||||||
|
* @date {{ date }}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _STRUCT2JSON_H_
|
||||||
|
#define _STRUCT2JSON_H_
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
{% for var_name, var_info in structs.items() -%}
|
||||||
|
void generateJsonObject_{{ var_name }}(JsonObject& data);
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
#endif /* _STRUCT2JSON_H_ */
|
24
Software/include/struct2json.h
Normal file
24
Software/include/struct2json.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* @file struct2json.h
|
||||||
|
*
|
||||||
|
* @brief Header file for converting structs to JSON objects.
|
||||||
|
*
|
||||||
|
* @note This file is auto-generated by a script on 2024-01-09 20:41:57.
|
||||||
|
*
|
||||||
|
* @author Marcel Peterkau
|
||||||
|
* @date 09.01.2024
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _STRUCT2JSON_H_
|
||||||
|
#define _STRUCT2JSON_H_
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
void generateJsonObject_LubeConfig(JsonObject& data);
|
||||||
|
void generateJsonObject_PersistenceData(JsonObject& data);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _STRUCT2JSON_H_ */
|
@ -29,6 +29,7 @@
|
|||||||
#include "dtc.h"
|
#include "dtc.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "debugger.h"
|
#include "debugger.h"
|
||||||
|
#include "struct2json.h"
|
||||||
|
|
||||||
void initWebUI();
|
void initWebUI();
|
||||||
void Webserver_Process();
|
void Webserver_Process();
|
||||||
|
@ -28,7 +28,7 @@ upload_flags =
|
|||||||
|
|
||||||
|
|
||||||
build_flags =
|
build_flags =
|
||||||
!python git_rev_macro.py
|
!python codegen/git_rev_macro.py
|
||||||
-DWIFI_SSID_CLIENT=${wifi_cred.wifi_ssid_client}
|
-DWIFI_SSID_CLIENT=${wifi_cred.wifi_ssid_client}
|
||||||
-DWIFI_PASSWORD_CLIENT=${wifi_cred.wifi_password_client}
|
-DWIFI_PASSWORD_CLIENT=${wifi_cred.wifi_password_client}
|
||||||
-DADMIN_PASSWORD=${wifi_cred.admin_password}
|
-DADMIN_PASSWORD=${wifi_cred.admin_password}
|
||||||
@ -38,9 +38,8 @@ build_flags =
|
|||||||
|
|
||||||
board_build.filesystem = littlefs
|
board_build.filesystem = littlefs
|
||||||
extra_scripts =
|
extra_scripts =
|
||||||
post:prepare_littlefs.py
|
post:codegen/prepare_littlefs.py
|
||||||
pre:build_dtcs.py
|
pre:codegen/run_pre.py
|
||||||
pre:prepare_fwfiles.py
|
|
||||||
|
|
||||||
monitor_filters = esp8266_exception_decoder
|
monitor_filters = esp8266_exception_decoder
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
Import("env")
|
|
||||||
|
|
||||||
env.Replace(PROGNAME="firmware_pcb_1.%s.fw" % env.GetProjectOption("custom_pcb_revision"))
|
|
47
Software/src/struct2json.cpp
Normal file
47
Software/src/struct2json.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* @file struct2json.cpp
|
||||||
|
*
|
||||||
|
* @brief Implementation file for converting structs to JSON objects.
|
||||||
|
*
|
||||||
|
* @note This file is auto-generated by a script on 2024-01-09 20:41:57.
|
||||||
|
*
|
||||||
|
* @author Marcel Peterkau
|
||||||
|
* @date 09.01.2024
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "struct2json.h"
|
||||||
|
|
||||||
|
void generateJsonObject_LubeConfig(JsonObject& data)
|
||||||
|
{
|
||||||
|
data["EEPROM_Version"] = LubeConfig.EEPROM_Version;
|
||||||
|
data["DistancePerLube_Default"] = LubeConfig.DistancePerLube_Default;
|
||||||
|
data["DistancePerLube_Rain"] = LubeConfig.DistancePerLube_Rain;
|
||||||
|
data["tankCapacity_ml"] = LubeConfig.tankCapacity_ml;
|
||||||
|
data["amountPerDose_microL"] = LubeConfig.amountPerDose_microL;
|
||||||
|
data["TankRemindAtPercentage"] = LubeConfig.TankRemindAtPercentage;
|
||||||
|
data["PulsePerRevolution"] = LubeConfig.PulsePerRevolution;
|
||||||
|
data["TireWidth_mm"] = LubeConfig.TireWidth_mm;
|
||||||
|
data["TireWidthHeight_Ratio"] = LubeConfig.TireWidthHeight_Ratio;
|
||||||
|
data["RimDiameter_Inch"] = LubeConfig.RimDiameter_Inch;
|
||||||
|
data["DistancePerRevolution_mm"] = LubeConfig.DistancePerRevolution_mm;
|
||||||
|
data["BleedingPulses"] = LubeConfig.BleedingPulses;
|
||||||
|
data["SpeedSource"] = LubeConfig.SpeedSource;
|
||||||
|
data["GPSBaudRate"] = LubeConfig.GPSBaudRate;
|
||||||
|
data["CANSource"] = LubeConfig.CANSource;
|
||||||
|
data["LED_Mode_Flash"] = LubeConfig.LED_Mode_Flash;
|
||||||
|
data["LED_Max_Brightness"] = LubeConfig.LED_Max_Brightness;
|
||||||
|
data["LED_Min_Brightness"] = LubeConfig.LED_Min_Brightness;
|
||||||
|
data["checksum"] = LubeConfig.checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateJsonObject_PersistenceData(JsonObject& data)
|
||||||
|
{
|
||||||
|
data["writeCycleCounter"] = PersistenceData.writeCycleCounter;
|
||||||
|
data["tankRemain_microL"] = PersistenceData.tankRemain_microL;
|
||||||
|
data["TravelDistance_highRes_mm"] = PersistenceData.TravelDistance_highRes_mm;
|
||||||
|
data["odometer_mm"] = PersistenceData.odometer_mm;
|
||||||
|
data["odometer"] = PersistenceData.odometer;
|
||||||
|
data["checksum"] = PersistenceData.checksum;
|
||||||
|
}
|
||||||
|
|
@ -463,46 +463,14 @@ void WebServerEEJSON_Callback(AsyncWebServerRequest *request)
|
|||||||
fwinfo["Git-Hash"] = buffer;
|
fwinfo["Git-Hash"] = buffer;
|
||||||
|
|
||||||
JsonObject config = json.createNestedObject("config");
|
JsonObject config = json.createNestedObject("config");
|
||||||
|
generateJsonObject_LubeConfig(config);
|
||||||
config["EEPROM_Version"] = LubeConfig.EEPROM_Version;
|
JsonObject persis = json.createNestedObject("persis");
|
||||||
config["DistancePerLube_Default"] = LubeConfig.DistancePerLube_Default;
|
generateJsonObject_PersistenceData(persis);
|
||||||
config["DistancePerLube_Rain"] = LubeConfig.DistancePerLube_Rain;
|
|
||||||
config["tankCapacity_ml"] = LubeConfig.tankCapacity_ml;
|
|
||||||
config["amountPerDose_microL"] = LubeConfig.amountPerDose_microL;
|
|
||||||
config["TankRemindAtPercentage"] = LubeConfig.TankRemindAtPercentage;
|
|
||||||
config["PulsePerRevolution"] = LubeConfig.PulsePerRevolution;
|
|
||||||
config["TireWidth_mm"] = LubeConfig.TireWidth_mm;
|
|
||||||
config["TireWidthHeight_Ratio"] = LubeConfig.TireWidthHeight_Ratio;
|
|
||||||
config["RimDiameter_Inch"] = LubeConfig.RimDiameter_Inch;
|
|
||||||
config["DistancePerRevolution_mm"] = LubeConfig.DistancePerRevolution_mm;
|
|
||||||
config["BleedingPulses"] = LubeConfig.BleedingPulses;
|
|
||||||
config["SpeedSource"] = LubeConfig.SpeedSource;
|
|
||||||
config["SpeedSource_Str"] = SpeedSourceString[LubeConfig.SpeedSource];
|
|
||||||
config["GPSBaudRate"] = LubeConfig.GPSBaudRate;
|
|
||||||
config["GPSBaudRate_Str"] = GPSBaudRateString[LubeConfig.GPSBaudRate];
|
|
||||||
config["CANSource"] = LubeConfig.CANSource;
|
|
||||||
config["CANSource_Str"] = CANSourceString[LubeConfig.CANSource];
|
|
||||||
config["LED_Mode_Flash"] = LubeConfig.LED_Mode_Flash;
|
|
||||||
config["LED_Max_Brightness"] = LubeConfig.LED_Max_Brightness;
|
|
||||||
config["LED_Min_Brightness"] = LubeConfig.LED_Min_Brightness;
|
|
||||||
sprintf(buffer, "0x%08X", LubeConfig.checksum);
|
|
||||||
config["checksum"] = buffer;
|
|
||||||
|
|
||||||
JsonObject eepart = json.createNestedObject("eepart");
|
JsonObject eepart = json.createNestedObject("eepart");
|
||||||
|
|
||||||
sprintf(buffer, "0x%04X", globals.eePersistanceAdress);
|
sprintf(buffer, "0x%04X", globals.eePersistanceAdress);
|
||||||
eepart["PersistanceAddress"] = buffer;
|
eepart["PersistanceAddress"] = buffer;
|
||||||
|
|
||||||
JsonObject persis = json.createNestedObject("persis");
|
|
||||||
|
|
||||||
persis["writeCycleCounter"] = PersistenceData.writeCycleCounter;
|
|
||||||
persis["tankRemain_microL"] = PersistenceData.tankRemain_microL;
|
|
||||||
persis["TravelDistance_highRes_mm"] = PersistenceData.TravelDistance_highRes_mm;
|
|
||||||
persis["odometer_mm"] = PersistenceData.odometer_mm;
|
|
||||||
persis["odometer"] = PersistenceData.odometer;
|
|
||||||
sprintf(buffer, "0x%08X", PersistenceData.checksum);
|
|
||||||
persis["checksum"] = buffer;
|
|
||||||
|
|
||||||
serializeJsonPretty(json, *response);
|
serializeJsonPretty(json, *response);
|
||||||
|
|
||||||
response->addHeader("Content-disposition", "attachment; filename=backup.ee.json");
|
response->addHeader("Content-disposition", "attachment; filename=backup.ee.json");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user