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

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;
} }
MaintainDTC(DTC_NO_CAN_SIGNAL, DTC_CRITICAL, (millis() > lastRecTimestamp + 10000 ? true : false)); if (lastRecTimestamp != 0)
{
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;
} }
} }
@@ -103,4 +107,33 @@ 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))
{
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() == "reset_ee_pds") if (p->name() == "purgenow")
{ {
globals.requestEEAction = EE_PDS_FORMAT; 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