55 Commits

Author SHA1 Message Date
367a41527d Updated FW-Version 2023-02-28 10:12:18 +01:00
5460a70f6d Added STL_Files for Case 2023-02-28 10:11:33 +01:00
3b4a22bff7 corrected some DTC-Stuff 2023-02-24 19:28:06 +01:00
df209a788b fixed Debug-Output in WebserverCallback (this time for real) 2023-02-24 19:25:59 +01:00
a6031798da moved DTC Processing to own File 2023-02-24 19:24:26 +01:00
00cba7b5ac DTC-Severity was not correctly set on new DTCs 2023-02-24 19:23:31 +01:00
034b6c918b fixed sysStat-Behaviour 2023-02-24 19:22:51 +01:00
3af678f3f8 fixed DebugOutput in WebserverCallback 2023-02-24 19:22:33 +01:00
32107a45db removed RemoteDebug-Library Stuff 2023-02-24 00:52:51 +01:00
a446a51c07 updated FastLED-Lib 2023-02-24 00:06:31 +01:00
5b41090add reworked debugger enabling 2023-02-24 00:05:51 +01:00
2376d14b5d fixed warning 2023-02-24 00:05:21 +01:00
77a94de2eb new debugger and websockets 2023-02-23 23:14:58 +01:00
c9a6e4c870 fixed warning 2023-02-23 17:46:36 +01:00
9ac161ee4c fixed Display-Bug with Remain Distance 2023-02-23 17:46:28 +01:00
1f8b085598 small improvement of DTC-Handling for CAN 2023-02-20 09:18:14 +01:00
46f98b1244 fixes... 2023-02-19 14:42:40 +01:00
9e87a05418 replaced var-name bc. encoding Issues with special char 2023-02-19 14:29:38 +01:00
140414ee8b minor FormatTweaks for DTC-DebugVal in WebUI 2022-09-02 00:10:21 +02:00
371e21429d WebUI adjusted and prepared EE-Backup-Stuff 2022-09-01 23:46:20 +02:00
64f9e102a5 Disabled autocorrect of Config after SanityCheck 2022-09-01 23:00:19 +02:00
dc4dbb05ca Format-Fixes and DTC-Debgval in WebUI visible 2022-09-01 22:47:25 +02:00
8c0db2ffd9 Implemented DebugVal for DTCs and SanityCheck 2022-09-01 22:46:00 +02:00
c6b47fffaf changed color of Bargraph-Text on WebUI 2022-09-01 21:31:27 +02:00
1b49ed4a2e Sanity-Check for ConfigValues 2022-09-01 21:29:07 +02:00
4167a222d7 ATOMIC_FS_UPDATE now Projecte-Define 2022-08-28 23:27:28 +02:00
f9498dac7d made FW-Version same Format as FS.Version 2022-08-28 23:27:01 +02:00
b9f658b111 FlashFS now gzip-Updatefiles & FS-Versioning imp. 2022-08-28 23:26:09 +02:00
4e34aaa24a Added Documentation 2022-08-24 23:13:27 +02:00
084925b844 missed include 2022-08-24 23:10:11 +02:00
e6a861185c Purging now also possible from WebUI 2022-08-24 23:09:26 +02:00
e12971b971 some debugging 2022-08-24 23:08:57 +02:00
4f5fdb7af4 corrected Tank-Lvel-Calculation 2022-08-24 23:08:29 +02:00
730f020f41 Updated DTC-Descriptions 2022-08-24 22:13:30 +02:00
3af1cfcb1b unimportant Serial Format Fix 2022-08-24 21:00:17 +02:00
685832cff8 Improved EEPROM-Formatting 2022-08-24 20:59:00 +02:00
3811834927 json now gets also gzipped 2022-08-24 20:58:12 +02:00
0025f8b0be DTC-Description now via Modal-Dialog 2022-08-24 16:49:40 +02:00
a30f56ff58 small fix 2022-08-24 07:30:51 +02:00
26942dd946 fixed missing name-tag in index.html 2022-08-24 07:27:53 +02:00
c997949c5b disabled Serial-debugging 2022-08-23 21:43:04 +02:00
1b0498ee5a fixed icons in manifest-File 2022-08-23 21:42:45 +02:00
82043ed9be re-added Firmware-Upload-Button after BS4-Update 2022-08-23 01:11:53 +02:00
f67817adb5 Format-Tweaks on WebUI 2022-08-23 00:50:52 +02:00
da19ebcc09 changed FlashVersion and incereased Buffer-Size 2022-08-23 00:48:00 +02:00
eaf2c9d8a8 DTC-Icon-fix 2022-08-23 00:12:03 +02:00
9072f2b3e2 added Google-Based Font locally 2022-08-23 00:11:44 +02:00
7d669dc04f updated .gitignore 2022-08-22 23:39:57 +02:00
79a7ca6fc1 renamed data-folder to data_src 2022-08-22 23:39:33 +02:00
821e94eec8 Updated WebUI to Bootstrap 4 2022-08-22 23:36:27 +02:00
0d9acaf43e preparing utility-script for gzip-littlefs 2022-08-22 23:32:51 +02:00
35361449eb some Fixes on Webui 2022-08-22 21:25:14 +02:00
45363b10fe missed ) on if-statement 2022-08-22 14:53:56 +02:00
c7f26bee32 made EEPROM-Format on WebUI more "secure" 2022-08-22 14:49:14 +02:00
984affb5a7 missed adjust of declaration for GetFlashVersion 2022-08-22 14:45:44 +02:00
66 changed files with 20219 additions and 921 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

1
Software/.gitignore vendored
View File

@@ -1,3 +1,4 @@
data/
.pio .pio
.vscode/.browse.c_cpp.db* .vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json .vscode/c_cpp_properties.json

View File

@@ -1,548 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>KTM CAN Chain Oiler</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="static/css/bootstrap.min.css">
<link rel="stylesheet" href="static/css/custom.css">
<script src="static/js/jquery.min.js"></script>
<script src="static/js/bootstrap.min.js"></script>
<link rel="apple-touch-icon" sizes="180x180" href="static/img/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="static/img/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="static/img/favicon-16x16.png">
<link rel="manifest" href="static/img/site.webmanifest">
</head>
<body>
<nav class="navbar navbar-expand-md navbar-default fixed-top">
<div class="navbar-header">
<a class="navbar-brand" href="#">
<img src="static/img/logo.png" width="30" height="30" class="d-inline-block align-top" alt="">
KTM CAN ChainLube
</a>
<button type="button" data-target="#navbarCollapse" data-toggle="collapse" class="navbar-toggle">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- Collection of nav links, forms, and other content for toggling -->
<div id="navbarCollapse" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a data-toggle="tab" href="#tab_home">Home</a></li>
<li><a data-toggle="tab" href="#tab_source">Wegstrecke</a></li>
<li><a data-toggle="tab" href="#tab_lube">Schmierung</a></li>
<li><a data-toggle="tab" href="#tab_tank">Öltank</a></li>
<li><a data-toggle="tab" href="#tab_maintenance">Wartung</a></li>
<li><a data-toggle="tab" href="#tab_sysinfo">Systeminfo</a></li>
<li><a data-toggle="tab" href="#tab_fwupdate">Update</a></li>
</ul>
</div>
</nav>
<main class="container">
<!-- Tabs Content -->
<div class="tab-content">
<!-- Div Tab Home-->
<div id="tab_home" class="tab-pane fade in active">
<div class="col text-center">
<div class="jumbotron">
<img src="static/img/logo.png" width="120" height="120" class="img-fluid" alt="">
<h3>KTM CAN Chain Lube</h3>
</div>
</div>
<p>
<h4>Tankinhalt verbleibend</h4>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="%TANK_REMAIN_CAPACITY%" aria-valuemin="0"
aria-valuemax="100" style="width: %TANK_REMAIN_CAPACITY%&#37;">
%TANK_REMAIN_CAPACITY%&#37;
</div>
</div>
<h4>aktueller Modus</h4>
<input class="form-control" type="text" placeholder="%SYSTEM_STATUS%" readonly>
<div %SHOW_DTC_TABLE%>
<h4>Fehlercodes</h4>
<table class="table">
<tbody>
<tr>
<th class="col-md-3" scope="col">Zeitstempel</th>
<th class="col-md-3" scope="col">Fehlercode</th>
<th class="col-md-3" scope="col">Schwere</th>
<th class="col-md-3" scope="col">Aktiv</th>
</tr>
%DTC_TABLE%
</tbody>
</table>
<p>
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#collapseDTCDescription"
aria-expanded="false" aria-controls="collapseDTCDescription">
DTC Beschreibung
</button>
</p>
<div class="collapse" id="collapseDTCDescription">
<div class="card card-body">
<embed type="text/html" src="static/dtc.txt" width="100&#37;">
</div>
</div>
</div>
</p>
</div>
<!-- Div Tab Home-->
<!-- Div Tab Source Settings-->
<div id="tab_source" class="tab-pane fade">
<h3>Erfassung Wegstrecke</h3>
<hr>
<p>
<form action="\post.htm" method="POST" class="form-horizontal">
<div class="form-group">
<label for="sourceselect" class="control-label col-xs-5">Wegstrecke Quelle</label>
<div class="col-xs-7">
<select id="sourceselect" name="sourceselect" class="select form-control">
%SOURCE_SELECT_OPTIONS%
</select>
</div>
</div>
<div class="form-group row">
<div class="col-xs-offset-5 col-xs-7">
<button name="sourcesave" type="submit" class="btn btn-primary">&Uuml;bernehmen</button>
</div>
</div>
</form>
</p>
<div class="alert alert-warning">
<strong>Achtung!</strong><br>
Bei Änderung der Wegstrecken-Quelle wird der CAN-Oiler neu gestartet.
Dadurch wird die WiFi-Verbindung getrennt und muss neu aufgebaut werden.
</div>
<!-- Div Source:Impulse Settings-->
<div %SHOW_IMPULSE_SETTINGS%>
<h4>Einstellungen Impuls</h4>
<p>
<form action="\post.htm" method="POST" class="form-horizontal">
<div class="form-group">
<label for="tirewidth" class="control-label col-xs-5">Reifenbreite</label>
<div class="col-xs-7">
<div class="input-group">
<input id="tirewidth" name="tirewidth" type="text" required="required" class="form-control"
value="%TIRE_WIDTH_MM%">
<div class="input-group-addon">mm</div>
</div>
</div>
</div>
<div class="form-group">
<label for="tireratio" class="control-label col-xs-5">Höhe/Breite-Verhältniss</label>
<div class="col-xs-7">
<div class="input-group">
<input id="tireratio" name="tireratio" type="text" required="required" class="form-control"
value="%TIRE_RATIO%">
<div class="input-group-addon"></div>
</div>
</div>
</div>
<div class="form-group">
<label for="tiredia" class="control-label col-xs-5">Felgendurchmesser</label>
<div class="col-xs-7">
<div class="input-group">
<input id="tiredia" name="tiredia" type="text" required="required" class="form-control"
value="%RIM_DIAMETER%">
<div class="input-group-addon">"</div>
</div>
</div>
</div>
<div class="form-group">
<label for="pulserev" class="control-label col-xs-5">Pulse pro Umdrehung</label>
<div class="col-xs-7">
<div class="input-group">
<input id="pulserev" name="pulserev" type="text" required="required" class="form-control"
value="%PULSE_PER_REV%">
<div class="input-group-addon"></div>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-xs-offset-5 col-xs-7">
<button name="pulsesave" type="submit" class="btn btn-primary">Speichern</button>
</div>
</div>
</form>
</p>
</div>
<!-- Div Source:Impulse Settings-->
<!-- Div Source:CAN Settings-->
<div %SHOW_CAN_SETTINGS%>
<h4>Einstellungen CAN-Bus</h4>
<p>
<form action="\post.htm" method="POST" class="form-horizontal">
<div class="form-group">
<label for="cansource" class="control-label col-xs-5">Model</label>
<div class="col-xs-7">
<select id="cansource" name="cansource" class="select form-control">
%CANSOURCE_SELECT_OPTIONS%
</select>
</div>
</div>
<div class="form-group row">
<div class="col-xs-offset-5 col-xs-7">
<button name="cansave" type="submit" class="btn btn-primary">Speichern</button>
</div>
</div>
</form>
</p>
</div>
<!-- Div Source:CAN Settings-->
<!-- Div Source:GPS Settings-->
<div %SHOW_GPS_SETTINGS%>
<h4>Einstellungen GPS</h4>
<p>
<form action="\post.htm" method="POST" class="form-horizontal">
<div class="form-group">
<label for="gpsbaud" class="control-label col-xs-5">Baudrate</label>
<div class="col-xs-7">
<select id="gpsbaud" name="gpsbaud" class="select form-control">
%GPSBAUD_SELECT_OPTIONS%
</select>
</div>
</div>
<div class="form-group row">
<div class="col-xs-offset-5 col-xs-7">
<button name="gpssave" type="submit" class="btn btn-primary">Speichern</button>
</div>
</div>
</form>
</p>
</div>
<!-- Div Source:GPS Settings-->
</div>
<!-- Div Tab Source Settings-->
<!-- Div Tab Lube -->
<div id="tab_lube" class="tab-pane fade">
<h3>Schmierung</h3>
<hr>
<p>
<form action="\post.htm" method="POST" class="form-horizontal">
<div class="form-group">
<label for="lubedistancenormal" class="control-label col-xs-5">Modus:normal</label>
<div class="col-xs-7">
<div class="input-group">
<input id="lubedistancenormal" name="lubedistancenormal" value="%LUBE_DISTANCE_NORMAL%" type="text"
class="form-control" required="required">
<div class="input-group-addon">m</div>
</div>
</div>
</div>
<div class="form-group">
<label for="lubedistancerain" class="control-label col-xs-5">Modus:rain</label>
<div class="col-xs-7">
<div class="input-group">
<input id="lubedistancerain" name="lubedistancerain" value="%LUBE_DISTANCE_RAIN%" type="text"
class="form-control" required="required">
<div class="input-group-addon">m</div>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-xs-offset-5 col-xs-7">
<button name="oilsave" type="submit" class="btn btn-primary">Speichern</button>
</div>
</div>
</form>
</p>
</div>
<!-- Div Tab Lube -->
<!-- Div Tab Maintenance -->
<div id="tab_maintenance" class="tab-pane fade">
<h3>Wartung</h3>
<hr>
<p>
<h4>&Ouml;lvorrat</h4>
<form action="\post.htm" method="POST" class="form-horizontal">
<div class="form-group">
<label for="tankremain_maint" class="control-label col-xs-5">Tankinhalt verbleibend</label>
<div class="col-xs-7">
<div class="progress">
<div id="tankremain_maint" class="progress-bar" role="progressbar"
aria-valuenow="%TANK_REMAIN_CAPACITY%" aria-valuemin="0" aria-valuemax="100"
style="width: %TANK_REMAIN_CAPACITY%&#37;">
%TANK_REMAIN_CAPACITY%&#37;
</div>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-xs-offset-5 col-xs-7">
<button name="resettank" type="submit" class="btn btn-primary">Tank zurücksetzen</button>
</div>
</div>
</form>
</p>
<hr>
<p>
<h4>Entl&uuml;ftung</h4>
<form action="\post.htm" method="POST" class="form-horizontal">
<div class="form-group">
<label for="purgepulse" class="control-label col-xs-5">Entl&uuml;ftung Dosierung</label>
<div class="col-xs-7">
<div class="input-group">
<input id="purgepulse" name="purgepulse" value="%BLEEDING_PULSES%" type="text" class="form-control">
<div class="input-group-addon">Pulse</div>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-xs-offset-5 col-xs-7">
<button name="maintsave" type="submit" class="btn btn-primary">Speichern</button>
</div>
</div>
</form>
</p>
<hr>
<h4>EEPROM</h4>
<p>
<form action="\post.htm" method="POST" class="form-horizontal">
<div class="form-group">
<div class="col-xs-offset-5 col-xs-7">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="reset_ee_cfg_check">
<label class="form-check-label" for="reset_ee_cfg_check">
JA, EEPROM-Bereich "CFG" formatieren und Konfiguration zurück setzen
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="reset_ee_pds_check">
<label class="form-check-label" for="reset_ee_pds_check">
JA, EEPROM-Bereich "PDS" formatieren und Betriebsdaten zurück setzen
</label>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-xs-offset-5 col-xs-7">
<button name="reset_ee_btn" type="submit" class="btn btn-primary">EEPROM formatieren</button>
</div>
</div>
</form>
</p>
</div>
<!-- Div Tab Maintenance -->
<!-- Div Tank Settings-->
<div id="tab_tank" class="tab-pane fade">
<h3>Öltank</h3>
<hr>
<p>
<form action="\post.htm" method="POST" class="form-horizontal">
<div class="form-group">
<label for="tankcap" class="control-label col-xs-5">Tankkapazität</label>
<div class="col-xs-7">
<div class="input-group">
<input id="tankcap" name="tankcap" value="%TANK_CAPACITY%" type="text" class="form-control"
required="required">
<div class="input-group-addon">ml</div>
</div>
</div>
</div>
<div class="form-group">
<label for="tankwarn" class="control-label col-xs-5">Leer-Warnung</label>
<div class="col-xs-7">
<div class="input-group">
<input id="tankwarn" name="tankwarn" value="%TANK_REMIND%" type="text" class="form-control"
required="required">
<div class="input-group-addon">&#37;</div>
</div>
</div>
</div>
<div class="form-group">
<label for="pumppulse" class="control-label col-xs-5">Menge pro Puls</label>
<div class="col-xs-7">
<div class="input-group">
<input id="pumppulse" name="pumppulse" value="%AMOUNT_PER_DOSE%" type="text" class="form-control"
required="required">
<div class="input-group-addon">µl</div>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-xs-offset-5 col-xs-7">
<button name="oilsave" type="submit" class="btn btn-primary">Speichern</button>
</div>
</div>
</form>
</p>
</div>
<!-- Div Tank Settings-->
<!-- Div Tab SystemInfo -->
<div id="tab_sysinfo" class="tab-pane fade">
<h3>Systeminfo</h3>
<hr>
<h4>Einstellungen</h4>
<p>
<table class="table">
<tbody>
<tr>
<th class="col-md-8" scope="col">Parameter</td>
<th class="col-md-4" scope="col">Value</td>
</tr>
<tr>
<td>DistancePerLube_Default</td>
<td>%LUBE_DISTANCE_NORMAL%</td>
</tr>
<tr>
<td>DistancePerLube_Rain</td>
<td>%LUBE_DISTANCE_RAIN%</td>
</tr>
<tr>
<td>tankCapacity_ml</td>
<td>%TANK_CAPACITY%</td>
</tr>
<tr>
<td>amountPerDose_&micro;l</td>
<td>%AMOUNT_PER_DOSE%</td>
</tr>
<tr>
<td>TankRemindAtPercentage</td>
<td>%TANK_REMIND%</td>
</tr>
<tr>
<td>PulsePerRevolution</td>
<td>%PULSE_PER_REV%</td>
</tr>
<tr>
<td>TireWidth_mm</td>
<td>%TIRE_WIDTH_MM%</td>
</tr>
<tr>
<td>TireWidthHeight_Ratio</td>
<td>%TIRE_RATIO%</td>
</tr>
<tr>
<td>RimDiameter_Inch</td>
<td>%RIM_DIAMETER%</td>
</tr>
<tr>
<td>DistancePerRevolution_mm</td>
<td>%DISTANCE_PER_REV%</td>
</tr>
<tr>
<td>BleedingPulses</td>
<td>%BLEEDING_PULSES%</td>
</tr>
<tr>
<td>SpeedSource</td>
<td>%SPEED_SOURCE%</td>
</tr>
<tr>
<td>GPSBaudRate</td>
<td>%GPS_BAUD%</td>
</tr>
<tr>
<td>CANSource</td>
<td>%CAN_SOURCE%</td>
</tr>
<tr>
<td>Checksum</td>
<td>%CONFIG_CHECKSUM%</td>
</tr>
</tbody>
</table>
</p>
<h4>Betriebsdaten</h4>
<p>
<table class="table">
<tbody>
<tr>
<th class="col-md-8" scope="col">Parameter</td>
<th class="col-md-4" scope="col">Value</td>
</tr>
<tr>
<td>writeCycleCounter</td>
<td>%WRITE_CYCLE_COUNT%</td>
</tr>
<tr>
<td>PersistenceMarker</td>
<td>%PERSISTENCE_MARKER%</td>
</tr>
<tr>
<td>tankRemain_µl</td>
<td>%TANK_REMAIN_UL%</td>
</tr>
<tr>
<td>TravelDistance_highRes</td>
<td>%TRAVEL_DISTANCE_HIGHRES%</td>
</tr>
<tr>
<td>Odometer</td>
<td>%ODOMETER%,%ODOMETER_M%</td>
</tr>
<tr>
<td>checksum</td>
<td>%PERSISTANCE_CHECKSUM%</td>
</tr>
</table>
</p>
</div>
<!-- Div Tab SystemInfo -->
<!-- Div Tab Firmware Update-->
<div id="tab_fwupdate" class="tab-pane fade">
<h3>Firmware Update</h3>
<hr>
<h4>Version-Info</h4>
<table class="table">
<tbody>
<tr>
<td>Firmware Version</td>
<td>%SW_VERSION%</td>
</tr>
<tr>
<td>Flash Version</td>
<td>%FS_VERSION%</td>
</tr>
</table>
<hr>
<h4>Firmware-Update</h4>
<form method='POST' action='/doUpdate' enctype='multipart/form-data'>
<div class="form-group">
<label for="fw-update-file" class="col-sm-2 col-form-label">Firmware-File</label>
<div class="col-xs-7">
<div class="input-group">
<input id="fw-update-file" name="fw-update-file" type="file" class="form-control-file"
required="required">
</div>
<div class="form-group row">
<div class="col-xs-offset-5 col-xs-7">
<button name="fw-update" type="submit" class="btn btn-primary">Aktualisieren</button>
</div>
</div>
</div>
</form>
</div>
<!-- Div Tab Firmware Update-->
</div>
<!-- Tabs Content -->
</main>
<!-- Footer -->
<footer class="navbar-default navbar-fixed-bottom">
<div class="container-fluid">
<!-- Copyright -->
<div class="col text-center">
© 2022 Copyright:
<a class="text-reset fw-bold" href="https://eventronics.de/">Marcel Peterkau</a>
</div>
<!-- Copyright -->
</div>
</footer>
<!-- Footer -->
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
kbd{border:1px solid #333}.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-color:#6a6a6a;border-color:#636363}.btn-default:hover{background-color:#6a6a6a}.btn-primary:hover{background-color:#404040}.btn-success:hover{background-color:#3d8b3d}.btn-info:hover{background-color:#28a1c5}.btn-danger:hover{background-color:#b52b27}.btn-warning:hover{background-color:#df8a13}.navbar-default .navbar-nav>li.active>a:hover{background-color:#222}.navbar-inverse .navbar-nav>li.active>a:hover{background-color:#444}.table{color:#fff}.table .primary,.table .info,.table .success,.table .warning,.table .danger{color:#fff}.table-hover tr:hover{cursor:pointer}.input-group-addon{color:#fff}.nav>li>a:hover{color:#fff}.pager>li>a:hover{color:#fff}a:focus{outline:0}a.list-group-item.active:hover{background-color:#4d4d4d}a.list-group-item-success,a.list-group-item-info,a.list-group-item-warning,a.list-group-item-danger,a.list-group-item-success:hover,a.list-group-item-info:hover,a.list-group-item-warning:hover,a.list-group-item-danger:hover{color:#fff}a.active.list-group-item-success,a.active.list-group-item-info,a.active.list-group-item-warning,a.active.list-group-item-danger,a.active.list-group-item-success:hover,a.active.list-group-item-info:hover,a.active.list-group-item-warning:hover,a.active.list-group-item-danger:hover{border-color:#666}a.active.list-group-item-success:hover{background-color:#3d8b3d}a.active.list-group-item-info:hover{background-color:#28a1c5}a.active.list-group-item-warning:hover{background-color:#df8a13}a.active.list-group-item-danger:hover{background-color:#b52b27}.list-group-item-success,.list-group-item-info,.list-group-item-warning,.list-group-item-danger{color:#fff}.alert-info,.alert-primary,.alert-warning,.alert-danger,.alert-success{color:#fff}.alert-info .alert-link,.alert-primary .alert-link,.alert-warning .alert-link,.alert-danger .alert-link,.alert-success .alert-link{color:#fff}

View File

@@ -1,12 +0,0 @@
1 - TANK_EMPTY
2 - DTC_TANK_LOW
3 - DTC_NO_EEPROM_FOUND
4 - DTC_EEPROM_CFG_BAD
5 - DTC_EEPROM_PDS_BAD
6 - DTC_EEPROM_PDSADRESS_BAD
7 - DTC_EEPROM_VERSION_BAD
8 - DTC_FLASHFS_ERROR
9 - DTC_FLASHFS_VERSION_ERROR
10 - DTC_NO_GPS_SERIAL
11 - DTC_CAN_TRANSCEIVER_FAILED
12 - DTC_NO_CAN_SIGNAL

View File

@@ -1 +0,0 @@
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
1

696
Software/data_src/index.htm Normal file
View File

@@ -0,0 +1,696 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>KTM CAN Chain Oiler</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="static/css/bootstrap.min.css">
<link rel="stylesheet" href="static/css/custom.css">
<link rel="stylesheet" href="static/css/tweaks.css">
<script src="static/js/jquery.min.js"></script>
<script src="static/js/bootstrap.min.js"></script>
<script src="static/js/websocket.js"></script>
<link rel="apple-touch-icon" sizes="180x180" href="static/img/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="static/img/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="static/img/favicon-16x16.png">
<link rel="manifest" href="static/img/site.webmanifest">
</head>
<body>
<nav class="navbar fixed-top navbar-dark bg-primary" id="navbar1">
<a class="navbar-brand" href="#">
<img src="static/img/logo.png" width="30" height="30" class="d-inline-block align-top mr-1" alt="">
KTM CAN ChainLube
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsingNavbar"
aria-controls="collapsingNavbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsingNavbar">
<ul class="navbar-nav nav mr-auto mt-2 mt-lg-0">
<li class="nav-item"><a class="nav-link active" role="tab" data-toggle="tab" href="#tab_home">Home</a></li>
<li class="nav-item"><a class="nav-link" role="tab" data-toggle="tab" href="#tab_source">Wegstrecke</a></li>
<li class="nav-item"><a class="nav-link" role="tab" data-toggle="tab" href="#tab_lube">Schmierung</a></li>
<li class="nav-item"><a class="nav-link" role="tab" data-toggle="tab" href="#tab_maintenance">Wartung</a></li>
<li class="nav-item"><a class="nav-link" role="tab" data-toggle="tab" href="#tab_sysinfo">Systeminfo</a></li>
<li class="nav-item"><a class="nav-link" role="tab" data-toggle="tab" href="#tab_fwupdate">Update</a></li>
</ul>
</div>
</nav>
<main class="container">
<!-- Tabs Content -->
<div class="tab-content">
<!-- Div Tab Home-->
<div id="tab_home" class="tab-pane fade show active" role="tabpanel">
<div class="col text-center">
<div class="jumbotron">
<img src="static/img/logo.png" width="120" height="120" class="img-fluid" alt="">
<h3 class="pt-3">KTM CAN Chain Lube</h3>
</div>
</div>
<hr />
<p>
<h4>Tankinhalt verbleibend</h4>
<div class="progress">
<div class="progress-bar text-light" role="progressbar" aria-valuenow="%TANK_REMAIN_CAPACITY%"
aria-valuemin="0" aria-valuemax="100" style="width: %TANK_REMAIN_CAPACITY%&#37;">
%TANK_REMAIN_CAPACITY%&#37;
</div>
</div>
</p>
<hr />
<p>
<h4>aktueller Modus</h4>
<input class="form-control" type="text" placeholder="%SYSTEM_STATUS%" readonly>
</p>
<hr />
<div %SHOW_DTC_TABLE%>
<p>
<h4>Fehlercodes</h4>
<table class="table">
<tbody>
<tr>
<th class="col-6" scope="col">Zeitstempel</th>
<th class="col-2" scope="col">Fehlercode</th>
<th class="col-2" scope="col">Schwere</th>
<th class="col-2" scope="col">Aktiv</th>
</tr>
%DTC_TABLE%
</tbody>
</table>
</p>
<hr />
</div>
</div>
<!-- Div Tab Home-->
<!-- Div Tab Source Settings-->
<div id="tab_source" class="tab-pane fade" role="tabpanel">
<h3>Wegstreckenerfassung</h3>
<hr />
<p>
<h4>Signalquelle</h4>
<form action="post.htm" method="POST" class="form-horizontal">
<div class="form-group row">
<label for="sourceselect" class="control-label col-4">Schnittstelle</label>
<div class="col-8">
<select id="sourceselect" name="sourceselect" class="select form-control">
%SOURCE_SELECT_OPTIONS%
</select>
</div>
</div>
<div class="alert alert-primary alert-dismissable show fade" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<strong>Achtung!</strong><br>
Bei Änderung der Signalquelle wird der CAN-Oiler neu gestartet.
Dadurch wird die WiFi-Verbindung getrennt und muss neu aufgebaut werden.
</div>
<div class="form-group row">
<div class="col text-center">
<button name="sourcesave" type="submit" class="btn btn-outline-primary">&Uuml;bernehmen</button>
</div>
</div>
</form>
</p>
<!-- Div Source:Impulse Settings-->
<div %SHOW_IMPULSE_SETTINGS%>
<hr />
<p>
<h4>Einstellungen Impulseingang</h4>
<form action="post.htm" method="POST" class="form-horizontal">
<div class="form-group row">
<label for="tirewidth" class="control-label col-4">Reifenbreite</label>
<div class="col-8">
<div class="input-group">
<input id="tirewidth" name="tirewidth" type="text" required="required" class="form-control"
value="%TIRE_WIDTH_MM%">
<div class="input-group-append">
<span class="input-group-text">mm</span>
</div>
</div>
</div>
</div>
<div class="form-group row">
<label for="tireratio" class="control-label col-4">Höhe/Breite-Verhältniss</label>
<div class="col-8">
<div class="input-group">
<input id="tireratio" name="tireratio" type="text" required="required" class="form-control"
value="%TIRE_RATIO%">
<div class="input-group-append">
<span class="input-group-text">mm</span>
</div>
</div>
</div>
</div>
<div class="form-group row">
<label for="tiredia" class="control-label col-4">Felgendurchmesser</label>
<div class="col-8">
<div class="input-group">
<input id="tiredia" name="tiredia" type="text" required="required" class="form-control"
value="%RIM_DIAMETER%">
<div class="input-group-append">
<span class="input-group-text">"</span>
</div>
</div>
</div>
</div>
<div class="form-group row">
<label for="pulserev" class="control-label col-4">Pulse pro Umdrehung</label>
<div class="col-8">
<div class="input-group">
<input id="pulserev" name="pulserev" type="text" required="required" class="form-control"
value="%PULSE_PER_REV%">
<div class="input-group-addon"></div>
</div>
</div>
</div>
<div class="form-group row">
<div class="col text-center">
<button name="pulsesave" type="submit" class="btn btn-outline-primary">Speichern</button>
</div>
</div>
</form>
</p>
<hr />
</div>
<!-- Div Source:Impulse Settings-->
<!-- Div Source:CAN Settings-->
<div %SHOW_CAN_SETTINGS%>
<hr />
<p>
<h4>Einstellungen CAN-Bus</h4>
<form action="post.htm" method="POST" class="form-horizontal">
<div class="form-group row">
<label for="cansource" class="control-label col-4">Model</label>
<div class="col-8">
<select id="cansource" name="cansource" class="select form-control">
%CANSOURCE_SELECT_OPTIONS%
</select>
</div>
</div>
<div class="form-group row">
<div class="col text-center">
<button name="cansave" type="submit" class="btn btn-outline-primary">Speichern</button>
</div>
</div>
</form>
</p>
<hr />
</div>
<!-- Div Source:CAN Settings-->
<!-- Div Source:GPS Settings-->
<div %SHOW_GPS_SETTINGS%>
<hr />
<p>
<h4>Einstellungen GPS</h4>
<form action="post.htm" method="POST" class="form-horizontal">
<div class="form-group row">
<label for="gpsbaud" class="control-label col-4">Baudrate</label>
<div class="col-8">
<select id="gpsbaud" name="gpsbaud" class="select form-control">
%GPSBAUD_SELECT_OPTIONS%
</select>
</div>
</div>
<div class="form-group row">
<div class="col text-center">
<button name="gpssave" type="submit" class="btn btn-outline-primary">Speichern</button>
</div>
</div>
</form>
</p>
<hr />
</div>
<!-- Div Source:GPS Settings-->
</div>
<!-- Div Tab Source Settings-->
<!-- Div Tab Lube -->
<div id="tab_lube" class="tab-pane fade" role="tabpanel">
<h3>Schmierung</h3>
<hr />
<p>
<h4>Dosierung</h4>
<form action="post.htm" method="POST" class="form-horizontal">
<div class="form-group row">
<label for="lubedistancenormal" class="control-label col-4">Normal (gr&uuml;n)</label>
<div class="col-8">
<div class="input-group">
<input id="lubedistancenormal" name="lubedistancenormal" value="%LUBE_DISTANCE_NORMAL%" type="text"
class="form-control" required="required">
<div class="input-group-append">
<span class="input-group-text">m</span>
</div>
</div>
</div>
</div>
<div class="form-group row">
<label for="lubedistancerain" class="control-label col-4">Regen (blau)</label>
<div class="col-8">
<div class="input-group">
<input id="lubedistancerain" name="lubedistancerain" value="%LUBE_DISTANCE_RAIN%" type="text"
class="form-control" required="required">
<div class="input-group-append">
<span class="input-group-text">m</span>
</div>
</div>
</div>
</div>
<div class="form-group row">
<div class="col text-center">
<button name="oilsave" type="submit" class="btn btn-outline-primary">Speichern</button>
</div>
</div>
</form>
</p>
<hr />
</div>
<!-- Div Tab Lube -->
<!-- Div Tab Maintenance -->
<div id="tab_maintenance" class="tab-pane fade" role="tabpanel">
<h3>Wartung</h3>
<hr />
<p>
<h4>&Ouml;lvorrat</h4>
<form action="post.htm" method="POST" class="form-horizontal">
<div class="form-group row">
<label for="tankcap" class="control-label col-4">Tankkapazität</label>
<div class="col-8">
<div class="input-group">
<input id="tankcap" name="tankcap" value="%TANK_CAPACITY%" type="text" class="form-control"
required="required">
<div class="input-group-append">
<span class="input-group-text">ml</span>
</div>
</div>
</div>
</div>
<div class="form-group row">
<label for="tankwarn" class="control-label col-4">Leer-Warnung</label>
<div class="col-8">
<div class="input-group">
<input id="tankwarn" name="tankwarn" value="%TANK_REMIND%" type="text" class="form-control"
required="required">
<div class="input-group-append">
<span class="input-group-text">&#37;</span>
</div>
</div>
</div>
</div>
<div class="form-group row">
<label for="pumppulse" class="control-label col-4">Menge pro Puls</label>
<div class="col-8">
<div class="input-group">
<input id="pumppulse" name="pumppulse" value="%AMOUNT_PER_DOSE%" type="text" class="form-control"
required="required">
<div class="input-group-append">
<span class="input-group-text">µl</span>
</div>
</div>
</div>
</div>
<div class="form-group row">
<label for="tankremain_maint" class="control-label col-4">Tankinhalt verbleibend</label>
<div class="col-8">
<div class="progress">
<div id="tankremain_maint" class="progress-bar text-light" role="progressbar"
aria-valuenow="%TANK_REMAIN_CAPACITY%" aria-valuemin="0" aria-valuemax="100"
style="width: %TANK_REMAIN_CAPACITY%&#37;">
%TANK_REMAIN_CAPACITY%&#37;
</div>
</div>
</div>
</div>
<div class="form-group row">
<div class="col text-center">
<button name="oilsave" type="submit" class="btn btn-outline-primary">Speichern</button>
<button name="resettank" type="submit" class="btn btn-outline-primary ml-2">Tank zurücksetzen</button>
</div>
</div>
</form>
</p>
<hr />
<p>
<h4>Entl&uuml;ftung</h4>
<form action="post.htm" method="POST" class="form-horizontal">
<div class="form-group row">
<label for="purgepulse" class="control-label col-4">Entl&uuml;ftung Dosierung</label>
<div class="col-8">
<div class="input-group">
<input id="purgepulse" name="purgepulse" value="%BLEEDING_PULSES%" type="text" class="form-control">
<div class="input-group-append">
<span class="input-group-text">Pulse</span>
</div>
</div>
</div>
</div>
<div class="form-group row">
<div class="col text-center">
<button name="maintsave" type="submit" class="btn btn-outline-primary">Speichern</button>
<button name="purgenow" type="submit" class="btn btn-outline-primary ml-2">Entlüftung starten</button>
</div>
</div>
</form>
</p>
<hr />
<p>
<h4>EEPROM formatieren</h4>
<div class="alert alert-primary alert-dismissable show fade" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<strong>Achtung!</strong><br>
Das Formatieren der EEPROM-Bereiche sollte nur ausgeführt werden wenn es unbedingt erforderlich ist!
Hierdurch werden alle Einstellungen zurück gesetzt bzw. alle Betriebsdaten gehen verloren.
Folgende Situationen erfordern unter anderem eine Formatierung:
- Erstinitialisierung (bei neu aufgebautem Gerät)
- Firmware-Update (nur wenn es die Release-Notes fordern)
</div>
<form action="post.htm" method="POST" class="form-horizontal">
<div class="form-group row">
<div class="offset-4 col-8">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="reset_ee_cfg" id="reset_ee_cfg">
<label class="form-check-label" for="reset_ee_cfg">
Bereich "CFG"
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="reset_ee_pds" id="reset_ee_pds">
<label class="form-check-label" for="reset_ee_pds">
Bereich "PDS"
</label>
</div>
</div>
</div>
<div class="form-group row">
<div class="col text-center">
<button name="reset_ee_btn" type="submit" class="btn btn-outline-primary">EEPROM formatieren</button>
</div>
</div>
</form>
</p>
<hr />
<p>
<h4>Ger&auml;t neustarten</h4>
<form action="post.htm" method="POST" class="form-horizontal">
<div class="form-group row">
<div class="col text-center">
<button name="reboot" type="submit" class="btn btn-outline-primary">Reboot</button>
</div>
</div>
</form>
</p>
<hr />
</div>
<!-- Div Tab Maintenance -->
<!-- Div Tab SystemInfo -->
<div id="tab_sysinfo" class="tab-pane fade" role="tabpanel">
<h3>Systeminfo</h3>
<hr />
<p>
<h4>Einstellungen</h4>
<table class="table">
<tbody>
<tr>
<th class="col-7" scope="col">Parameter</td>
<th class="col-5" scope="col">Value</td>
</tr>
<tr>
<td>DistancePerLube_Default</td>
<td>%LUBE_DISTANCE_NORMAL%</td>
</tr>
<tr>
<td>DistancePerLube_Rain</td>
<td>%LUBE_DISTANCE_RAIN%</td>
</tr>
<tr>
<td>tankCapacity_ml</td>
<td>%TANK_CAPACITY%</td>
</tr>
<tr>
<td>amountPerDose_&micro;l</td>
<td>%AMOUNT_PER_DOSE%</td>
</tr>
<tr>
<td>TankRemindAtPercentage</td>
<td>%TANK_REMIND%</td>
</tr>
<tr>
<td>PulsePerRevolution</td>
<td>%PULSE_PER_REV%</td>
</tr>
<tr>
<td>TireWidth_mm</td>
<td>%TIRE_WIDTH_MM%</td>
</tr>
<tr>
<td>TireWidthHeight_Ratio</td>
<td>%TIRE_RATIO%</td>
</tr>
<tr>
<td>RimDiameter_Inch</td>
<td>%RIM_DIAMETER%</td>
</tr>
<tr>
<td>DistancePerRevolution_mm</td>
<td>%DISTANCE_PER_REV%</td>
</tr>
<tr>
<td>BleedingPulses</td>
<td>%BLEEDING_PULSES%</td>
</tr>
<tr>
<td>SpeedSource</td>
<td>%SPEED_SOURCE%</td>
</tr>
<tr>
<td>GPSBaudRate</td>
<td>%GPS_BAUD%</td>
</tr>
<tr>
<td>CANSource</td>
<td>%CAN_SOURCE%</td>
</tr>
<tr>
<td>Checksum</td>
<td>%CONFIG_CHECKSUM%</td>
</tr>
</tbody>
</table>
</p>
<hr />
<p>
<h4>Betriebsdaten</h4>
<table class="table">
<tbody>
<tr>
<th class="col-7" scope="col">Parameter</td>
<th class="col-5" scope="col">Value</td>
</tr>
<tr>
<td>writeCycleCounter</td>
<td>%WRITE_CYCLE_COUNT%</td>
</tr>
<tr>
<td>PersistenceMarker</td>
<td>%PERSISTENCE_MARKER%</td>
</tr>
<tr>
<td>tankRemain_µl</td>
<td>%TANK_REMAIN_UL%</td>
</tr>
<tr>
<td>TravelDistance_highRes</td>
<td>%TRAVEL_DISTANCE_HIGHRES%</td>
</tr>
<tr>
<td>Odometer</td>
<td>%ODOMETER%,%ODOMETER_M%</td>
</tr>
<tr>
<td>checksum</td>
<td>%PERSISTANCE_CHECKSUM%</td>
</tr>
</table>
</p>
<hr />
<p>
<h4>Live Debug</h4>
<div class="form-group row">
<textarea class="form-control" spellcheck="false" id="livedebug-out" rows="3" readonly></textarea>
</div>
<div class="form-group row">
<div class="col text-center">
<button id="btn-ws-start" class="btn btn-outline-primary">Start</button>
<button id="btn-ws-stop" class="btn btn-outline-primary ml-2">Stop</button>
</div>
</div>
</p>
<hr />
</div>
<!-- Div Tab SystemInfo -->
<!-- Div Tab Firmware Update-->
<div id="tab_fwupdate" class="tab-pane fade" role="tabpanel">
<h3>Firmware</h3>
<hr />
<p>
<h4>Version-Info</h4>
<table class="table">
<tbody>
<tr>
<th class="col-7" scope="col">Parameter</td>
<th class="col-5" scope="col">Value</td>
</tr>
<tr>
<td>Firmware Version</td>
<td>%SW_VERSION%</td>
</tr>
<tr>
<td>Flash Version</td>
<td>%FS_VERSION%</td>
</tr>
</table>
</p>
<hr />
<p>
<h4>EEPROM-Backup</h4>
<div class="form-group row">
<div class="col text-center">
<a class="btn btn-outline-primary" href="eejson" role="button" id="ee-backup-download">Download</a>
</div>
</div>
</p>
<hr />
<p>
<h4>EEPROM-Restore</h4>
<form method='POST' action='eeRestore' enctype='multipart/form-data'>
<div class="form-group row">
<div class="custom-file">
<input type="file" name="ee-restore-file" class="custom-file-input" id="ee-restore-file" accept=".ee.json"
required />
<label class="custom-file-label" for="ee-restore-file">EEPROM-Backup ausw&auml;hlen</label>
</div>
</div>
<div class="form-group row">
<div class="col text-center">
<button name="submit" type="submit" class="btn btn-outline-primary">Restore starten</button>
</div>
</div>
</form>
</p>
<hr />
<p>
<h4>Firmware-Update</h4>
<form method='POST' action='doUpdate' enctype='multipart/form-data'>
<div class="form-group row">
<div class="custom-file">
<input type="file" name="fw-update-file" class="custom-file-input" id="fw-update-file"
accept=".fw.bin,.fs.gz" required />
<label class="custom-file-label" for="fw-update-file">Firmware-Update ausw&auml;hlen</label>
</div>
</div>
<div class="form-group row">
<div class="col text-center">
<button name="submit" type="submit" class="btn btn-outline-primary">Update starten</button>
</div>
</div>
</form>
</p>
<hr />
</div>
<!-- Div Tab Firmware Update-->
</div>
<!-- Tabs Content -->
</main>
<!-- Footer -->
<footer class="page-footer navbar-dark bg-primary font-small fixed-bottom">
<div class="container-fluid text-center">
<div class="footer-copyright text-center py-3">
<span class="text-muted">© 2022 -
<a class="text-reset fw-bold" href="https://eventronics.de/">Marcel Peterkau</a></span>
</div>
</div>
</footer>
<!-- Footer -->
<!-- Modal Dialog -->
<div class="modal fade" id="dtcModal" tabindex="-1" role="dialog" aria-labelledby="dtcModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="dtcModalLabel">DTC-Description</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p class="dtc-desc">DTC Description</p>
<p class="dtc-debugval">DTC DebugVal</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Modal Dialog -->
<script>
$('.navbar-nav>li>a').on('click', function () {
$('.navbar-collapse').collapse('hide');
});
document.querySelector('.custom-file-input').addEventListener('change', function (e) {
var fileName = document.getElementById("fw-update-file").files[0].name;
var nextSibling = e.target.nextElementSibling
nextSibling.innerText = fileName
});
$(document).ready(function () {
$("tr[data-dtc]").each(function (i) {
$(this).attr('data-toggle', "modal");
$(this).attr('data-target', "#dtcModal");
});
});
$('#dtcModal').on('show.bs.modal', function (event) {
var dtctr = $(event.relatedTarget)
var dtc = dtctr.data('dtc')
var debugval = dtctr.data('debugval')
var modal = $(this)
$.getJSON('static/tt_dtc/dtc_' + dtc + '.json', function (data) {
modal.find('.modal-title').text(data.title)
modal.find('.dtc-desc').text(data.description)
if (debugval > 0) {
modal.find('.dtc-debugval').text("Debugvalue: " + debugval)
}
else {
modal.find('.dtc-debugval').remove()
}
}).fail(function () {
console.log("An error has occurred.");
modal.find('.modal-title').text("Fehler")
modal.find('.dtc-desc').text("DTC-Beschreibung konnte nicht geladen werden")
});
});
</script>
</body>
</html>

View File

@@ -14,7 +14,7 @@
<link rel="icon" type="image/png" sizes="32x32" href="static/img/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="32x32" href="static/img/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="static/img/favicon-16x16.png"> <link rel="icon" type="image/png" sizes="16x16" href="static/img/favicon-16x16.png">
<link rel="manifest" href="static/img/site.webmanifest"> <link rel="manifest" href="static/img/site.webmanifest">
<meta http-equiv="refresh" content="3; url='/index.htm'" /> <meta http-equiv="refresh" content="3; url='index.htm'" />
</head> </head>
<body> <body>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,27 @@
@font-face {
font-family: 'Comfortaa';
font-style: normal;
font-weight: 300;
src: url(../fonts/comfortaa.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
body {
padding-top: 70px;
margin-bottom: 70px;
}
hr {
height: 2px;
border-width: 0;
color: gray;
background-color: gray
}
.dtc-debugval {
color: #F2771A;
font: 0.8rem Inconsolata, monospace;
background-color: black;
padding: 10px;
}

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

Before

Width:  |  Height:  |  Size: 545 B

After

Width:  |  Height:  |  Size: 545 B

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -0,0 +1 @@
{"name":"","short_name":"","icons":[{"src":"/static/img/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/static/img/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,68 @@
var gateway = `ws://${window.location.hostname}/ws`;
var websocket;
window.addEventListener("load", onLoad);
function initWebSocket() {
console.log("Trying to open a WebSocket connection...");
websocket = new WebSocket(gateway);
websocket.onopen = onOpen;
websocket.onclose = onClose;
websocket.onmessage = onMessage; // <-- add this line
}
function initButtons() {
document
.getElementById("btn-ws-stop")
.addEventListener("click", livedebug_stop);
document
.getElementById("btn-ws-start")
.addEventListener("click", livedebug_start);
}
function onOpen(event) {
console.log("Connection opened");
}
function onClose(event) {
console.log("Connection closed");
setTimeout(initWebSocket, 2000);
}
function onMessage(event) {
var livedebug_out = document.getElementById("livedebug-out");
var textarea_heigth = livedebug_out.scrollHeight;
livedebug_out.value += event.data;
livedebug_out.scrollTop = livedebug_out.scrollHeight;
do_resize(livedebug_out);
}
function onLoad(event) {
initWebSocket();
initButtons();
}
function livedebug_start() {
websocket.send("start");
}
function livedebug_stop() {
websocket.send("stop");
}
function do_resize(textbox) {
var maxrows = 15;
var minrows = 3;
var txt = textbox.value;
var cols = textbox.cols;
var arraytxt = txt.split("\n");
var rows = arraytxt.length;
for (i = 0; i < arraytxt.length; i++)
rows += parseInt(arraytxt[i].length / cols);
if (rows > maxrows) textbox.rows = maxrows;
else if (rows < minrows) textbox.rows = minrows;
else textbox.rows = rows;
}

View File

@@ -0,0 +1,4 @@
{
"title": "Ölvorrat leer",
"description": "Ölvorrat ist komplett leer. Den Ölvorrat auffüllen und im Menu 'Wartung' zurück setzen"
}

View File

@@ -0,0 +1,4 @@
{
"title": "Keine GPS-Verbindung",
"description": "Es wurde kein GPS-Signal über die serielle Schnittstelle empfangen, Prüfen sie die Verbindung und das GPS-Modul"
}

View File

@@ -0,0 +1,4 @@
{
"title": "CAN-Transceiver Error",
"description": "Es konnte keine Verbindung zum CAN-Transceiver hergestellt werden. Prüfen Sie die Hardware auf Defekte"
}

View File

@@ -0,0 +1,4 @@
{
"title": "Keine CAN-Verbindung",
"description": "Es konnte kein CAN-Signal empfangen werden. Prüfen sie die Verbindung und die Einstellungen"
}

View File

@@ -0,0 +1,4 @@
{
"title": "Config-Validierung",
"description": "Ein oder mehrer Einstellungswerte sind ausserhalb plausibler Werte. Prüfen Sie Ihre Einstellungen"
}

View File

@@ -0,0 +1,4 @@
{
"title": "Ölvorrat niedrig",
"description": "Ölvorrat ist unter der Warnschwelle. Den Ölvorrat demnächst auffüllen und im Menu 'Wartung' zurück setzen"
}

View File

@@ -0,0 +1,4 @@
{
"title": "kein EEPROM gefunden",
"description": "Es wurde kein EEPROM gefunden. Dies lässt einen Hardware-Defekt vermuten."
}

View File

@@ -0,0 +1,4 @@
{
"title": "EEPROM CFG Checksumme",
"description": "Die Checksumme der Config-Partition des EEPROM ist ungültig. Setzen sie den EEPROM-Bereich 'CFG' im Menu 'Wartung' zurück"
}

View File

@@ -0,0 +1,4 @@
{
"title": "EEPROM PDS Checksumme",
"description": "Die Checksumme der Betriebsdaten-Partition des EEPROM ist ungültig. Setzen sie den EEPROM-Bereich 'PDS' im Menu 'Wartung' zurück"
}

View File

@@ -0,0 +1,4 @@
{
"title": "EEPROM PDS Adresse",
"description": "Die Adresse der Betriebsdaten-Partition im EEPROM ist ungültig. Setzen sie den EEPROM-Bereich 'PDS' im Menu 'Wartung' zurück"
}

View File

@@ -0,0 +1,4 @@
{
"title": "EEPROM Version falsch",
"description": "Die Layout-Version des EEPROM stimmt nicht mit der Firmware-Version überein. Setzen sie den EEPROM-Bereich 'CFG' im Menu 'Wartung' zurück"
}

View File

@@ -0,0 +1,4 @@
{
"title": "Flashstorage Fehler",
"description": "Der Flashstorage konnte nicht initialisiert werden. Aktualisieren sie Flash & Firmware"
}

View File

@@ -0,0 +1,4 @@
{
"title": "Flashstorage Version falsch",
"description": "Die Version des Flashstorage stimmt nicht mit der Firmware-Version überein. Aktualisieren sie den Flash mit der passenden Update-Datei"
}

View File

@@ -0,0 +1 @@
1.3

View File

@@ -31,17 +31,19 @@ build_flags =
-DADMIN_PASSWORD=${wifi_cred.admin_password} -DADMIN_PASSWORD=${wifi_cred.admin_password}
-DWIFI_AP_PASSWORD=${wifi_cred.wifi_ap_password} -DWIFI_AP_PASSWORD=${wifi_cred.wifi_ap_password}
-DWIFI_AP_IP_GW=10,0,0,1 -DWIFI_AP_IP_GW=10,0,0,1
;-DFEATURE_ENABLE_WIFI_CLIENT -DATOMIC_FS_UPDATE
;-DFEATURE_ENABLE_REMOTE_DEBUG -DFEATURE_ENABLE_WIFI_CLIENT
;-DFEATURE_ENABLE_OLED -DFEATURE_ENABLE_OLED
;-DFEATURE_ENABLE_CAN -DFEATURE_ENABLE_CAN
;-DFEATURE_ENABLE_GPS ;-DFEATURE_ENABLE_GPS
-DPCB_REV=2 -DFEATURE_ENABLE_WEBSOCKETS
-DNO_MODE_FLASH -DPCB_REV=4
;-DNO_MODE_FLASH
;build_type = debug ;build_type = debug
board_build.filesystem = littlefs board_build.filesystem = littlefs
extra_scripts = post:prepare_littlefs.py
monitor_filters = esp8266_exception_decoder monitor_filters = esp8266_exception_decoder
monitor_speed = 115200 monitor_speed = 115200
@@ -50,10 +52,10 @@ board_build.ldscript = eagle.flash.4m1m.ld
lib_ldf_mode = deep lib_ldf_mode = deep
lib_deps = lib_deps =
olikraus/U8g2 @ ^2.28.8 olikraus/U8g2 @ ^2.28.8
joaolopesf/RemoteDebug @ ^2.1.2 https://github.com/FastLED/FastLED.git#3d2ab78 ;fastled/FastLED @ ^3.5.0
fastled/FastLED @ ^3.5.0
sstaub/Ticker @ ^4.2.0 sstaub/Ticker @ ^4.2.0
coryjfowler/mcp_can @ ^1.5.0 coryjfowler/mcp_can @ ^1.5.0
robtillaart/I2C_EEPROM @ ^1.5.2 robtillaart/I2C_EEPROM @ ^1.5.2
mikalhart/TinyGPSPlus @ ^1.0.3 mikalhart/TinyGPSPlus @ ^1.0.3
me-no-dev/ESP Async WebServer @ ^1.2.3 me-no-dev/ESP Async WebServer @ ^1.2.3
bblanchon/ArduinoJson @ ^6.19.4

View File

@@ -0,0 +1,116 @@
# SCRIPT TO GZIP CRITICAL FILES FOR ACCELERATED WEBSERVING
# see also https://community.platformio.org/t/question-esp32-compress-files-in-data-to-gzip-before-upload-possible-to-spiffs/6274/10
import glob
import shutil
import gzip
import os
Import("env")
Import("projenv")
def gzip_file(src_path, dst_path):
with open(src_path, 'rb') as src, gzip.open(dst_path, 'wb') as dst:
for chunk in iter(lambda: src.read(4096), b""):
dst.write(chunk)
def getListOfFiles(dirName):
# create a list of file and sub directories
# names in the given directory
listOfFile = os.listdir(dirName)
allFiles = list()
# Iterate over all the entries
for entry in listOfFile:
# Create full path
fullPath = os.path.join(dirName, entry)
# If entry is a directory then get the list of files in this directory
if os.path.isdir(fullPath):
allFiles = allFiles + getListOfFiles(fullPath)
else:
allFiles.append(fullPath)
return allFiles
def remove_prefix(text, prefix):
if text.startswith(prefix):
return text[len(prefix):]
return text # or whatever
# Compress files from 'data_src/' to 'data/'
def gzip_webfiles(source, target, env):
# Filetypes to compress
filetypes_to_gzip = ['.css', '.png', '.js', '.ico', '.woff2', '.json']
print('\nGZIP: Starting gzip-Process for LittleFS-Image...\n')
data_src_dir_path = os.path.join(env.get('PROJECT_DIR'), 'data_src')
data_dir_path = env.get('PROJECT_DATA_DIR')
# check if data and datasrc exist. If the first exists and not the second, it renames it
if(os.path.exists(data_dir_path) and not os.path.exists(data_src_dir_path)):
print('GZIP: Directory "'+data_dir_path +
'" exists, "'+data_src_dir_path+'" is not found.')
print('GZIP: Renaming "' + data_dir_path +
'" to "' + data_src_dir_path + '"')
os.rename(data_dir_path, data_src_dir_path)
# Delete the 'data' directory
if(os.path.exists(data_dir_path)):
print('GZIP: Deleting the "data" directory ' + data_dir_path)
shutil.rmtree(data_dir_path)
# Recreate empty 'data' directory
print('GZIP: Re-creating an empty data directory ' + data_dir_path)
os.mkdir(data_dir_path)
# Determine the files to compress
files_to_copy = []
files_to_gzip = []
all_data_src = getListOfFiles(data_src_dir_path)
for file in all_data_src:
file_name, file_extension = os.path.splitext(file)
print(file_name + " has filetype " + file_extension)
if file_extension in filetypes_to_gzip:
files_to_gzip.append(file)
else:
filename_subdir = remove_prefix(file, data_src_dir_path)
files_to_copy.append(filename_subdir)
for file in files_to_copy:
print('GZIP: Copying file from: ' + data_src_dir_path + file + ' to: ' + data_dir_path + file)
os.makedirs(os.path.dirname(data_dir_path + file), exist_ok=True)
shutil.copy(data_src_dir_path + file, data_dir_path + file)
# Compress and move files
was_error = False
try:
for source_file_path in files_to_gzip:
print('GZIP: compressing... ' + source_file_path)
filename_subdir = remove_prefix(source_file_path, data_src_dir_path)
target_file_path = data_dir_path + filename_subdir
os.makedirs(os.path.dirname(target_file_path), exist_ok=True)
print('GZIP: Compressed... ' + target_file_path)
gzip_file(source_file_path, target_file_path + ".gz")
except IOError as e:
was_error = True
print('GZIP: Failed to compress file: ' + source_file_path)
# print( 'GZIP: EXCEPTION... {}'.format( e ) )
if was_error:
print('GZIP: Failure/Incomplete.\n')
else:
print('GZIP: Compressed correctly.\n')
return
def gzip_binffiles(source, target, env):
littlefsbin = target[0].get_abspath()
targetbin = os.path.join(os.path.dirname(littlefsbin), 'filesystem.fs')
shutil.copyfile(littlefsbin, targetbin)
gzip_file(targetbin, os.path.join(str(targetbin) + '.gz'))
os.remove(targetbin)
return
# IMPORTANT, this needs to be added to call the routine
env.AddPreAction('$BUILD_DIR/littlefs.bin', gzip_webfiles)
env.AddPostAction('$BUILD_DIR/littlefs.bin', gzip_binffiles)

View File

@@ -23,9 +23,11 @@ uint32_t Process_CAN_WheelSpeed()
can_frame canMsg; can_frame canMsg;
static uint32_t lastRecTimestamp = 0; static uint32_t lastRecTimestamp = 0;
uint16_t RearWheelSpeed_raw; uint16_t RearWheelSpeed_raw;
uint32_t milimeters_to_add = 0;
if (CAN0.readMsgBuf(&canMsg.can_id, &canMsg.can_dlc, canMsg.data) == CAN_OK) if (CAN0.readMsgBuf(&canMsg.can_id, &canMsg.can_dlc, canMsg.data) == CAN_OK)
{ {
RearWheelSpeed_raw = (uint16_t)canMsg.data[5] << 8 | canMsg.data[6]; RearWheelSpeed_raw = (uint16_t)canMsg.data[5] << 8 | canMsg.data[6];
// raw / FACTOR_RWP_KMH_890ADV -> km/h * 100000 -> cm/h / 3600 -> cm/s // raw / FACTOR_RWP_KMH_890ADV -> km/h * 100000 -> cm/h / 3600 -> cm/s
// raw * 500 -> cm/s // raw * 500 -> cm/s
@@ -34,13 +36,14 @@ uint32_t Process_CAN_WheelSpeed()
uint32_t timesincelast = millis() - lastRecTimestamp; uint32_t timesincelast = millis() - lastRecTimestamp;
lastRecTimestamp = millis(); lastRecTimestamp = millis();
uint32_t milimeters_to_add = (RWP_millimeter_per_second * timesincelast) / 1000; milimeters_to_add = (RWP_millimeter_per_second * timesincelast) / 1000;
return milimeters_to_add;
} }
if (lastRecTimestamp != 0)
{
MaintainDTC(DTC_NO_CAN_SIGNAL, DTC_CRITICAL, (millis() > lastRecTimestamp + 10000 ? true : false)); MaintainDTC(DTC_NO_CAN_SIGNAL, DTC_CRITICAL, (millis() > lastRecTimestamp + 10000 ? true : false));
}
return 0; return milimeters_to_add;
} }
#endif #endif

View File

@@ -26,17 +26,27 @@
#define HOST_NAME "ChainLube_%06X" // Use printf-Formatting - Chip-ID (uin32_t) will be added #define HOST_NAME "ChainLube_%06X" // Use printf-Formatting - Chip-ID (uin32_t) will be added
#endif #endif
#define SW_VERSION_MAJOR 1 #define SW_VERSION 1.4
#define SW_VERSION_MINOR 1 #define FLASH_FS_VERSION 1.4
#define FLASH_FS_VERSION 1.1
#ifndef OTA_DELAY #ifndef OTA_DELAY
#define OTA_DELAY 50 // ticks -> 10ms / tick #define OTA_DELAY 50 // ticks -> 10ms / tick
#endif #endif
#define LUBE_PULSE_LENGHT_MS 160
#define LUBE_PULSE_PAUSE_MS 340
// -> 2Hz PumpPulse
// -> 49,7cc / h @ 2Hz
// -> 49,7 ml / h @ 2Hz
// -> 828,4µl / min @ 2Hz
// -> 828,3µl / 60s
// -> 13,81µl / 1s
// -> 6,90µl / Pulse
#define DEFAULT_PUMP_DOSE 7
#define STARTUP_DELAY 5000
#define SHUTDOWN_DELAY_MS 5000 #define SHUTDOWN_DELAY_MS 5000
#define ATOMIC_FS_UPDATE
#endif #endif

View File

@@ -1,4 +1,5 @@
#include "config.h" #include "config.h"
#include "debugger.h"
I2C_eeprom ee(0x50, EEPROM_SIZE_BYTES); I2C_eeprom ee(0x50, EEPROM_SIZE_BYTES);
@@ -15,37 +16,55 @@ boolean checkEEPROMavailable();
void InitEEPROM() void InitEEPROM()
{ {
ee.begin(); ee.begin();
if (!checkEEPROMavailable()) checkEEPROMavailable();
{
return;
}
} }
void EEPROM_Process() void EEPROM_Process()
{ {
switch (globals.requestEEAction) switch (globals.requestEEAction)
{ {
case EE_CFG_SAVE: case EE_CFG_SAVE:
StoreConfig_EEPROM(); StoreConfig_EEPROM();
globals.requestEEAction = EE_IDLE; globals.requestEEAction = EE_IDLE;
Debug_pushMessage("Stored EEPROM CFG\n");
break; break;
case EE_CFG_LOAD: case EE_CFG_LOAD:
GetConfig_EEPROM(); GetConfig_EEPROM();
globals.requestEEAction = EE_IDLE; globals.requestEEAction = EE_IDLE;
Debug_pushMessage("Loaded EEPROM CFG\n");
break;
case EE_CFG_FORMAT:
FormatConfig_EEPROM();
globals.requestEEAction = EE_IDLE;
globals.systemStatus = sysStat_Shutdown;
Debug_pushMessage("Formated EEPROM CFG\n");
break; break;
case EE_PDS_SAVE: case EE_PDS_SAVE:
StorePersistence_EEPROM(); StorePersistence_EEPROM();
globals.requestEEAction = EE_IDLE; globals.requestEEAction = EE_IDLE;
Debug_pushMessage("Stored EEPROM PDS\n");
break; break;
case EE_PDS_LOAD: case EE_PDS_LOAD:
GetPersistence_EEPROM(); GetPersistence_EEPROM();
globals.requestEEAction = EE_IDLE; globals.requestEEAction = EE_IDLE;
Debug_pushMessage("Loaded EEPROM PDS\n");
break;
case EE_PDS_FORMAT:
FormatPersistence_EEPROM();
globals.requestEEAction = EE_IDLE;
Debug_pushMessage("Formated EEPROM PDS\n");
break;
case EE_FORMAT_ALL:
FormatConfig_EEPROM();
FormatPersistence_EEPROM();
globals.requestEEAction = EE_IDLE;
Debug_pushMessage("Formated EEPROM ALL\n");
break; break;
case EE_ALL_SAVE: case EE_ALL_SAVE:
StorePersistence_EEPROM(); StorePersistence_EEPROM();
StoreConfig_EEPROM(); StoreConfig_EEPROM();
globals.requestEEAction = EE_IDLE; globals.requestEEAction = EE_IDLE;
Debug_pushMessage("Stored EEPROM ALL\n");
break; break;
case EE_IDLE: case EE_IDLE:
default: default:
@@ -76,9 +95,16 @@ void GetConfig_EEPROM()
if (Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig)) != checksum) if (Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig)) != checksum)
{ {
MaintainDTC(DTC_EEPROM_CFG_BAD, DTC_CRITICAL, true); MaintainDTC(DTC_EEPROM_CFG_BAD, DTC_CRITICAL, true);
FormatConfig_EEPROM();
} }
LubeConfig.checksum = checksum; LubeConfig.checksum = checksum;
uint32_t ConfigSanityCheckResult = ConfigSanityCheck(false);
if (ConfigSanityCheckResult > 0)
{
MaintainDTC(DTC_EEPROM_CFG_SANITY, DTC_WARN, true, ConfigSanityCheckResult);
globals.requestEEAction = EE_CFG_SAVE;
}
} }
void StorePersistence_EEPROM() void StorePersistence_EEPROM()
@@ -128,16 +154,17 @@ void GetPersistence_EEPROM()
void FormatConfig_EEPROM() void FormatConfig_EEPROM()
{ {
LubeConfig_t defaults; Debug_pushMessage("Formatting Config-Partition\n");
LubeConfig = defaults; LubeConfig = LubeConfig_defaults;
LubeConfig.EEPROM_Version = eeVersion; LubeConfig.EEPROM_Version = eeVersion;
StoreConfig_EEPROM(); StoreConfig_EEPROM();
} }
void FormatPersistence_EEPROM() void FormatPersistence_EEPROM()
{ {
persistenceData_t defaults; Debug_pushMessage("Formatting Persistance-Partition\n");
PersistenceData = defaults; PersistenceData = {0};
// memset(&PersistenceData, 0, sizeof(PersistenceData));
StorePersistence_EEPROM(); StorePersistence_EEPROM();
} }
@@ -186,9 +213,9 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
char ascii_buf[BLOCK_TO_LENGTH + 1]; char ascii_buf[BLOCK_TO_LENGTH + 1];
sprintf(ascii_buf, "%*s", BLOCK_TO_LENGTH, "ASCII"); sprintf(ascii_buf, "%*s", BLOCK_TO_LENGTH, "ASCII");
Serial.print(PSTR("\nAddress ")); Debug_pushMessage(PSTR("\nAddress "));
for (int x = 0; x < BLOCK_TO_LENGTH; x++) for (int x = 0; x < BLOCK_TO_LENGTH; x++)
Serial.printf("%3d", x); Debug_pushMessage("%3d", x);
memoryAddress = memoryAddress / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH; memoryAddress = memoryAddress / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH;
length = (length + BLOCK_TO_LENGTH - 1) / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH; length = (length + BLOCK_TO_LENGTH - 1) / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH;
@@ -199,16 +226,16 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
if (blockpoint == 0) if (blockpoint == 0)
{ {
ascii_buf[BLOCK_TO_LENGTH] = 0; ascii_buf[BLOCK_TO_LENGTH] = 0;
Serial.printf(" %s", ascii_buf); Debug_pushMessage(" %s", ascii_buf);
Serial.printf("\n0x%05X:", memoryAddress); Debug_pushMessage("\n0x%05X:", memoryAddress);
} }
ascii_buf[blockpoint] = ee.readByte(memoryAddress); ascii_buf[blockpoint] = ee.readByte(memoryAddress);
Serial.printf(" %02X", ascii_buf[blockpoint]); Debug_pushMessage(" %02X", ascii_buf[blockpoint]);
if (ascii_buf[blockpoint] < 0x20 || ascii_buf[blockpoint] > 0x7E) if (ascii_buf[blockpoint] < 0x20 || ascii_buf[blockpoint] > 0x7E)
ascii_buf[blockpoint] = '.'; ascii_buf[blockpoint] = '.';
memoryAddress++; memoryAddress++;
} }
Serial.println(); Debug_pushMessage("\n");
} }
boolean checkEEPROMavailable() boolean checkEEPROMavailable()
@@ -216,9 +243,116 @@ boolean checkEEPROMavailable()
if (!ee.isConnected()) if (!ee.isConnected())
{ {
MaintainDTC(DTC_NO_EEPROM_FOUND, DTC_CRITICAL, true); MaintainDTC(DTC_NO_EEPROM_FOUND, DTC_CRITICAL, true);
globals.systemStatus = sysStat_Error;
return false; return false;
} }
MaintainDTC(DTC_NO_EEPROM_FOUND, DTC_CRITICAL, false); MaintainDTC(DTC_NO_EEPROM_FOUND, DTC_CRITICAL, false);
return true; return true;
} }
uint32_t ConfigSanityCheck(bool autocorrect)
{
uint32_t setting_reset_bits = 0;
if (!(LubeConfig.DistancePerLube_Default > 0) || !(LubeConfig.DistancePerLube_Default < 50000))
{
setting_reset_bits = setting_reset_bits | (1 << 0);
if (autocorrect)
LubeConfig.DistancePerLube_Default = LubeConfig_defaults.DistancePerLube_Default;
}
if (!(LubeConfig.DistancePerLube_Rain > 0) || !(LubeConfig.DistancePerLube_Rain < 50000))
{
setting_reset_bits = setting_reset_bits | (1 << 1);
if (autocorrect)
LubeConfig.DistancePerLube_Rain = LubeConfig_defaults.DistancePerLube_Rain;
}
if (!(LubeConfig.tankCapacity_ml > 0) || !(LubeConfig.tankCapacity_ml < 5000))
{
setting_reset_bits = setting_reset_bits | (1 << 2);
if (autocorrect)
LubeConfig.tankCapacity_ml = LubeConfig_defaults.tankCapacity_ml;
}
if (!(LubeConfig.amountPerDose_microL > 0) || !(LubeConfig.amountPerDose_microL < 100))
{
setting_reset_bits = setting_reset_bits | (1 << 3);
if (autocorrect)
LubeConfig.amountPerDose_microL = LubeConfig_defaults.amountPerDose_microL;
}
if (!(LubeConfig.TankRemindAtPercentage >= 0) || !(LubeConfig.TankRemindAtPercentage <= 100))
{
setting_reset_bits = setting_reset_bits | (1 << 4);
if (autocorrect)
LubeConfig.TankRemindAtPercentage = LubeConfig_defaults.TankRemindAtPercentage;
}
if (!(LubeConfig.PulsePerRevolution > 0) || !(LubeConfig.PulsePerRevolution < 1000))
{
setting_reset_bits = setting_reset_bits | (1 << 5);
if (autocorrect)
LubeConfig.PulsePerRevolution = LubeConfig_defaults.PulsePerRevolution;
}
if (!(LubeConfig.TireWidth_mm > 0) || !(LubeConfig.TireWidth_mm < 500))
{
setting_reset_bits = setting_reset_bits | (1 << 6);
if (autocorrect)
LubeConfig.TireWidth_mm = LubeConfig_defaults.TireWidth_mm;
}
if (!(LubeConfig.TireWidthHeight_Ratio > 0) || !(LubeConfig.TireWidthHeight_Ratio < 150))
{
setting_reset_bits = setting_reset_bits | (1 << 7);
if (autocorrect)
LubeConfig.TireWidthHeight_Ratio = LubeConfig_defaults.TireWidthHeight_Ratio;
}
if (!(LubeConfig.RimDiameter_Inch > 0) || !(LubeConfig.RimDiameter_Inch < 30))
{
setting_reset_bits = setting_reset_bits | (1 << 8);
if (autocorrect)
LubeConfig.RimDiameter_Inch = LubeConfig_defaults.RimDiameter_Inch;
}
if (!(LubeConfig.DistancePerRevolution_mm > 0) || !(LubeConfig.DistancePerRevolution_mm < 10000))
{
setting_reset_bits = setting_reset_bits | (1 << 9);
if (autocorrect)
LubeConfig.DistancePerRevolution_mm = LubeConfig_defaults.DistancePerRevolution_mm;
}
if (!(LubeConfig.BleedingPulses > 0) || !(LubeConfig.BleedingPulses < 1001))
{
setting_reset_bits = setting_reset_bits | (1 << 10);
if (autocorrect)
LubeConfig.BleedingPulses = LubeConfig_defaults.BleedingPulses;
}
if (!(LubeConfig.SpeedSource >= 0) || !(LubeConfig.SpeedSource < SpeedSourceString_Elements))
{
setting_reset_bits = setting_reset_bits | (1 << 11);
if (autocorrect)
LubeConfig.SpeedSource = LubeConfig_defaults.SpeedSource;
}
#ifdef FEATURE_ENABLE_GPS
if (!(LubeConfig.GPSBaudRate >= 0) || !(LubeConfig.GPSBaudRate < GPSBaudRateString_Elements))
{
setting_reset_bits = setting_reset_bits | (1 << 12);
if (autocorrect)
LubeConfig.GPSBaudRate = LubeConfig_defaults.GPSBaudRate;
}
#endif
#ifdef FEATURE_ENABLE_CAN
if (!(LubeConfig.CANSource >= 0) || !(LubeConfig.CANSource < CANSourceString_Elements))
{
setting_reset_bits = setting_reset_bits | (1 << 13);
if (autocorrect)
LubeConfig.CANSource = LubeConfig_defaults.CANSource;
}
#endif
return setting_reset_bits;
}

View File

@@ -6,8 +6,13 @@
#include <I2C_eeprom.h> #include <I2C_eeprom.h>
#include "globals.h" #include "globals.h"
#include "dtc.h" #include "dtc.h"
#include "common.h"
#if PCB_REV == 1 || PCB_REV == 2 || PCB_REV == 3
#define EEPROM_SIZE_BYTES I2C_DEVICESIZE_24LC64
#elif PCB_REV == 4
#define EEPROM_SIZE_BYTES I2C_DEVICESIZE_24LC256 #define EEPROM_SIZE_BYTES I2C_DEVICESIZE_24LC256
#endif
typedef enum SpeedSource_e typedef enum SpeedSource_e
{ {
@@ -63,7 +68,7 @@ const size_t SpeedSourceString_Elements = sizeof(SpeedSourceString) / sizeof(Spe
typedef struct typedef struct
{ {
uint16_t writeCycleCounter = 0; uint16_t writeCycleCounter = 0;
uint32_t tankRemain_µl = 0; uint32_t tankRemain_microL = 0;
uint32_t TravelDistance_highRes_mm = 0; uint32_t TravelDistance_highRes_mm = 0;
uint32_t odometer_mm = 0; uint32_t odometer_mm = 0;
uint32_t odometer = 0; uint32_t odometer = 0;
@@ -76,7 +81,7 @@ typedef struct
uint32_t DistancePerLube_Default = 8000; uint32_t DistancePerLube_Default = 8000;
uint32_t DistancePerLube_Rain = 4000; uint32_t DistancePerLube_Rain = 4000;
uint32_t tankCapacity_ml = 320; uint32_t tankCapacity_ml = 320;
uint32_t amountPerDose_µl = 72; uint32_t amountPerDose_microL = DEFAULT_PUMP_DOSE;
uint8_t TankRemindAtPercentage = 30; uint8_t TankRemindAtPercentage = 30;
uint8_t PulsePerRevolution = 1; uint8_t PulsePerRevolution = 1;
uint32_t TireWidth_mm = 150; uint32_t TireWidth_mm = 150;
@@ -94,6 +99,16 @@ typedef struct
uint32_t checksum = 0; uint32_t checksum = 0;
} LubeConfig_t; } LubeConfig_t;
const LubeConfig_t LubeConfig_defaults = {
0, 8000, 4000, 320, DEFAULT_PUMP_DOSE, 30, 1, 150, 70, 18, 2000, 25, SOURCE_IMPULSE,
#ifdef FEATURE_ENABLE_GPS
BAUD_115200,
#endif
#ifdef FEATURE_ENABLE_CAN
KTM_890_ADV_R_2021,
#endif
0};
void InitEEPROM(); void InitEEPROM();
void EEPROM_Process(); void EEPROM_Process();
void StoreConfig_EEPROM(); void StoreConfig_EEPROM();
@@ -105,6 +120,7 @@ void FormatPersistence_EEPROM();
uint32_t Checksum_EEPROM(uint8_t const *data, size_t len); uint32_t Checksum_EEPROM(uint8_t const *data, size_t len);
void dumpEEPROM(uint16_t memoryAddress, uint16_t length); void dumpEEPROM(uint16_t memoryAddress, uint16_t length);
void MovePersistencePage_EEPROM(boolean reset); void MovePersistencePage_EEPROM(boolean reset);
uint32_t ConfigSanityCheck(bool autocorrect = false);
extern LubeConfig_t LubeConfig; extern LubeConfig_t LubeConfig;
extern persistenceData_t PersistenceData; extern persistenceData_t PersistenceData;

253
Software/src/debugger.cpp Normal file
View File

@@ -0,0 +1,253 @@
#include "debugger.h"
DebugStatus_t DebuggerStatus[dbg_cntElements];
String IpAddress2String(const IPAddress &ipAddress);
void processCmdDebug();
void Debug_formatCFG();
void Debug_formatPersistence();
void Debug_printSystemInfo();
void Debug_printWifiInfo();
void Debug_CheckEEPOM();
void Debug_dumpConfig();
void Debug_dumpPersistance();
void Debug_ShowDTCs();
void Debug_dumpGlobals();
void initDebugger()
{
DebuggerStatus[dbg_Serial] = disabled;
DebuggerStatus[dbg_Webui] = disabled;
Serial.setDebugOutput(false);
}
void SetDebugportStatus(DebugPorts_t port, DebugStatus_t status)
{
if (status == disabled)
Debug_pushMessage("disable DebugPort %s", sDebugPorts[port]);
DebuggerStatus[port] = status;
if (status == enabled)
Debug_pushMessage("enabled DebugPort %s", sDebugPorts[port]);
}
void Debug_pushMessage(const char *format, ...)
{
if ((DebuggerStatus[dbg_Serial] == enabled) || (DebuggerStatus[dbg_Webui] == enabled))
{
char buff[64];
va_list arg;
va_start(arg, format);
vsnprintf(buff, sizeof(buff), format, arg);
va_end(arg);
if (DebuggerStatus[dbg_Serial] == enabled)
{
Serial.print(buff);
}
if (DebuggerStatus[dbg_Webui] == enabled)
{
Websocket_PushLiveDebug(String(buff));
}
}
}
void pushCANDebug(uint32_t id, uint8_t dlc, uint8_t *data)
{
if ((DebuggerStatus[dbg_Serial] == enabled) || (DebuggerStatus[dbg_Webui] == enabled))
{
char buff[100];
char *p = buff;
p += snprintf(p, sizeof(buff), "CAN: 0x%08X | %d | ", id, dlc);
for (int i = 0; i < dlc; i++)
{
p += snprintf(p, sizeof(buff) - (p - buff), "%02X ", data[i]);
}
*(p++) = '\n';
*p = '\0';
if (DebuggerStatus[dbg_Serial] == enabled)
{
Serial.print(buff);
}
if (DebuggerStatus[dbg_Webui] == enabled)
{
Websocket_PushLiveDebug(String(buff));
}
}
}
void processCmdDebug(String command)
{
if (command == "sysinfo")
Debug_printSystemInfo();
else if (command == "netinfo")
Debug_printWifiInfo();
else if (command == "formatCFG")
Debug_formatCFG();
else if (command == "formatPDS")
Debug_formatPersistence();
else if (command == "checkEE")
Debug_CheckEEPOM();
else if (command == "dumpEE1k")
dumpEEPROM(0, 1024);
else if (command == "dumpEE")
dumpEEPROM(0, EEPROM_SIZE_BYTES);
else if (command == "resetPageEE")
MovePersistencePage_EEPROM(true);
else if (command == "dumpCFG")
Debug_dumpConfig();
else if (command == "dumpPDS")
Debug_dumpPersistance();
else if (command == "saveEE")
globals.requestEEAction = EE_ALL_SAVE;
else if (command == "showdtc")
Debug_ShowDTCs();
else if (command == "dumpGlobals")
Debug_dumpGlobals();
}
void Debug_formatCFG()
{
Debug_pushMessage("Formatting Config-EEPROM and reseting to default");
FormatConfig_EEPROM();
}
void Debug_formatPersistence()
{
Debug_pushMessage("Formatting Persistence-EEPROM and reseting to default");
FormatPersistence_EEPROM();
}
void RemotDebug_printSystemInfo()
{
Debug_pushMessage("Souko's ChainOiler Mk1");
Debug_pushMessage("Hostname: %s", globals.DeviceName);
FlashMode_t ideMode = ESP.getFlashChipMode();
Debug_pushMessage("Sdk version: %s", ESP.getSdkVersion());
Debug_pushMessage("Core Version: %s", ESP.getCoreVersion().c_str());
Debug_pushMessage("Boot Version: %u", ESP.getBootVersion());
Debug_pushMessage("Boot Mode: %u", ESP.getBootMode());
Debug_pushMessage("CPU Frequency: %u MHz", ESP.getCpuFreqMHz());
Debug_pushMessage("Reset reason: %s", ESP.getResetReason().c_str());
Debug_pushMessage("Flash Size: %d", ESP.getFlashChipRealSize());
Debug_pushMessage("Flash Size IDE: %d", ESP.getFlashChipSize());
Debug_pushMessage("Flash ide mode: %s", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT"
: ideMode == FM_DIO ? "DIO"
: ideMode == FM_DOUT ? "DOUT"
: "UNKNOWN"));
Debug_pushMessage("OTA-Pass: %s", QUOTE(ADMIN_PASSWORD));
Debug_pushMessage("Git-Revison: %s", GIT_REV);
Debug_pushMessage("Sw-Version: %s", QUOTE(SW_VERSION));
}
void Debug_dumpConfig()
{
Debug_pushMessage("DistancePerLube_Default: %d", LubeConfig.DistancePerLube_Default);
Debug_pushMessage("DistancePerLube_Rain: %d", LubeConfig.DistancePerLube_Rain);
Debug_pushMessage("tankCapacity_ml: %d", LubeConfig.tankCapacity_ml);
Debug_pushMessage("amountPerDose_microL: %d", LubeConfig.amountPerDose_microL);
Debug_pushMessage("TankRemindAtPercentage: %d", LubeConfig.TankRemindAtPercentage);
Debug_pushMessage("PulsePerRevolution: %d", LubeConfig.PulsePerRevolution);
Debug_pushMessage("TireWidth_mm: %d", LubeConfig.TireWidth_mm);
Debug_pushMessage("TireWidthHeight_Ratio: %d", LubeConfig.TireWidth_mm);
Debug_pushMessage("RimDiameter_Inch: %d", LubeConfig.RimDiameter_Inch);
Debug_pushMessage("DistancePerRevolution_mm: %d", LubeConfig.DistancePerRevolution_mm);
Debug_pushMessage("BleedingPulses: %d", LubeConfig.BleedingPulses);
Debug_pushMessage("SpeedSource: %d", LubeConfig.SpeedSource);
#ifdef FEATURE_ENABLE_GPS
Debug_pushMessage("GPSBaudRate: %d", LubeConfig.GPSBaudRate);
#endif
#ifdef FEATURE_ENABLE_CAN
Debug_pushMessage("CANSource: %d", LubeConfig.CANSource);
#endif
Debug_pushMessage("checksum: 0x%08X", LubeConfig.checksum);
}
void Debug_dumpGlobals()
{
Debug_pushMessage("systemStatus: %d", globals.systemStatus);
Debug_pushMessage("resumeStatus: %d", globals.resumeStatus);
Debug_pushMessage("systemStatustxt: %s", globals.systemStatustxt);
Debug_pushMessage("purgePulses: %d", globals.purgePulses);
Debug_pushMessage("requestEEAction: %d", globals.requestEEAction);
Debug_pushMessage("DeviceName: %s", globals.DeviceName);
Debug_pushMessage("FlashVersion: %s", globals.FlashVersion);
Debug_pushMessage("eePersistanceAdress: %d", globals.eePersistanceAdress);
Debug_pushMessage("TankPercentage: %d", globals.TankPercentage);
Debug_pushMessage("hasDTC: %d", globals.hasDTC);
}
void Debug_dumpPersistance()
{
Debug_pushMessage("writeCycleCounter: %d", PersistenceData.writeCycleCounter);
Debug_pushMessage("tankRemain_microL: %d", PersistenceData.tankRemain_microL);
Debug_pushMessage("TravelDistance_highRes_mm: %d", PersistenceData.TravelDistance_highRes_mm);
Debug_pushMessage("checksum: %d", PersistenceData.checksum);
Debug_pushMessage("PSD Adress: 0x%04X", globals.eePersistanceAdress);
}
void Debug_printWifiInfo()
{
}
void Debug_CheckEEPOM()
{
uint32_t checksum = PersistenceData.checksum;
PersistenceData.checksum = 0;
if (Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)) == checksum)
{
Debug_pushMessage("PersistenceData EEPROM Checksum OK\n");
}
else
{
Debug_pushMessage("PersistenceData EEPROM Checksum BAD\n");
}
PersistenceData.checksum = checksum;
checksum = LubeConfig.checksum;
LubeConfig.checksum = 0;
if (Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig)) == checksum)
{
Debug_pushMessage("LubeConfig EEPROM Checksum OK\n");
}
else
{
Debug_pushMessage("LubeConfig EEPROM Checksum BAD\n");
}
LubeConfig.checksum = checksum;
}
void Debug_ShowDTCs()
{
char buff_timestamp[16]; // Format: DD-hh:mm:ss:xxx
char buff_active[9];
for (uint32_t i = 0; i < MAX_DTC_STORAGE; i++)
{
if (DTCStorage[i].Number < DTC_LAST_DTC)
{
sprintf(buff_timestamp, "%02d-%02d:%02d:%02d:%03d",
DTCStorage[i].timestamp / 86400000, // Days
DTCStorage[i].timestamp / 360000 % 24, // Hours
DTCStorage[i].timestamp / 60000 % 60, // Minutes
DTCStorage[i].timestamp / 1000 % 60, // Seconds
DTCStorage[i].timestamp % 1000); // milliseconds
if (DTCStorage[i].active == DTC_ACTIVE)
strcpy(buff_active, "active");
else if (DTCStorage[i].active == DTC_PREVIOUS)
strcpy(buff_active, "previous");
else
strcpy(buff_active, "none");
Debug_pushMessage("%s \t %6d \t %s \t %d", buff_timestamp, DTCStorage[i].Number, buff_active, DTCStorage[i].severity);
}
}
}

View File

@@ -1,3 +1,9 @@
#ifndef _DEBUGGER_H_
#define _DEBUGGER_H_
#include <Arduino.h>
#include "webui.h"
const char helpCmd[] = "sysinfo - System Info\r\n" const char helpCmd[] = "sysinfo - System Info\r\n"
"netinfo - WiFi Info\r\n" "netinfo - WiFi Info\r\n"
"formatPDS - Format Persistence EEPROM Data\r\n" "formatPDS - Format Persistence EEPROM Data\r\n"
@@ -9,4 +15,31 @@ const char helpCmd[] = "sysinfo - System Info\r\n"
"dumpCFG - print Config struct\r\n" "dumpCFG - print Config struct\r\n"
"dumpPDS - print PersistanceStruct\r\n" "dumpPDS - print PersistanceStruct\r\n"
"saveEE - save EE-Data\r\n" "saveEE - save EE-Data\r\n"
"showdtc - Show all DTCs\r\n"; "showdtc - Show all DTCs\r\n"
"dumpGlobals - print globals\r\n";
typedef enum DebugStatus_e
{
disabled,
enabled
} DebugStatus_t;
typedef enum DebugPorts_e
{
dbg_Serial,
dbg_Webui,
dbg_cntElements
} DebugPorts_t;
const char sDebugPorts[dbg_cntElements][7] = {
"Serial",
"WebUI"};
extern DebugStatus_t DebuggerStatus[dbg_cntElements];
void initDebugger();
void pushCANDebug(uint32_t id, uint8_t dlc, uint8_t *data);
void Debug_pushMessage(const char *format, ...);
void SetDebugportStatus(DebugPorts_t port, DebugStatus_t status);
#endif

View File

@@ -1,8 +1,9 @@
#include "dtc.h" #include "dtc.h"
#include "debugger.h"
DTCEntry_s DTCStorage[MAX_DTC_STORAGE]; DTCEntry_s DTCStorage[MAX_DTC_STORAGE];
void MaintainDTC(DTCNums_t DTC_no, DTCSeverity_t DTC_severity, boolean active) void MaintainDTC(DTCNums_t DTC_no, DTCSeverity_t DTC_severity, boolean active, uint32_t DebugValue)
{ {
for (int i = 0; i < MAX_DTC_STORAGE; i++) for (int i = 0; i < MAX_DTC_STORAGE; i++)
{ {
@@ -10,14 +11,15 @@ void MaintainDTC(DTCNums_t DTC_no, DTCSeverity_t DTC_severity, boolean active)
{ {
if (active && DTCStorage[i].active != DTC_ACTIVE) if (active && DTCStorage[i].active != DTC_ACTIVE)
{ {
Serial.printf("DTC gone active: %d\n", DTC_no); Debug_pushMessage("DTC gone active: %d, DebugVal: %d\n", DTC_no, DebugValue);
DTCStorage[i].timestamp = millis(); DTCStorage[i].timestamp = millis();
DTCStorage[i].active = DTC_ACTIVE; DTCStorage[i].active = DTC_ACTIVE;
DTCStorage[i].severity = DTC_severity; DTCStorage[i].severity = DTC_severity;
DTCStorage[i].debugVal = DebugValue;
} }
if (!active && DTCStorage[i].active == DTC_ACTIVE) if (!active && DTCStorage[i].active == DTC_ACTIVE)
{ {
Serial.printf("DTC gone previous: %d\n", DTC_no); Debug_pushMessage("DTC gone previous: %d\n", DTC_no);
DTCStorage[i].active = DTC_PREVIOUS; DTCStorage[i].active = DTC_PREVIOUS;
} }
return; return;
@@ -32,10 +34,12 @@ void MaintainDTC(DTCNums_t DTC_no, DTCSeverity_t DTC_severity, boolean active)
{ {
if (DTCStorage[i].Number == DTC_LAST_DTC) if (DTCStorage[i].Number == DTC_LAST_DTC)
{ {
Serial.printf("new DTC registered: %d\n", DTC_no); Debug_pushMessage("new DTC registered: %d, DebugVal: %d\n", DTC_no, DebugValue);
DTCStorage[i].Number = DTC_no; DTCStorage[i].Number = DTC_no;
DTCStorage[i].timestamp = millis(); DTCStorage[i].timestamp = millis();
DTCStorage[i].active = DTC_ACTIVE; DTCStorage[i].active = DTC_ACTIVE;
DTCStorage[i].debugVal = DebugValue;
DTCStorage[i].severity = DTC_severity;
return; return;
} }
} }
@@ -104,3 +108,32 @@ DTCNums_t getlastDTC_Severity(boolean only_active, DTCSeverity_t severity)
return pointer >= 0 ? DTCStorage[pointer].Number : DTC_LAST_DTC; return pointer >= 0 ? DTCStorage[pointer].Number : DTC_LAST_DTC;
} }
void DTC_Process()
{
static tSystem_Status preserverSysStatusError;
if (getlastDTC(false) < DTC_LAST_DTC)
{
globals.hasDTC = true;
if (getlastDTC_Severity(true, DTC_CRITICAL) < DTC_LAST_DTC)
{
if (globals.systemStatus != sysStat_Error)
{
preserverSysStatusError = globals.systemStatus;
}
globals.systemStatus = sysStat_Error;
}
else
{
if (globals.systemStatus == sysStat_Error)
{
globals.systemStatus = preserverSysStatusError;
}
}
}
else
{
globals.hasDTC = false;
}
}

View File

@@ -23,6 +23,7 @@ typedef enum DTCNums_e
DTC_CAN_TRANSCEIVER_FAILED, DTC_CAN_TRANSCEIVER_FAILED,
DTC_NO_CAN_SIGNAL, DTC_NO_CAN_SIGNAL,
#endif #endif
DTC_EEPROM_CFG_SANITY,
DTC_LAST_DTC DTC_LAST_DTC
} DTCNums_t; } DTCNums_t;
@@ -46,13 +47,15 @@ typedef struct DTCEntry_s
uint32_t timestamp; uint32_t timestamp;
DTCActive_t active; DTCActive_t active;
DTCSeverity_t severity; DTCSeverity_t severity;
uint32_t debugVal;
} DTCEntry_t; } DTCEntry_t;
void MaintainDTC(DTCNums_t DTC_no, DTCSeverity_t DTC_severity, boolean active); void MaintainDTC(DTCNums_t DTC_no, DTCSeverity_t DTC_severity, boolean active, uint32_t DebugValue = 0);
void ClearDTC(DTCNums_t DTC_no); void ClearDTC(DTCNums_t DTC_no);
void ClearAllDTC(); void ClearAllDTC();
DTCNums_t getlastDTC(boolean only_active); DTCNums_t getlastDTC(boolean only_active);
DTCNums_t getlastDTC_Severity(boolean only_active, DTCSeverity_t severity); DTCNums_t getlastDTC_Severity(boolean only_active, DTCSeverity_t severity);
void DTC_Process();
extern DTCEntry_s DTCStorage[MAX_DTC_STORAGE]; extern DTCEntry_s DTCStorage[MAX_DTC_STORAGE];
#endif #endif

11
Software/src/globals.cpp Normal file
View File

@@ -0,0 +1,11 @@
#include "globals.h"
Globals_t globals;
void initGlobals()
{
globals.purgePulses = 0;
globals.requestEEAction = EE_IDLE;
globals.resumeStatus = sysStat_Normal;
globals.systemStatus = sysStat_Startup;
}

View File

@@ -22,6 +22,7 @@ typedef enum eEERequest
EE_PDS_SAVE, EE_PDS_SAVE,
EE_PDS_LOAD, EE_PDS_LOAD,
EE_PDS_FORMAT, EE_PDS_FORMAT,
EE_FORMAT_ALL,
EE_ALL_SAVE EE_ALL_SAVE
} tEERequest; } tEERequest;
@@ -34,7 +35,7 @@ typedef struct Globals_s
uint16_t purgePulses = 0; uint16_t purgePulses = 0;
eEERequest requestEEAction = EE_IDLE; eEERequest requestEEAction = EE_IDLE;
char DeviceName[33]; char DeviceName[33];
char FlashVersion[5]; char FlashVersion[10];
uint16_t eePersistanceAdress; uint16_t eePersistanceAdress;
uint8_t TankPercentage; uint8_t TankPercentage;
bool hasDTC; bool hasDTC;
@@ -42,4 +43,6 @@ typedef struct Globals_s
extern Globals_t globals; extern Globals_t globals;
void initGlobals();
#endif #endif

View File

@@ -19,7 +19,7 @@ void Init_GPS()
break; break;
} }
Serial.printf(PSTR("Init GPS with Baud %d\n"), baudrate); Debug_pushMessage(PSTR("Init GPS with Baud %d\n"), baudrate);
Serial.begin(baudrate); Serial.begin(baudrate);
} }

View File

@@ -5,37 +5,11 @@ uint32_t lubePulseTimestamp = 0;
void RunLubeApp(uint32_t add_milimeters) void RunLubeApp(uint32_t add_milimeters)
{ {
globals.TankPercentage = PersistenceData.tankRemain_µl / (LubeConfig.tankCapacity_ml * 1000); globals.TankPercentage = PersistenceData.tankRemain_microL / (LubeConfig.tankCapacity_ml * 10);
MaintainDTC(DTC_TANK_EMPTY, DTC_CRITICAL, (PersistenceData.tankRemain_µl < LubeConfig.amountPerDose_µl)); MaintainDTC(DTC_TANK_EMPTY, DTC_CRITICAL, (PersistenceData.tankRemain_microL < LubeConfig.amountPerDose_microL));
MaintainDTC(DTC_TANK_LOW, DTC_WARN, (globals.TankPercentage < LubeConfig.TankRemindAtPercentage)); MaintainDTC(DTC_TANK_LOW, DTC_WARN, (globals.TankPercentage < LubeConfig.TankRemindAtPercentage));
static tSystem_Status preserverSysStatusError;
if (getlastDTC(false) < DTC_LAST_DTC)
{
globals.hasDTC = true;
if (getlastDTC_Severity(true, DTC_CRITICAL) < DTC_LAST_DTC)
{
if (globals.systemStatus != sysStat_Error)
{
preserverSysStatusError = globals.systemStatus;
}
globals.systemStatus = sysStat_Error;
}
else
{
if (globals.systemStatus == sysStat_Error)
{
globals.systemStatus = preserverSysStatusError;
}
}
}
else
{
globals.hasDTC = false;
}
// Add traveled Distance in mm // Add traveled Distance in mm
PersistenceData.TravelDistance_highRes_mm += add_milimeters; PersistenceData.TravelDistance_highRes_mm += add_milimeters;
PersistenceData.odometer_mm += add_milimeters; PersistenceData.odometer_mm += add_milimeters;
@@ -121,13 +95,13 @@ void RunLubeApp(uint32_t add_milimeters)
void LubePulse() void LubePulse()
{ {
if (PersistenceData.tankRemain_µl > 0) // Only Lube if theres Oil remaining! if (PersistenceData.tankRemain_microL > 0) // Only Lube if theres Oil remaining!
{ {
lubePulseTimestamp = millis() + LUBE_PULSE_LENGHT_MS; lubePulseTimestamp = millis() + LUBE_PULSE_LENGHT_MS;
if (PersistenceData.tankRemain_µl < LubeConfig.amountPerDose_µl) // Prevent underrun and shiftover if (PersistenceData.tankRemain_microL < LubeConfig.amountPerDose_microL) // Prevent underrun and shiftover
PersistenceData.tankRemain_µl = 0; PersistenceData.tankRemain_microL = 0;
else else
PersistenceData.tankRemain_µl = PersistenceData.tankRemain_µl - LubeConfig.amountPerDose_µl; PersistenceData.tankRemain_microL = PersistenceData.tankRemain_microL - LubeConfig.amountPerDose_microL;
} }
} }

View File

@@ -8,10 +8,6 @@
#include "globals.h" #include "globals.h"
#include "dtc.h" #include "dtc.h"
#define LUBE_PULSE_LENGHT_MS 160
#define LUBE_PULSE_PAUSE_MS 100
#define STARTUP_DELAY 5000
void RunLubeApp(uint32_t add_milimeters); void RunLubeApp(uint32_t add_milimeters);
void LubePulse(); void LubePulse();

View File

@@ -17,6 +17,7 @@
#include "webui.h" #include "webui.h"
#include "config.h" #include "config.h"
#include "globals.h" #include "globals.h"
#include "debugger.h"
#ifdef FEATURE_ENABLE_CAN #ifdef FEATURE_ENABLE_CAN
#include "can.h" #include "can.h"
#endif #endif
@@ -25,14 +26,6 @@
#endif #endif
#include "dtc.h" #include "dtc.h"
#ifdef FEATURE_ENABLE_REMOTE_DEBUG
#include <RemoteDebug.h>
#include "rmtdbghelp.h"
#else
#define debugV Serial.println
#define debugE Serial.println
#endif
#ifdef FEATURE_ENABLE_WIFI_CLIENT #ifdef FEATURE_ENABLE_WIFI_CLIENT
#include <ESP8266WiFiMulti.h> #include <ESP8266WiFiMulti.h>
@@ -44,9 +37,6 @@ ESP8266WiFiMulti wifiMulti;
#endif #endif
bool startSetupMode = false; bool startSetupMode = false;
Globals_t globals;
uint32_t TravelDistance_highRes;
volatile uint32_t wheel_pulse = 0; volatile uint32_t wheel_pulse = 0;
CRGB leds[1]; CRGB leds[1];
@@ -63,21 +53,6 @@ void toggleWiFiAP(boolean shutdown = false);
void SystemShutdown(); void SystemShutdown();
uint32_t Process_Impulse_WheelSpeed(); uint32_t Process_Impulse_WheelSpeed();
void EEPROMCyclicPDS_callback(); void EEPROMCyclicPDS_callback();
void initGlobals();
#ifdef FEATURE_ENABLE_REMOTE_DEBUG
RemoteDebug Debug;
String IpAddress2String(const IPAddress &ipAddress);
void processCmdRemoteDebug();
void RemoteDebug_formatCFG();
void RemoteDebug_formatPersistence();
void RemotDebug_printSystemInfo();
void RemoteDebug_printWifiInfo();
void RemoteDebug_CheckEEPOM();
void RemoteDebug_dumpConfig();
void RemoteDebug_dumpPersistance();
void RemoteDebug_ShowDTCs();
#endif
#ifdef FEATURE_ENABLE_WIFI_CLIENT #ifdef FEATURE_ENABLE_WIFI_CLIENT
void wifiMaintainConnectionTicker_callback(); void wifiMaintainConnectionTicker_callback();
@@ -103,9 +78,7 @@ void setup()
#endif #endif
Serial.begin(115200); Serial.begin(115200);
Serial.setDebugOutput(true); Serial.println("\n\nSouko's ChainLube Mk1");
Serial.println("Souko's ChainLube Mk1");
Serial.println(globals.DeviceName); Serial.println(globals.DeviceName);
InitEEPROM(); InitEEPROM();
@@ -137,26 +110,13 @@ void setup()
break; break;
#endif #endif
default: default:
debugE("Source Setting N/A"); Debug_pushMessage("Source Setting N/A");
break; break;
} }
pinMode(GPIO_BUTTON, INPUT_PULLUP); pinMode(GPIO_BUTTON, INPUT_PULLUP);
pinMode(GPIO_PUMP, OUTPUT); pinMode(GPIO_PUMP, OUTPUT);
#ifdef FEATURE_ENABLE_REMOTE_DEBUG
Debug.begin(globals.DeviceName);
Debug.setResetCmdEnabled(true);
Debug.showProfiler(false);
Debug.showColors(true);
Debug.setPassword(QUOTE(ADMIN_PASSWORD));
Debug.setSerialEnabled(true);
Debug.showDebugLevel(true);
Debug.setHelpProjectsCmds(helpCmd);
Debug.setCallBackProjectCmds(&processCmdRemoteDebug);
#endif
ArduinoOTA.setPort(8266); ArduinoOTA.setPort(8266);
ArduinoOTA.setHostname(globals.DeviceName); ArduinoOTA.setHostname(globals.DeviceName);
ArduinoOTA.setPassword(QUOTE(ADMIN_PASSWORD)); ArduinoOTA.setPassword(QUOTE(ADMIN_PASSWORD));
@@ -225,18 +185,17 @@ void loop()
} }
RunLubeApp(wheelDistance); RunLubeApp(wheelDistance);
EEPROMCyclicPDSTicker.update();
#ifdef FEATURE_ENABLE_OLED #ifdef FEATURE_ENABLE_OLED
Display_Process(); Display_Process();
#endif #endif
Button_Process(); Button_Process();
LED_Process(); LED_Process();
EEPROM_Process(); EEPROM_Process();
Webserver_Process();
DTC_Process();
ArduinoOTA.handle(); ArduinoOTA.handle();
#ifdef FEATURE_ENABLE_REMOTE_DEBUG EEPROMCyclicPDSTicker.update();
Debug.handle();
#endif
#ifdef FEATURE_ENABLE_WIFI_CLIENT #ifdef FEATURE_ENABLE_WIFI_CLIENT
WiFiMaintainConnectionTicker.update(); WiFiMaintainConnectionTicker.update();
#endif #endif
@@ -253,147 +212,6 @@ String IpAddress2String(const IPAddress &ipAddress)
String(ipAddress[3]); String(ipAddress[3]);
} }
void initGlobals()
{
globals.purgePulses = 0;
globals.requestEEAction = EE_IDLE;
globals.resumeStatus = sysStat_Normal;
globals.systemStatus = sysStat_Startup;
}
#ifdef FEATURE_ENABLE_REMOTE_DEBUG
void processCmdRemoteDebug()
{
String lastCmd = Debug.getLastCommand();
if (lastCmd == "sysinfo")
RemotDebug_printSystemInfo();
else if (lastCmd == "netinfo")
RemoteDebug_printWifiInfo();
else if (lastCmd == "formatCFG")
RemoteDebug_formatCFG();
else if (lastCmd == "formatPDS")
RemoteDebug_formatPersistence();
else if (lastCmd == "checkEE")
RemoteDebug_CheckEEPOM();
else if (lastCmd == "dumpEE1k")
dumpEEPROM(0, 1024);
else if (lastCmd == "dumpEE")
dumpEEPROM(0, EEPROM_SIZE_BYTES);
else if (lastCmd == "resetPageEE")
MovePersistencePage_EEPROM(true);
else if (lastCmd == "dumpCFG")
RemoteDebug_dumpConfig();
else if (lastCmd == "dumpPDS")
RemoteDebug_dumpPersistance();
else if (lastCmd == "saveEE")
globals.requestEEAction == EE_ALL_SAVE;
else if (lastCmd == "showdtc")
RemoteDebug_ShowDTCs();
}
void RemoteDebug_formatCFG()
{
debugA("Formatting Config-EEPROM and reseting to default");
FormatConfig_EEPROM();
}
void RemoteDebug_formatPersistence()
{
debugA("Formatting Persistence-EEPROM and reseting to default");
FormatPersistence_EEPROM();
}
void RemotDebug_printSystemInfo()
{
debugA("Souko's ChainOiler Mk1");
debugA("Hostname: %s", globals.DeviceName);
FlashMode_t ideMode = ESP.getFlashChipMode();
debugA("Sdk version: %s", ESP.getSdkVersion());
debugA("Core Version: %s", ESP.getCoreVersion().c_str());
debugA("Boot Version: %u", ESP.getBootVersion());
debugA("Boot Mode: %u", ESP.getBootMode());
debugA("CPU Frequency: %u MHz", ESP.getCpuFreqMHz());
debugA("Reset reason: %s", ESP.getResetReason().c_str());
debugA("Flash Size: %d", ESP.getFlashChipRealSize());
debugA("Flash Size IDE: %d", ESP.getFlashChipSize());
debugA("Flash ide mode: %s", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT"
: ideMode == FM_DIO ? "DIO"
: ideMode == FM_DOUT ? "DOUT"
: "UNKNOWN"));
debugA("OTA-Pass: %s", QUOTE(ADMIN_PASSWORD));
debugA("Git-Revison: %s", GIT_REV);
debugA("Sw-Version: %d.%02d", SW_VERSION_MAJOR, SW_VERSION_MINOR);
}
void RemoteDebug_dumpConfig()
{
debugA("DistancePerLube_Default: %d", LubeConfig.DistancePerLube_Default);
debugA("DistancePerLube_Rain: %d", LubeConfig.DistancePerLube_Rain);
debugA("tankCapacity_ml: %d", LubeConfig.tankCapacity_ml);
debugA("amountPerDose_µl: %d", LubeConfig.amountPerDose_µl);
debugA("TankRemindAtPercentage: %d", LubeConfig.TankRemindAtPercentage);
debugA("PulsePerRevolution: %d", LubeConfig.PulsePerRevolution);
debugA("TireWidth_mm: %d", LubeConfig.TireWidth_mm);
debugA("TireWidthHeight_Ratio: %d", LubeConfig.TireWidth_mm);
debugA("RimDiameter_Inch: %d", LubeConfig.RimDiameter_Inch);
debugA("DistancePerRevolution_mm: %d", LubeConfig.DistancePerRevolution_mm);
debugA("BleedingPulses: %d", LubeConfig.BleedingPulses);
debugA("SpeedSource: %d", LubeConfig.SpeedSource);
#ifdef FEATURE_ENABLE_GPS
debugA("GPSBaudRate: %d", LubeConfig.GPSBaudRate);
#endif
#ifdef FEATURE_ENABLE_CAN
debugA("CANSource: %d", LubeConfig.CANSource);
#endif
debugA("checksum: 0x%08X", LubeConfig.checksum);
}
void RemoteDebug_dumpPersistance()
{
debugA("writeCycleCounter: %d", PersistenceData.writeCycleCounter);
debugA("tankRemain_µl: %d", PersistenceData.tankRemain_µl);
debugA("TravelDistance_highRes_mm: %d", PersistenceData.TravelDistance_highRes_mm);
debugA("checksum: %d", PersistenceData.checksum);
debugA("PSD Adress: 0x%04X", globals.eePersistanceAdress);
}
void RemoteDebug_printWifiInfo()
{
}
void RemoteDebug_CheckEEPOM()
{
uint32_t checksum = PersistenceData.checksum;
PersistenceData.checksum = 0;
if (Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)) == checksum)
{
debugA("PersistenceData EEPROM Checksum OK\n");
}
else
{
debugA("PersistenceData EEPROM Checksum BAD\n");
}
PersistenceData.checksum = checksum;
checksum = LubeConfig.checksum;
LubeConfig.checksum = 0;
if (Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig)) == checksum)
{
debugA("LubeConfig EEPROM Checksum OK\n");
}
else
{
debugA("LubeConfig EEPROM Checksum BAD\n");
}
LubeConfig.checksum = checksum;
}
#endif
#ifdef FEATURE_ENABLE_WIFI_CLIENT #ifdef FEATURE_ENABLE_WIFI_CLIENT
void wifiMaintainConnectionTicker_callback() void wifiMaintainConnectionTicker_callback()
{ {
@@ -412,7 +230,7 @@ void wifiMaintainConnectionTicker_callback()
} }
else else
{ {
debugV("WiFi not connected! - Start AP"); Debug_pushMessage("WiFi not connected! - Start AP");
toggleWiFiAP(); toggleWiFiAP();
} }
} }
@@ -458,7 +276,7 @@ void LED_Process(uint8_t override, CRGB SetColor)
if (LED_Status != LED_Override) if (LED_Status != LED_Override)
{ {
LED_ResumeOverrideStatus = LED_Status; LED_ResumeOverrideStatus = LED_Status;
debugV("Override LED_Status"); Debug_pushMessage("Override LED_Status");
} }
LED_Status = LED_Override; LED_Status = LED_Override;
LED_override_color = SetColor; LED_override_color = SetColor;
@@ -469,7 +287,7 @@ void LED_Process(uint8_t override, CRGB SetColor)
if (LED_Status == LED_Override) if (LED_Status == LED_Override)
{ {
LED_Status = LED_ResumeOverrideStatus; LED_Status = LED_ResumeOverrideStatus;
debugV("Resume LED_Status"); Debug_pushMessage("Resume LED_Status");
} }
} }
@@ -479,25 +297,25 @@ void LED_Process(uint8_t override, CRGB SetColor)
{ {
case sysStat_Startup: case sysStat_Startup:
LED_Status = LED_Startup; LED_Status = LED_Startup;
debugV("sysStat: Startup"); Debug_pushMessage("sysStat: Startup");
break; break;
case sysStat_Normal: case sysStat_Normal:
timestamp = timer + 3500; timestamp = timer + 3500;
LED_Status = LED_Confirm_Normal; LED_Status = LED_Confirm_Normal;
debugV("sysStat: Normal"); Debug_pushMessage("sysStat: Normal");
break; break;
case sysStat_Rain: case sysStat_Rain:
timestamp = timer + 3500; timestamp = timer + 3500;
LED_Status = LED_Confirm_Rain; LED_Status = LED_Confirm_Rain;
debugV("sysStat: Rain"); Debug_pushMessage("sysStat: Rain");
break; break;
case sysStat_Purge: case sysStat_Purge:
LED_Status = LED_Purge; LED_Status = LED_Purge;
debugV("sysStat: Purge"); Debug_pushMessage("sysStat: Purge");
break; break;
case sysStat_Error: case sysStat_Error:
LED_Status = LED_Error; LED_Status = LED_Error;
debugV("sysStat: Error"); Debug_pushMessage("sysStat: Error");
break; break;
case sysStat_Shutdown: case sysStat_Shutdown:
default: default:
@@ -524,7 +342,7 @@ void LED_Process(uint8_t override, CRGB SetColor)
{ {
LED_Status = LED_Normal; LED_Status = LED_Normal;
FastLED.setBrightness(64); FastLED.setBrightness(64);
debugV("LED_Status: Confirm -> Normal"); Debug_pushMessage("LED_Status: Confirm -> Normal");
} }
break; break;
@@ -548,7 +366,7 @@ void LED_Process(uint8_t override, CRGB SetColor)
{ {
LED_Status = LED_Rain; LED_Status = LED_Rain;
FastLED.setBrightness(64); FastLED.setBrightness(64);
debugV("LED_Status: Confirm -> Rain"); Debug_pushMessage("LED_Status: Confirm -> Rain");
} }
break; break;
@@ -602,7 +420,7 @@ void Display_Process()
u8x8.setCursor(0, 1); u8x8.setCursor(0, 1);
uint32_t DistRemain = globals.systemStatus == sysStat_Normal ? LubeConfig.DistancePerLube_Default : LubeConfig.DistancePerLube_Rain; uint32_t DistRemain = globals.systemStatus == sysStat_Normal ? LubeConfig.DistancePerLube_Default : LubeConfig.DistancePerLube_Rain;
DistRemain -= TravelDistance_highRes / 1000; DistRemain = DistRemain - (PersistenceData.TravelDistance_highRes_mm / 1000);
u8x8.printf(PSTR("Mode: %10s\n"), globals.systemStatustxt); u8x8.printf(PSTR("Mode: %10s\n"), globals.systemStatustxt);
if (globals.systemStatus == sysStat_Error) if (globals.systemStatus == sysStat_Error)
{ {
@@ -611,7 +429,7 @@ void Display_Process()
else else
{ {
u8x8.printf(PSTR("next Lube: %4dm\n"), DistRemain); u8x8.printf(PSTR("next Lube: %4dm\n"), DistRemain);
u8x8.printf(PSTR("Tank: %8dml\n"), PersistenceData.tankRemain_µl / 1000); u8x8.printf(PSTR("Tank: %8dml\n"), PersistenceData.tankRemain_microL / 1000);
u8x8.printf(PSTR("WiFi: %10s\n"), (WiFi.getMode() == WIFI_AP ? "AP" : WiFi.getMode() == WIFI_OFF ? "OFF" u8x8.printf(PSTR("WiFi: %10s\n"), (WiFi.getMode() == WIFI_AP ? "AP" : WiFi.getMode() == WIFI_OFF ? "OFF"
: WiFi.getMode() == WIFI_STA ? "CLIENT" : WiFi.getMode() == WIFI_STA ? "CLIENT"
: "UNKNOWN")); : "UNKNOWN"));
@@ -678,13 +496,13 @@ void Button_Process()
{ {
case BTN_TOGGLEWIFI: case BTN_TOGGLEWIFI:
toggleWiFiAP(); toggleWiFiAP();
debugV("Starting WiFi AP"); Debug_pushMessage("Starting WiFi AP");
break; break;
case BTN_STARTPURGE: case BTN_STARTPURGE:
globals.systemStatus = sysStat_Purge; globals.systemStatus = sysStat_Purge;
globals.purgePulses = LubeConfig.BleedingPulses; globals.purgePulses = LubeConfig.BleedingPulses;
debugV("Starting Purge"); Debug_pushMessage("Starting Purge");
break; break;
case BTN_TOGGLEMODE: case BTN_TOGGLEMODE:
@@ -702,12 +520,12 @@ void Button_Process()
default: default:
break; break;
} }
debugV("Toggling Mode"); Debug_pushMessage("Toggling Mode");
break; break;
case BTN_NOTHING: case BTN_NOTHING:
default: default:
debugV("Nothing or invalid"); Debug_pushMessage("Nothing or invalid");
break; break;
} }
LED_Process(2); LED_Process(2);
@@ -722,7 +540,7 @@ void toggleWiFiAP(boolean shutdown)
if (WiFi.getMode() != WIFI_OFF) if (WiFi.getMode() != WIFI_OFF)
{ {
WiFi.mode(WIFI_OFF); WiFi.mode(WIFI_OFF);
debugV("WiFi turned off"); Debug_pushMessage("WiFi turned off");
#ifdef FEATURE_ENABLE_WIFI_CLIENT #ifdef FEATURE_ENABLE_WIFI_CLIENT
WiFiMaintainConnectionTicker.stop(); WiFiMaintainConnectionTicker.stop();
#endif #endif
@@ -734,9 +552,9 @@ void toggleWiFiAP(boolean shutdown)
WiFi.softAP(globals.DeviceName, QUOTE(WIFI_AP_PASSWORD)); WiFi.softAP(globals.DeviceName, QUOTE(WIFI_AP_PASSWORD));
#ifdef FEATURE_ENABLE_WIFI_CLIENT #ifdef FEATURE_ENABLE_WIFI_CLIENT
WiFiMaintainConnectionTicker.stop(); WiFiMaintainConnectionTicker.stop();
debugV("WiFi AP started, stopped Maintain-Timer"); Debug_pushMessage("WiFi AP started, stopped Maintain-Timer");
#else #else
debugV("WiFi AP started"); Debug_pushMessage("WiFi AP started");
#endif #endif
} }
} }
@@ -748,7 +566,7 @@ void SystemShutdown()
if (shutdown_delay == 0) if (shutdown_delay == 0)
{ {
shutdown_delay = millis() + SHUTDOWN_DELAY_MS; shutdown_delay = millis() + SHUTDOWN_DELAY_MS;
Serial.printf("Shutdown requested - Restarting in %d seconds\n", SHUTDOWN_DELAY_MS); Serial.printf("Shutdown requested - Restarting in %d seconds\n", SHUTDOWN_DELAY_MS / 1000);
} }
if (shutdown_delay < millis()) if (shutdown_delay < millis())
{ {
@@ -768,32 +586,3 @@ uint32_t Process_Impulse_WheelSpeed()
return add_milimeters; return add_milimeters;
} }
#ifdef FEATURE_ENABLE_REMOTE_DEBUG
void RemoteDebug_ShowDTCs()
{
char buff_timestamp[16]; // Format: DD-hh:mm:ss:xxx
char buff_active[9];
for (uint32_t i = 0; i < MAX_DTC_STORAGE; i++)
{
if (DTCStorage[i].Number < DTC_LAST_DTC)
{
sprintf(buff_timestamp, "%02d-%02d:%02d:%02d:%03d",
DTCStorage[i].timestamp / 86400000, // Days
DTCStorage[i].timestamp / 360000 % 24, // Hours
DTCStorage[i].timestamp / 60000 % 60, // Minutes
DTCStorage[i].timestamp / 1000 % 60, // Seconds
DTCStorage[i].timestamp % 1000); // milliseconds
if (DTCStorage[i].active == DTC_ACTIVE)
strcpy(buff_active, "active");
else if (DTCStorage[i].active == DTC_PREVIOUS)
strcpy(buff_active, "previous");
else
strcpy(buff_active, "none");
debugA("%s \t %6d \t %s", buff_timestamp, DTCStorage[i].Number, buff_active);
}
}
}
#endif

View File

@@ -9,44 +9,69 @@ void WebserverPOST_Callback(AsyncWebServerRequest *request);
void WebserverNotFound_Callback(AsyncWebServerRequest *request); void WebserverNotFound_Callback(AsyncWebServerRequest *request);
void Webserver_Callback(AsyncWebServerRequest *request); void Webserver_Callback(AsyncWebServerRequest *request);
void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final); void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final);
uint32_t GetFlashVersion(); void WebserverEERestore_Callback(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final);
void WebServerEEJSON_Callback(AsyncWebServerRequest *request);
void GetFlashVersion(char *buff, size_t buff_size);
#ifdef FEATURE_ENABLE_WEBSOCKETS
AsyncWebSocket webSocket("/ws");
void WebsocketEvent_Callback(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len);
void Websocket_HandleMessage(void *arg, uint8_t *data, size_t len);
#endif
void initWebUI() void initWebUI()
{ {
if (!LittleFS.begin()) if (!LittleFS.begin())
{ {
Serial.println("An Error has occurred while mounting LittleFS"); Debug_pushMessage("An Error has occurred while mounting LittleFS\n");
MaintainDTC(DTC_FLASHFS_ERROR, DTC_CRITICAL, true); MaintainDTC(DTC_FLASHFS_ERROR, DTC_CRITICAL, true);
return; return;
} }
GetFlashVersion(globals.FlashVersion, sizeof(globals.FlashVersion)); GetFlashVersion(globals.FlashVersion, sizeof(globals.FlashVersion));
if (!strcmp(globals.FlashVersion, QUOTE(FLASH_FS_VERSION)) if (strcmp(globals.FlashVersion, QUOTE(FLASH_FS_VERSION)))
{ {
MaintainDTC(DTC_FLASHFS_VERSION_ERROR, DTC_WARN, true); MaintainDTC(DTC_FLASHFS_VERSION_ERROR, DTC_WARN, true);
} }
MDNS.begin(globals.DeviceName); MDNS.begin(globals.DeviceName);
MDNS.addService("telnet", "tcp", 23);
MDNS.addService("http", "tcp", 80); MDNS.addService("http", "tcp", 80);
#ifdef FEATURE_ENABLE_WEBSOCKETS
webSocket.onEvent(WebsocketEvent_Callback);
webServer.addHandler(&webSocket);
#endif
webServer.serveStatic("/static/", LittleFS, "/static/").setCacheControl("max-age=360000"); webServer.serveStatic("/static/", LittleFS, "/static/").setCacheControl("max-age=360000");
webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request) webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->redirect("/index.htm"); }); { request->redirect("/index.htm"); });
webServer.onNotFound(WebserverNotFound_Callback); webServer.onNotFound(WebserverNotFound_Callback);
webServer.on("/index.htm", HTTP_GET, Webserver_Callback); webServer.on("/index.htm", HTTP_GET, Webserver_Callback);
webServer.on("/post.htm", HTTP_POST, WebserverPOST_Callback); webServer.on("/post.htm", HTTP_POST, WebserverPOST_Callback);
webServer.on("/eejson", HTTP_GET, WebServerEEJSON_Callback);
webServer.on( webServer.on(
"/doUpdate", HTTP_POST, [](AsyncWebServerRequest *request) {}, WebserverFirmwareUpdate_Callback); "/doUpdate", HTTP_POST, [](AsyncWebServerRequest *request) {}, WebserverFirmwareUpdate_Callback);
webServer.on(
"/eeRestore", HTTP_POST, [](AsyncWebServerRequest *request) {}, WebserverEERestore_Callback);
webServer.begin(); webServer.begin();
} }
void Webserver_Process()
{
#ifdef FEATURE_ENABLE_WEBSOCKETS
webSocket.cleanupClients();
#endif
}
String processor(const String &var) String processor(const String &var)
{ {
if (var == "TANK_REMAIN_CAPACITY") if (var == "TANK_REMAIN_CAPACITY")
return String((PersistenceData.tankRemain_µl / 10) / LubeConfig.tankCapacity_ml); return String((PersistenceData.tankRemain_microL / 10) / LubeConfig.tankCapacity_ml);
if (var == "LUBE_DISTANCE_NORMAL") if (var == "LUBE_DISTANCE_NORMAL")
return String(LubeConfig.DistancePerLube_Default); return String(LubeConfig.DistancePerLube_Default);
if (var == "LUBE_DISTANCE_RAIN") if (var == "LUBE_DISTANCE_RAIN")
@@ -54,7 +79,7 @@ String processor(const String &var)
if (var == "TANK_CAPACITY") if (var == "TANK_CAPACITY")
return String(LubeConfig.tankCapacity_ml); return String(LubeConfig.tankCapacity_ml);
if (var == "AMOUNT_PER_DOSE") if (var == "AMOUNT_PER_DOSE")
return String(LubeConfig.amountPerDose_µl); return String(LubeConfig.amountPerDose_microL);
if (var == "TANK_REMIND") if (var == "TANK_REMIND")
return String(LubeConfig.TankRemindAtPercentage); return String(LubeConfig.TankRemindAtPercentage);
if (var == "PULSE_PER_REV") if (var == "PULSE_PER_REV")
@@ -94,7 +119,7 @@ String processor(const String &var)
if (var == "PERSISTENCE_MARKER") if (var == "PERSISTENCE_MARKER")
return String(globals.eePersistanceAdress); return String(globals.eePersistanceAdress);
if (var == "TANK_REMAIN_UL") if (var == "TANK_REMAIN_UL")
return String(PersistenceData.tankRemain_µl); return String(PersistenceData.tankRemain_microL);
if (var == "TRAVEL_DISTANCE_HIGHRES") if (var == "TRAVEL_DISTANCE_HIGHRES")
return String(PersistenceData.TravelDistance_highRes_mm); return String(PersistenceData.TravelDistance_highRes_mm);
if (var == "ODOMETER") if (var == "ODOMETER")
@@ -140,7 +165,8 @@ String processor(const String &var)
DTCStorage[i].timestamp / 1000 % 60, // Seconds DTCStorage[i].timestamp / 1000 % 60, // Seconds
DTCStorage[i].timestamp % 1000); // milliseconds DTCStorage[i].timestamp % 1000); // milliseconds
temp = temp + "<tr><td>" + String(buff_timestamp); temp = temp + "<tr data-dtc=" + String(DTCStorage[i].Number);
temp = temp + " data-debugval=" + String(DTCStorage[i].debugVal) + "><td>" + String(buff_timestamp);
temp = temp + "</td><td>" + String(DTCStorage[i].Number) + "</td><td>"; temp = temp + "</td><td>" + String(DTCStorage[i].Number) + "</td><td>";
temp = temp + "<img src=static/img/"; temp = temp + "<img src=static/img/";
switch (DTCStorage[i].severity) switch (DTCStorage[i].severity)
@@ -155,7 +181,7 @@ String processor(const String &var)
temp = temp + "info"; temp = temp + "info";
break; break;
} }
temp = temp + "_black.png></td><td>"; temp = temp + ".png></td><td>";
if (DTCStorage[i].active == DTC_ACTIVE) if (DTCStorage[i].active == DTC_ACTIVE)
temp = temp + "active"; temp = temp + "active";
@@ -210,9 +236,7 @@ String processor(const String &var)
return String(globals.systemStatustxt); return String(globals.systemStatustxt);
if (var == "SW_VERSION") if (var == "SW_VERSION")
{ {
char buffer[7]; return String(QUOTE(SW_VERSION));
sprintf(buffer, "%d.%02d", SW_VERSION_MAJOR, SW_VERSION_MINOR);
return String(buffer);
} }
if (var == "FS_VERSION") if (var == "FS_VERSION")
return String(globals.FlashVersion); return String(globals.FlashVersion);
@@ -232,19 +256,19 @@ void WebserverPOST_Callback(AsyncWebServerRequest *request)
{ {
request->send(LittleFS, "/post.htm", "text/html", false, processor); request->send(LittleFS, "/post.htm", "text/html", false, processor);
Serial.print("POST:\n"); Debug_pushMessage("POST:\n");
int paramsNr = request->params(); int paramsNr = request->params();
for (int i = 0; i < paramsNr; i++) for (int i = 0; i < paramsNr; i++)
{ {
AsyncWebParameter *p = request->getParam(i); AsyncWebParameter *p = request->getParam(i);
Serial.printf("%s : %s\n", p->name().c_str(), p->value().c_str()); Debug_pushMessage("%s : %s\n", p->name().c_str(), p->value().c_str());
// begin: POST Form Source Changed // begin: POST Form Source Changed
if (p->name() == "sourceselect") if (p->name() == "sourceselect")
{ {
SpeedSource_t temp = (SpeedSource_t)p->value().toInt(); SpeedSource_t temp = (SpeedSource_t)p->value().toInt();
Serial.printf("temp: %d", temp); Debug_pushMessage("temp: %d", temp);
Serial.printf("SpeedSource: %d", LubeConfig.SpeedSource); Debug_pushMessage("SpeedSource: %d", LubeConfig.SpeedSource);
if (LubeConfig.SpeedSource != temp) if (LubeConfig.SpeedSource != temp)
{ {
LubeConfig.SpeedSource = temp; LubeConfig.SpeedSource = temp;
@@ -294,7 +318,7 @@ void WebserverPOST_Callback(AsyncWebServerRequest *request)
if (p->name() == "tankwarn") if (p->name() == "tankwarn")
LubeConfig.TankRemindAtPercentage = p->value().toInt(); LubeConfig.TankRemindAtPercentage = p->value().toInt();
if (p->name() == "pumppulse") if (p->name() == "pumppulse")
LubeConfig.amountPerDose_µl = p->value().toInt(); LubeConfig.amountPerDose_microL = p->value().toInt();
if (p->name() == "oilsave") if (p->name() == "oilsave")
globals.requestEEAction = EE_CFG_SAVE; globals.requestEEAction = EE_CFG_SAVE;
// end: POST Form Oiltank // end: POST Form Oiltank
@@ -305,18 +329,33 @@ void WebserverPOST_Callback(AsyncWebServerRequest *request)
globals.requestEEAction = EE_CFG_SAVE; globals.requestEEAction = EE_CFG_SAVE;
if (p->name() == "resettank") if (p->name() == "resettank")
{ {
PersistenceData.tankRemain_µl = LubeConfig.tankCapacity_ml * 1000; PersistenceData.tankRemain_microL = LubeConfig.tankCapacity_ml * 1000;
globals.requestEEAction = EE_PDS_SAVE; globals.requestEEAction = EE_PDS_SAVE;
} }
if (p->name() == "reset_ee_cfg") if (p->name() == "reset_ee_btn")
{ {
globals.requestEEAction = EE_CFG_FORMAT; if (request->hasParam("reset_ee_pds", true))
}
if (p->name() == "reset_ee_pds")
{ {
globals.requestEEAction = EE_PDS_FORMAT; AsyncWebParameter *param = request->getParam("reset_ee_pds", true);
if (param->value() == "on")
globals.requestEEAction = globals.requestEEAction == EE_CFG_FORMAT ? EE_FORMAT_ALL : EE_PDS_FORMAT;
}
if (request->hasParam("reset_ee_cfg", true))
{
AsyncWebParameter *param = request->getParam("reset_ee_cfg", true);
if (param->value() == "on")
globals.requestEEAction = globals.requestEEAction == EE_PDS_FORMAT ? EE_FORMAT_ALL : EE_CFG_FORMAT;
}
}
if (p->name() == "purgenow")
{
globals.systemStatus = sysStat_Purge;
globals.purgePulses = LubeConfig.BleedingPulses;
}
if (p->name() == "reboot")
{
globals.systemStatus = sysStat_Shutdown;
} }
// end: POST Form Maintenance // end: POST Form Maintenance
} }
} }
@@ -337,7 +376,7 @@ void GetFlashVersion(char *buff, size_t buff_size)
if (this_file.available()) if (this_file.available())
{ {
int bytes_read; int bytes_read;
bytes_read = this_file.readBytesUntil('\r', buff, buff_size-1); bytes_read = this_file.readBytesUntil('\r', buff, buff_size - 1);
buff[bytes_read] = '\0'; buff[bytes_read] = '\0';
} }
this_file.close(); this_file.close();
@@ -348,9 +387,8 @@ void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const Stri
if (!index) if (!index)
{ {
Serial.println("Update"); Debug_pushMessage("Update");
size_t content_len = request->contentLength(); size_t content_len = request->contentLength();
// if filename includes spiffs, update the spiffs partition
int cmd = (filename.indexOf(".fs") > -1) ? U_FS : U_FLASH; int cmd = (filename.indexOf(".fs") > -1) ? U_FS : U_FLASH;
Update.runAsync(true); Update.runAsync(true);
if (!Update.begin(content_len, cmd)) if (!Update.begin(content_len, cmd))
@@ -365,7 +403,7 @@ void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const Stri
} }
else else
{ {
Serial.printf("Progress: %d%%\n", (Update.progress() * 100) / Update.size()); Debug_pushMessage("Progress: %d%%\n", (Update.progress() * 100) / Update.size());
} }
if (final) if (final)
@@ -380,9 +418,154 @@ void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const Stri
} }
else else
{ {
Serial.println("Update complete"); Debug_pushMessage("Update complete\n");
Serial.flush();
globals.systemStatus = sysStat_Shutdown; globals.systemStatus = sysStat_Shutdown;
} }
} }
} }
void WebserverEERestore_Callback(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final)
{
bool ee_done = false;
bool validext = false;
if (!index)
{
Debug_pushMessage("EEPROM restore\n");
// size_t content_len = request->contentLength();
validext = (filename.indexOf(".ee.json") > -1);
}
if (validext)
{
Debug_pushMessage("Restoring EEPROM-Stuff\n");
}
if (final)
{
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "Please wait while the device reboots");
response->addHeader("Refresh", "20");
response->addHeader("Location", "/");
request->send(response);
if (ee_done)
{
Debug_pushMessage("Update complete");
globals.systemStatus = sysStat_Shutdown;
}
else
{
}
}
}
void WebServerEEJSON_Callback(AsyncWebServerRequest *request)
{
AsyncResponseStream *response = request->beginResponseStream("application/json");
DynamicJsonDocument json(1024);
JsonObject fwinfo = json.createNestedObject("info");
char buffer[16];
fwinfo["DeviceName"] = globals.DeviceName;
fwinfo["FW-Version"] = QUOTE(SW_VERSION);
fwinfo["FS-Version"] = globals.FlashVersion;
JsonObject config = json.createNestedObject("config");
config["EEPROM_Version"] = LubeConfig.EEPROM_Version;
config["DistancePerLube_Default"] = LubeConfig.DistancePerLube_Default;
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];
#ifdef FEATURE_ENABLE_GPS
config["GPSBaudRate"] = LubeConfig.GPSBaudRate;
config["GPSBaudRate_Str"] = GPSBaudRateString[LubeConfig.GPSBaudRate];
#endif
#ifdef FEATURE_ENABLE_CAN
config["CANSource"] = LubeConfig.CANSource;
config["CANSource_Str"] = CANSourceString[LubeConfig.CANSource];
#endif
sprintf(buffer, "0x%08X", LubeConfig.checksum);
config["checksum"] = buffer;
JsonObject eepart = json.createNestedObject("eepart");
sprintf(buffer, "0x%04X", globals.eePersistanceAdress);
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);
response->addHeader("Content-disposition", "attachment; filename=backup.ee.json");
request->send(response);
}
#ifdef FEATURE_ENABLE_WEBSOCKETS
void WebsocketEvent_Callback(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len)
{
switch (type)
{
case WS_EVT_CONNECT:
Debug_pushMessage("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
break;
case WS_EVT_DISCONNECT:
Debug_pushMessage("WebSocket client #%u disconnected\n", client->id());
break;
case WS_EVT_DATA:
Websocket_HandleMessage(arg, data, len);
break;
case WS_EVT_PONG:
case WS_EVT_ERROR:
break;
}
}
void Websocket_HandleMessage(void *arg, uint8_t *data, size_t len)
{
AwsFrameInfo *info = (AwsFrameInfo *)arg;
if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT)
{
data[len] = 0;
Debug_pushMessage("Got WebSocket Message: %s \n", (char *)data);
if (strcmp((char *)data, "start") == 0)
{
SetDebugportStatus(dbg_Webui, enabled);
}
else if (strcmp((char *)data, "stop") == 0)
{
SetDebugportStatus(dbg_Webui, disabled);
}
else if (strcmp((char *)data, "foo") == 0)
{
Debug_pushMessage("Got WebSocket Message 'foo' from client\n");
}
}
}
void Websocket_PushLiveDebug(String Message)
{
webSocket.textAll(Message + "\n");
}
#endif

View File

@@ -8,12 +8,20 @@
#include <ESPAsyncWebServer.h> #include <ESPAsyncWebServer.h>
#include <Updater.h> #include <Updater.h>
#include <ESP8266mDNS.h> #include <ESP8266mDNS.h>
#include <AsyncJson.h>
#include <ArduinoJson.h>
#include "config.h" #include "config.h"
#include "globals.h" #include "globals.h"
#include "dtc.h" #include "dtc.h"
#include "common.h" #include "common.h"
#include "debugger.h"
void initWebUI(); void initWebUI();
void Webserver_Process();
#ifdef FEATURE_ENABLE_WEBSOCKETS
void Websocket_PushLiveDebug(String Message);
#endif
#endif #endif