Skip to content

Commit cf7dbd6

Browse files
committedMay 26, 2021
Merge pull request doudar#155 from kadaan/Improve_logging
Improve logging
1 parent 5cea40a commit cf7dbd6

27 files changed

+784
-524
lines changed
 

‎.github/workflows/pre-commit.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ jobs:
2828
if: steps.filter.outputs.software == 'true'
2929
uses: docker://kadaan/platformio_esp32:latest
3030
with:
31-
args: --build=esp32doit
31+
args: --build=release

‎CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3030
- Filter Flywheel advertisements by name.
3131
- Add documentation to SensorData class.
3232
- Enabled native testing.
33+
- Added logging library which supports levels.
3334

3435
### Changed
3536
- Moved Vin to the correct side on the ESP32 connection diagram.
@@ -56,6 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5657
- Ignore zero heart rate reported from remote FTMS.
5758
- Fix Assimoa Uno stuck cadence.
5859
- Started extract non-arduino code into a cross-platform library.
60+
- Changed all logging calls to new logging library.
5961

6062
### Removed
6163
- Deleted and ignored .pio folder which had been mistakenly committed.

‎build_date_macro.py

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from datetime import datetime
2+
3+
print("-DBUILD_TIMESTAMP='\"%s\"'" % datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S GMT"))

‎data/settings.html

+12-8
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,14 @@ <h2>
136136
</body>
137137

138138
<script>
139-
//Update values on specified interval loading late because this tiny webserver hates frequent requests
140-
setInterval(function () {
141-
if (document.getElementById("ssid").value == "loading") {
142-
requestConfigValues();
143-
}
144-
145-
}, 1000);
139+
function startConfigUpdate() {
140+
//Update values on specified interval loading late because this tiny webserver hates frequent requests
141+
setTimeout(function () {
142+
if (document.getElementById("ssid").value == "loading") {
143+
requestConfigValues();
144+
}
145+
}, 1000);
146+
}
146147

147148
function requestConfigValues() {
148149
var xhttp = new XMLHttpRequest();
@@ -161,7 +162,9 @@ <h2>
161162
updateSlider(document.getElementById("inclineMultiplier").value, document.getElementById("inclineMultiplierValue"));
162163
updateSlider(document.getElementById("stepperPower").value, document.getElementById("stepperPowerValue"));
163164
document.getElementById("loadingWatermark").opacity = 0;
164-
setTimeout(function () { document.getElementById("loadingWatermark").remove(); }, 1000);
165+
document.getElementById("loadingWatermark").remove();
166+
} else {
167+
startConfigUpdate();
165168
}
166169
};
167170
xhttp.open("GET", "/configJSON", true);
@@ -180,6 +183,7 @@ <h2>
180183
//Delay loading css to not swamp webserver
181184
window.addEventListener('load', function () {
182185
setTimeout(loadCss, 100);
186+
startConfigUpdate();
183187
}, false);
184188

185189
function updateSlider(x, valueElement) {

‎data/status.html

+82-34
Original file line numberDiff line numberDiff line change
@@ -77,51 +77,99 @@ <h2>
7777
</tbody>
7878
</table>
7979
</form>
80-
<p style="text-align: left; margin-left:0 auto;">Debugging Info:</p>
81-
<div id="debug" name="debug"
82-
style="margin-left:0 auto;background-color:black;background-image:radial-gradient(rgba(0,150,0,0.75), black 120%);text-align: left;height:30vh;width:100%;resize:both;border:1px solid #ccc;color:white;font:1.3rem Inconsolata, monospace;overflow:auto;text-shadow: 0 0 4px #C8C8C8;">
83-
loading </div>
80+
<table style="width: 100%;padding: 0;margin: 0;table-layout: fixed;">
81+
<tbody>
82+
<tr>
83+
<td>
84+
<p style="text-align: left;float: left;">Debugging Info:</p>
85+
</td>
86+
<td>
87+
<div style="float: right;">
88+
<input type="checkbox" id="follow" name="follow" checked="true">
89+
<label for="follow">Follow</label>
90+
</div>
91+
</td>
92+
</tr>
93+
<tr>
94+
<td colspan="2">
95+
<pre id="debug" name="debug" style="margin: 0;padding: 5;background-color:black;background-image:radial-gradient(rgba(0,150,0,0.75), black 120%);text-align: left;height:30vh;width:100%;resize:both;border:1px solid #ccc;color:white;font:1.3rem Inconsolata, monospace;overflow:auto;text-shadow: 0 0 4px #C8C8C8;">Loading</pre>
96+
</td>
97+
</tr>
98+
</tbody>
99+
</table>
84100
<br>
85101
</h2>
86102
</body>
87103

88104
<script>
89105

106+
var debugElement = document.getElementById("debug");
107+
var followElement = document.getElementById("follow");
108+
var updatePending = false;
109+
var updateTimer = undefined;
110+
111+
function onVisibilityChanged() {
112+
if (document.hidden || document.mozHidden || document.webkitHidden || document.msHidden) {
113+
stopUpdate();
114+
} else {
115+
startUpdate();
116+
}
117+
}
90118

91-
var element = document.getElementById("debug");
92-
element.scrollTop = element.scrollHeight;
119+
document.addEventListener("visibilitychange", onVisibilityChanged, false);
120+
document.addEventListener("mozvisibilitychange", onVisibilityChanged, false);
121+
document.addEventListener("webkitvisibilitychange", onVisibilityChanged, false);
122+
document.addEventListener("msvisibilitychange", onVisibilityChanged, false);
93123

94-
function updateScroll() {
95-
var element = document.getElementById("debug");
96-
element.scrollTop = element.scrollHeight;
124+
function startUpdate() {
125+
//Update values on specified interval loading late because this tiny webserver hates frequent requests
126+
if (updateTimer === undefined) {
127+
updateTimer = setInterval(function () {
128+
requestConfigValues();
129+
}, 1000);
130+
}
97131
}
98132

99-
//Update values on specified interval loading late because this tiny webserver hates frequent requests
100-
setInterval(function () {
101-
requestConfigValues();
102-
}, 1000);
133+
function stopUpdate() {
134+
clearInterval(updateTimer);
135+
updateTimer = undefined;
136+
}
137+
138+
function updateDebugView(newContent) {
139+
if (followElement.checked) {
140+
debugElement.scrollTop = debugElement.scrollHeight - debugElement.clientHeight
141+
}
142+
}
103143

104144
function requestConfigValues() {
105-
var xhttp = new XMLHttpRequest();
106-
xhttp.onreadystatechange = function () {
107-
if (this.readyState == 4 && this.status == 200) {
108-
var obj = JSON.parse(this.responseText);
109-
document.getElementById("ssid").value = obj.ssid;
110-
document.getElementById("connectedHeartMonitor").value = obj.connectedHeartMonitor;
111-
document.getElementById("deviceName").value = obj.deviceName;
112-
document.getElementById("shiftStep").value = obj.shiftStep;
113-
document.getElementById("inclineMultiplier").value = obj.inclineMultiplier;
114-
document.getElementById("incline").value = obj.incline;
115-
document.getElementById("simulatedHr").value = obj.simulatedHr;
116-
document.getElementById("simulatedWatts").value = obj.simulatedWatts;
117-
document.getElementById("simulatedCad").value = obj.simulatedCad;
118-
document.getElementById("connectedPowerMeter").value = obj.connectedPowerMeter;
119-
document.getElementById("debug").innerHTML += obj.debug;
120-
updateScroll();
121-
}
122-
};
123-
xhttp.open("GET", "/configJSON", true);
124-
xhttp.send();
145+
if (!updatePending) {
146+
updatePending = true
147+
var xhttp = new XMLHttpRequest();
148+
xhttp.onreadystatechange = function () {
149+
updatePending = false;
150+
if (this.readyState == 4 && this.status == 200) {
151+
var obj = JSON.parse(this.responseText);
152+
document.getElementById("ssid").value = obj.ssid;
153+
document.getElementById("connectedHeartMonitor").value = obj.connectedHeartMonitor;
154+
document.getElementById("deviceName").value = obj.deviceName;
155+
document.getElementById("shiftStep").value = obj.shiftStep;
156+
document.getElementById("inclineMultiplier").value = obj.inclineMultiplier;
157+
document.getElementById("incline").value = obj.incline;
158+
document.getElementById("simulatedHr").value = obj.simulatedHr;
159+
document.getElementById("simulatedWatts").value = obj.simulatedWatts;
160+
document.getElementById("simulatedCad").value = obj.simulatedCad;
161+
document.getElementById("connectedPowerMeter").value = obj.connectedPowerMeter;
162+
if (debugElement.innerHTML == "Loading") {
163+
document.getElementById("debug").innerHTML = obj.debug;
164+
} else {
165+
document.getElementById("debug").innerHTML += obj.debug;
166+
}
167+
updateDebugView(obj.debug);
168+
}
169+
};
170+
xhttp.open("GET", "/configJSON?includeDebugLog=true", true);
171+
xhttp.send();
172+
}
125173
}
126174

127175
//define function to load css
@@ -136,8 +184,8 @@ <h2>
136184
//Delay loading css to not swamp webserver
137185
window.addEventListener('load', function () {
138186
setTimeout(loadCss, 100);
187+
startUpdate();
139188
}, false);
140-
141189
</script>
142190

143191
</html>

‎data/style.css

+134-131
Original file line numberDiff line numberDiff line change
@@ -15,153 +15,160 @@ div{
1515
font-size: medium;
1616
}
1717

18-
a{
19-
color:#000000;
18+
a {
19+
color: #000000;
20+
}
21+
a:visited {
22+
color: #000000;
23+
}
24+
h1 {
25+
color: #03245c;
26+
padding: 0.5rem;
27+
line-height: 1em;
2028
}
21-
a:visited{
29+
h2 {
2230
color: #000000;
31+
font-size: 1.5rem;
32+
font-weight: bold;
33+
}
34+
p {
35+
font-size: 1rem;
36+
}
37+
.button {
38+
display: inline-block;
39+
background-color: #2a9df4;
40+
border: line;
41+
border-radius: 4px;
42+
color: #d0efff;
43+
padding: 10px 40px;
44+
text-decoration: none;
45+
font-size: 20px;
46+
margin: 0px;
47+
cursor: pointer;
48+
}
49+
.button2 {
50+
background-color: #f44336;
51+
padding: 10px 35px;
52+
}
53+
.switch {
54+
position: relative;
55+
display: inline-block;
56+
width: 80px;
57+
height: 40px;
58+
}
59+
.switch input {
60+
display: none;
61+
}
62+
.slider {
63+
position: absolute;
64+
top: 0;
65+
left: 0;
66+
right: 0;
67+
bottom: 0;
68+
transition: 0.4s;
69+
background-color: #03254c;
70+
border-radius: 34px;
71+
}
72+
.slider:before {
73+
position: absolute;
74+
content: "";
75+
height: 37px;
76+
width: 37px;
77+
left: 2px;
78+
bottom: 2px;
79+
background-color: #d0efff;
80+
-webkit-transition: 0.4s;
81+
transition: 0.4s;
82+
border-radius: 68px;
83+
}
84+
input:checked + .slider {
85+
transition: 0.4s;
86+
background-color: #2a9df4;
87+
}
88+
input:checked + .slider:before {
89+
-webkit-transform: translateX(38px);
90+
-ms-transform: translateX(38px);
91+
transform: translateX(38px);
2392
}
24-
h1{
25-
color: #03245c;
26-
padding: .5rem;
27-
line-height: 1em;
28-
}
29-
h2{
30-
color: #000000;
31-
font-size: 1.5rem;
32-
font-weight: bold;
33-
}
34-
p{
35-
font-size: 1rem;
36-
}
37-
.button {
38-
display: inline-block;
39-
background-color: #2a9df4;
40-
border: line;
41-
border-radius: 4px;
42-
color: #d0efff;
43-
padding: 10px 40px;
44-
text-decoration: none;
45-
font-size: 20px;
46-
margin: 0px;
47-
cursor: pointer;
48-
}
49-
.button2 {
50-
background-color: #f44336;
51-
padding: 10px 35px;
52-
}
53-
.switch {
54-
position: relative;
55-
display: inline-block;
56-
width: 80px;
57-
height: 40px}
58-
.switch input {
59-
display: none}
60-
.slider {
61-
position: absolute;
62-
top: 0;
63-
left: 0;
64-
right: 0;
65-
bottom: 0;
66-
transition: .4s;
67-
background-color: #03254c;
68-
border-radius: 34px;
69-
}
70-
.slider:before {
71-
position: absolute;
72-
content: "";
73-
height: 37px;
74-
width: 37px;
75-
left: 2px;
76-
bottom: 2px;
77-
background-color: #d0efff;
78-
-webkit-transition: .4s;
79-
transition: .4s;
80-
border-radius: 68px;
81-
}
82-
input:checked+.slider {
83-
transition: .4s;
84-
background-color: #2a9df4}
85-
input:checked+.slider:before {
86-
-webkit-transform: translateX(38px);
87-
-ms-transform: translateX(38px);
88-
transform: translateX(38px);
89-
}
90-
.slider2 {
91-
-webkit-appearance: none;
92-
margin: 5px;
93-
width: 270px;
94-
height: 20px;
95-
background: #d0efff;
96-
/*outline:8px ridge rgba(170,50,220, .6);
93+
.slider2 {
94+
-webkit-appearance: none;
95+
margin: 5px;
96+
width: 270px;
97+
height: 20px;
98+
background: #d0efff;
99+
/*outline:8px ridge rgba(170,50,220, .6);
97100
border-radius: 2rem;*/
98-
outline: none;
99-
-webkit-transition: .2s; transition: opacity .2s;
100-
}
101-
.slider2::-webkit-slider-thumb {
102-
-webkit-appearance: none;
103-
appearance: none; width: 30px;
104-
height: 30px; background: #03254C;
105-
cursor: pointer;
106-
}
107-
.slider2::-moz-range-thumb { width: 30px;
108-
height: 30px; background: #1167b1;
109-
cursor: pointer;
110-
}
101+
outline: none;
102+
-webkit-transition: 0.2s;
103+
transition: opacity 0.2s;
104+
}
105+
.slider2::-webkit-slider-thumb {
106+
-webkit-appearance: none;
107+
appearance: none;
108+
width: 30px;
109+
height: 30px;
110+
background: #03254c;
111+
cursor: pointer;
112+
}
113+
.slider2::-moz-range-thumb {
114+
width: 30px;
115+
height: 30px;
116+
background: #1167b1;
117+
cursor: pointer;
118+
}
119+
120+
table.center {
121+
margin-left: auto;
122+
margin-right: auto;
123+
}
111124

112-
table.center {
113-
margin-left:auto;
114-
margin-right:auto;
115-
}
125+
.tooltip {
126+
position: relative;
127+
display: inline-block;
128+
border-bottom: 1px dotted #03254c;
129+
}
116130

117-
.tooltip {
118-
position: relative;
119-
display: inline-block;
120-
border-bottom: 1px dotted #03254c;
121-
}
122-
123-
.tooltip .tooltiptext {
124-
visibility: hidden;
125-
width: 120px;
126-
background-color: #03254c;
127-
color: #d0efff;
128-
text-align: center;
129-
border-radius: 6px;
130-
padding: 5px 0;
131-
132-
/* Position the tooltip */
133-
position: absolute;
134-
z-index: 1;
135-
}
136-
137-
.tooltip:hover .tooltiptext {
138-
visibility: visible;
139-
}
131+
.tooltip .tooltiptext {
132+
visibility: hidden;
133+
width: 120px;
134+
background-color: #03254c;
135+
color: #d0efff;
136+
text-align: center;
137+
border-radius: 6px;
138+
padding: 5px 0;
140139

141-
.watermark
142-
{
140+
/* Position the tooltip */
141+
position: absolute;
142+
z-index: 1;
143+
}
144+
145+
.tooltip:hover .tooltiptext {
146+
visibility: visible;
147+
}
148+
149+
.watermark {
143150
display: inline;
144151
position: fixed;
145152
top: 0px;
146153
left: 0px;
147-
transform: translate(calc(50vw - 200px), calc(50vh - 170px)) rotate(45deg);
148-
transition: .4s ease-in-out;
149-
opacity:.7;
150-
z-index:99;
151-
color:grey;
152-
font-size: 7rem
154+
transform: translate(calc(50vw - 200px), calc(50vh - 170px)) rotate(45deg);
155+
transition: 0.4s ease-in-out;
156+
opacity: 0.7;
157+
z-index: 99;
158+
color: grey;
159+
font-size: 7rem;
153160
}
154161

155162
.watermark:hidden {
156163
transition: visibility 0s 2s, opacity 2s linear;
157164
}
158165

159166
body {
160-
display: block;
167+
display: block;
161168
margin: 0 auto;
162-
background-color:#1167b1;
169+
background-color: #1167b1;
163170
opacity: 1;
164-
transition: .5s ease-in-out;
171+
transition: 0.5s ease-in-out;
165172
}
166173

167174
fieldset{
@@ -173,7 +180,3 @@ fieldset{
173180
margin: 0 auto;
174181
z-index: -1;
175182
}
176-
177-
178-
179-

‎include/BLE_Common.h

+1-4
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,8 @@ extern bool updateConnParametersFlag;
3434

3535
void startBLEServer();
3636
void computeERG(int, int);
37-
void computeCSC();
3837
void updateIndoorBikeDataChar();
39-
void updateCyclingPowerMesurementChar();
38+
void updateCyclingPowerMeasurementChar();
4039
void calculateInstPwrFromHR();
4140
void updateHeartRateMeasurementChar();
4241
int connectedClientCount();
@@ -96,8 +95,6 @@ class SpinBLEAdvertisedDevice {
9695
userSelectedCT = false; // Controllable Trainer
9796
doConnect = false; // Initiate connection flag
9897
}
99-
100-
void print();
10198
};
10299

103100
class SpinBLEClient {

‎include/HTTP_Server_Basic.h

+4
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ void handleHrSlider();
1818
void FirmwareUpdate();
1919

2020
#ifdef USE_TELEGRAM
21+
#define SEND_TO_TELEGRAM(message) sendTelegram(message);
22+
2123
void sendTelegram(String textToSend);
2224
void telegramUpdate(void *pvParameters);
25+
#else
26+
#define SEND_TO_TELEGRAM(message) (void)message
2327
#endif
2428

2529
// wifi Function

‎include/Main.h

-5
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ bool IRAM_ATTR deBounce();
1717
void IRAM_ATTR moveStepper(void* pvParameters);
1818
void IRAM_ATTR shiftUp();
1919
void IRAM_ATTR shiftDown();
20-
void debugDirector(String, bool = true, bool = false);
2120
void resetIfShiftersHeld();
2221
void scanIfShiftersHeld();
2322
void setupTMCStepperDriver();
@@ -30,7 +29,3 @@ extern userParameters userConfig;
3029
// Users Physical Working Capacity Calculation Parameters (heartrate to Power
3130
// calculation)
3231
extern physicalWorkingCapacity userPWC;
33-
34-
// Variable that will store debugging information that will get appended and
35-
// then cleared once posted to HTML or a timer expires.
36-
extern String debugToHTML;

‎include/SS2KLog.h

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright (C) 2020 Anthony Doud & Joel Baranick
3+
* All rights reserved
4+
*
5+
* SPDX-License-Identifier: GPL-2.0-only
6+
*/
7+
8+
#pragma once
9+
10+
#include "sdkconfig.h"
11+
#include "esp_log.h"
12+
#include <stdio.h>
13+
#include <stdarg.h>
14+
#include <SPIFFS.h>
15+
#include <freertos/semphr.h>
16+
17+
#ifndef DEBUG_LOG_BUFFER_SIZE
18+
#define DEBUG_LOG_BUFFER_SIZE 1000
19+
#endif
20+
21+
#ifndef DEBUG_FILE_CHARS_PER_LINE
22+
#define DEBUG_FILE_CHARS_PER_LINE 64
23+
#endif
24+
25+
#ifndef CORE_DEBUG_LEVEL
26+
#define CORE_DEBUG_LEVEL CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL
27+
#endif
28+
29+
#if CORE_DEBUG_LEVEL >= 4
30+
#define SS2K_LOGD(tag, format, ...) SS2K_MODLOG_DFLT(ERROR, "D %lu %s: " #format "\n", millis(), tag, ##__VA_ARGS__)
31+
#else
32+
#define SS2K_LOGD(tag, format, ...) (void)tag
33+
#endif
34+
35+
#if CORE_DEBUG_LEVEL >= 3
36+
#define SS2K_LOGI(tag, format, ...) SS2K_MODLOG_DFLT(ERROR, "I %lu %s: " #format "\n", millis(), tag, ##__VA_ARGS__)
37+
#else
38+
#define SS2K_LOGI(tag, format, ...) (void)tag
39+
#endif
40+
41+
#if CORE_DEBUG_LEVEL >= 2
42+
#define SS2K_LOGW(tag, format, ...) SS2K_MODLOG_DFLT(ERROR, "W %lu %s: " #format "\n", millis(), tag, ##__VA_ARGS__)
43+
#else
44+
#define SS2K_LOGW(tag, format, ...) (void)tag
45+
#endif
46+
47+
#if CORE_DEBUG_LEVEL >= 1
48+
#define SS2K_LOGE(tag, format, ...) SS2K_MODLOG_DFLT(ERROR, "E %lu %s: " #format "\n", millis(), tag, ##__VA_ARGS__)
49+
#else
50+
#define SS2K_LOGE(tag, format, ...) (void)tag
51+
#endif
52+
53+
#define SS2K_LOGC(tag, format, ...) SS2K_MODLOG_DFLT(CRITICAL, "C %lu %s: " #format "\n", millis(), tag, ##__VA_ARGS__)
54+
#define SS2K_LOG(tag, format, ...) SS2K_MODLOG_DFLT(CRITICAL, "N %lu %s: " #format "\n", millis(), tag, ##__VA_ARGS__)
55+
56+
class DebugInfo {
57+
public:
58+
static void appendLog(const char *format, ...);
59+
60+
static const std::string getAndClearLogs();
61+
62+
private:
63+
static DebugInfo INSTANCE;
64+
#if DEBUG_LOG_BUFFER_SIZE > 0
65+
DebugInfo() : logBufferLength(0), logBufferMutex(xSemaphoreCreateMutex()) { logBuffer[0] = '\0'; }
66+
int logBufferLength;
67+
char logBuffer[DEBUG_LOG_BUFFER_SIZE];
68+
SemaphoreHandle_t logBufferMutex;
69+
void appendLog_internal(const char *format, va_list args);
70+
const std::string getAndClearLogs_internal();
71+
#else
72+
DebugInfo() {}
73+
#endif
74+
};
75+
76+
#if DEBUG_LOG_BUFFER_SIZE > 0
77+
#define SS2K_MODLOG_ESP_LOCAL(level, ml_msg_, ...) \
78+
do { \
79+
if (LOG_LOCAL_LEVEL >= level) { \
80+
esp_log_write(level, "SS2K", ml_msg_, ##__VA_ARGS__); \
81+
DebugInfo::appendLog(ml_msg_, ##__VA_ARGS__); \
82+
} \
83+
} while (0)
84+
#else
85+
#define SS2K_MODLOG_ESP_LOCAL(level, ml_msg_, ...) \
86+
do { \
87+
if (LOG_LOCAL_LEVEL >= level) esp_log_write(level, "SS2K", ml_msg_, ##__VA_ARGS__); \
88+
} while (0)
89+
#endif
90+
91+
#define SS2K_MODLOG_DEBUG(ml_mod_, ml_msg_, ...) SS2K_MODLOG_ESP_LOCAL(ESP_LOG_DEBUG, ml_msg_, ##__VA_ARGS__)
92+
93+
#define SS2K_MODLOG_INFO(ml_mod_, ml_msg_, ...) SS2K_MODLOG_ESP_LOCAL(ESP_LOG_INFO, ml_msg_, ##__VA_ARGS__)
94+
95+
#define SS2K_MODLOG_WARN(ml_mod_, ml_msg_, ...) SS2K_MODLOG_ESP_LOCAL(ESP_LOG_WARN, ml_msg_, ##__VA_ARGS__)
96+
97+
#define SS2K_MODLOG_ERROR(ml_mod_, ml_msg_, ...) SS2K_MODLOG_ESP_LOCAL(ESP_LOG_ERROR, ml_msg_, ##__VA_ARGS__)
98+
99+
#define SS2K_MODLOG_CRITICAL(ml_mod_, ml_msg_, ...) SS2K_MODLOG_ESP_LOCAL(ESP_LOG_ERROR, ml_msg_, ##__VA_ARGS__)
100+
101+
#define SS2K_MODLOG(ml_lvl_, ml_mod_, ...) SS2K_MODLOG_##ml_lvl_((ml_mod_), __VA_ARGS__)
102+
103+
#define SS2K_MODLOG_DFLT(ml_lvl_, ...) SS2K_MODLOG(ml_lvl_, LOG_MODULE_DEFAULT, __VA_ARGS__);
104+
105+
void ss2k_remove_newlines(std::string *str);
106+
107+
int ss2k_log_hex_to_buffer(const byte *data, const size_t data_length, char *buffer, const int buffer_offset, const size_t buffer_length);
108+
109+
void ss2k_log_file_internal(const char *tag, File file);
110+
111+
#define SS2K_LOG_FILE(tag, file) \
112+
do { \
113+
ss2k_log_file_internal(tag, file); \
114+
} while (0)

‎include/SmartSpin_parameters.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class userParameters {
8282
void setConnectedPowerMeter(String cpm) { connectedPowerMeter = cpm; }
8383
void setConnectedHeartMonitor(String cHr) { connectedHeartMonitor = cHr; }
8484

85-
String returnJSON();
85+
String returnJSON(bool includeDebugLog = false);
8686
void saveToSPIFFS();
8787
void loadFromSPIFFS();
8888
void printFile();

‎include/settings.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
#pragma once
99

10+
#include "SS2KLog.h"
11+
1012
// Update firmware on boot?
1113
#define AUTO_FIRMWARE_UPDATE true
1214

@@ -116,7 +118,7 @@
116118
#define WIFI_CONNECT_TIMEOUT 10
117119

118120
// Max size of userconfig
119-
#define USERCONFIG_JSON_SIZE 768
121+
#define USERCONFIG_JSON_SIZE 768 + DEBUG_LOG_BUFFER_SIZE
120122

121123
// Uncomment to enable sending Telegram debug messages back to the chat
122124
// specified in telegram_token.h

‎lib/SS2K/include/sensors/CyclePowerData.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
class CyclePowerData : public SensorData {
1313
public:
14-
CyclePowerData() : SensorData("CPS"), power() {}
14+
CyclePowerData() : SensorData("CPS") {}
1515

1616
bool hasHeartRate();
1717
bool hasCadence();

‎lib/SS2K/include/sensors/FitnessMachineIndoorBikeData.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
class FitnessMachineIndoorBikeData : public SensorData {
1313
public:
14-
FitnessMachineIndoorBikeData() : SensorData("FTMS") {
14+
FitnessMachineIndoorBikeData() : SensorData("FTMS(IBD)") {
1515
for (int i = 0; i < FieldCount; i++) {
1616
this->values[i] = nan("");
1717
}

‎lib/SS2K/include/sensors/HeartRateData.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
class HeartRateData : public SensorData {
1313
public:
14-
HeartRateData() : SensorData("HRM") {}
14+
HeartRateData() : SensorData("HRS(HRM)") {}
1515

1616
bool hasHeartRate();
1717
bool hasCadence();

‎lib/SS2K/include/sensors/SensorDataFactory.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,19 @@ class SensorDataFactory {
1616
public:
1717
SensorDataFactory() {}
1818

19-
std::shared_ptr<SensorData> getSensorData(NimBLEUUID characteristicUUID, uint8_t *data, size_t length);
19+
std::shared_ptr<SensorData> getSensorData(NimBLEUUID characteristicUUID, const uint64_t peerAddress, uint8_t *data, size_t length);
2020

2121
private:
2222
class KnownDevice {
2323
public:
24-
KnownDevice(NimBLEUUID uuid, std::shared_ptr<SensorData> sensorData) : uuid(uuid), sensorData(sensorData) {}
25-
NimBLEUUID getUUID();
24+
KnownDevice(const NimBLEUUID characteristicUUID, const uint64_t peerAddress, std::shared_ptr<SensorData> sensorData)
25+
: characteristicId(characteristicUUID), peerAddress(peerAddress), sensorData(sensorData) {}
2626
std::shared_ptr<SensorData> decode(uint8_t *data, size_t length);
27+
bool isSameDeviceCharacteristic(const NimBLEUUID characteristicUUID, const uint64_t peerAddress);
2728

2829
private:
29-
NimBLEUUID uuid;
30+
NimBLEUUID characteristicId;
31+
uint64_t peerAddress;
3032
std::shared_ptr<SensorData> sensorData;
3133
};
3234

‎lib/SS2K/src/sensors/FitnessMachineIndoorBikeData.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ void FitnessMachineIndoorBikeData::decode(uint8_t *data, size_t length) {
7676
continue;
7777
}
7878
}
79-
values[typeIndex] = NAN;
79+
values[typeIndex] = nanf("");
8080
}
8181
}
8282

‎lib/SS2K/src/sensors/SensorDataFactory.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
#include "sensors/HeartRateData.h"
1515
#include "sensors/EchelonData.h"
1616

17-
std::shared_ptr<SensorData> SensorDataFactory::getSensorData(const NimBLEUUID characteristicUUID, uint8_t *data, size_t length) {
17+
std::shared_ptr<SensorData> SensorDataFactory::getSensorData(const NimBLEUUID characteristicUUID, const uint64_t peerAddress, uint8_t *data, size_t length) {
1818
for (auto &it : SensorDataFactory::knownDevices) {
19-
if (it->getUUID() == characteristicUUID) {
19+
if (it->isSameDeviceCharacteristic(characteristicUUID, peerAddress)) {
2020
return it->decode(data, length);
2121
}
2222
}
@@ -36,18 +36,20 @@ std::shared_ptr<SensorData> SensorDataFactory::getSensorData(const NimBLEUUID ch
3636
return NULL_SENSOR_DATA;
3737
}
3838

39-
KnownDevice *knownDevice = new KnownDevice(characteristicUUID, sensorData);
39+
KnownDevice *knownDevice = new KnownDevice(characteristicUUID, peerAddress, sensorData);
4040
SensorDataFactory::knownDevices.push_back(knownDevice);
4141
return knownDevice->decode(data, length);
4242
}
4343

44-
NimBLEUUID SensorDataFactory::KnownDevice::getUUID() { return this->uuid; }
45-
4644
std::shared_ptr<SensorData> SensorDataFactory::KnownDevice::decode(uint8_t *data, size_t length) {
4745
this->sensorData->decode(data, length);
4846
return this->sensorData;
4947
}
5048

49+
bool SensorDataFactory::KnownDevice::isSameDeviceCharacteristic(const NimBLEUUID characteristicUUID, const uint64_t peerAddress) {
50+
return this->characteristicId == characteristicUUID && this->peerAddress == peerAddress;
51+
}
52+
5153
bool SensorDataFactory::NullData::hasHeartRate() { return false; }
5254

5355
bool SensorDataFactory::NullData::hasCadence() { return false; }

‎platformio.ini

+26-20
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,9 @@
88
; Please visit documentation for the other options and examples
99
; https://docs.platformio.org/page/projectconf.html
1010
[platformio]
11-
default_envs = esp32doit
11+
default_envs = debug
1212

13-
[common_env_data]
14-
lib_deps =
15-
;https://github.com/h2zero/NimBLE-Arduino.git#master //Nimble is tracked and including this will probably cause issues.
16-
teemuatlut/TMCStepper@^0.7.1
17-
bblanchon/ArduinoJson@^6.17.2
18-
https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/archive/V1.3.0.zip
19-
20-
[env:esp32doit]
21-
build_flags =
22-
!python git_tag_macro.py
13+
[esp32doit]
2314
lib_ldf_mode = chain+
2415
lib_compat_mode = strict
2516
platform = espressif32
@@ -29,17 +20,32 @@ platform_packages = framework-arduinoespressif32@https://github.com/espressif/ar
2920
board_build.partitions = min_spiffs.csv
3021
upload_speed = 921600
3122
monitor_speed = 512000
32-
debug_init_break = tbreak setup
23+
build_flags =
24+
!python git_tag_macro.py
25+
!python build_date_macro.py
26+
-DCONFIG_BT_NIMBLE_MAX_CONNECTIONS=6
3327
lib_deps =
34-
${common_env_data.lib_deps}
35-
lib/SS2K
28+
;https://github.com/h2zero/NimBLE-Arduino.git#master //Nimble is tracked and including this will probably cause issues.
29+
teemuatlut/TMCStepper@^0.7.1
30+
bblanchon/ArduinoJson@^6.17.2
31+
https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/archive/V1.3.0.zip
32+
33+
[env:release]
34+
extends = esp32doit
35+
36+
[env:debug]
37+
extends = esp32doit
38+
build_type = debug
39+
build_flags = ${esp32doit.build_flags} -D__DEBUG__=1
40+
debug_tool = esp-prog
41+
debug_init_break = tbreak setup
3642
check_tool = cppcheck
37-
check_flags =
38-
--enable=all
39-
--suppress=*:*/.pio/*
40-
--suppress=*:*/lib/NimBLE-Arduino/*
41-
--suppress=unmatchedSuppression
42-
--suppress=missingIncludeSystem
43+
check_flags =
44+
--enable=all
45+
--suppress=*:*/.pio/*
46+
--suppress=*:*/lib/NimBLE-Arduino/*
47+
--suppress=unmatchedSuppression
48+
--suppress=missingIncludeSystem
4349
check_severity = medium, high
4450
check_skip_packages = true
4551

‎src/BLE_Client.cpp

+68-81
Large diffs are not rendered by default.

‎src/BLE_Common.cpp

+27-19
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include "Main.h"
9+
#include "SS2KLog.h"
910
#include "BLE_Common.h"
1011

1112
#include <math.h>
@@ -23,7 +24,12 @@ void BLECommunications(void *pvParameters) {
2324
// **********************************Client***************************************
2425
for (size_t x = 0; x < NUM_BLE_DEVICES; x++) { // loop through discovered devices
2526
if (spinBLEClient.myBLEDevices[x].connectedClientID != BLE_HS_CONN_HANDLE_NONE) {
26-
// spinBLEClient.myBLEDevices[x].print();
27+
SS2K_LOGD("BLE_Client", "Address: (%s) Client ID: (%d) SerUUID: (%s) CharUUID: (%s) HRM: (%s) PM: (%s) CSC: (%s) CT: (%s) doConnect: (%s)",
28+
spinBLEClient.myBLEDevices[x].peerAddress.toString().c_str(), spinBLEClient.myBLEDevices[x].connectedClientID,
29+
spinBLEClient.myBLEDevices[x].serviceUUID.toString().c_str(), spinBLEClient.myBLEDevices[x].charUUID.toString().c_str(),
30+
spinBLEClient.myBLEDevices[x].userSelectedHR ? "true" : "false", spinBLEClient.myBLEDevices[x].userSelectedPM ? "true" : "false",
31+
spinBLEClient.myBLEDevices[x].userSelectedCSC ? "true" : "false", spinBLEClient.myBLEDevices[x].userSelectedCT ? "true" : "false",
32+
spinBLEClient.myBLEDevices[x].doConnect ? "true" : "false");
2733
if (spinBLEClient.myBLEDevices[x].advertisedDevice) { // is device registered?
2834
// debugDirector("1",false);
2935
SpinBLEAdvertisedDevice myAdvertisedDevice = spinBLEClient.myBLEDevices[x];
@@ -44,47 +50,50 @@ void BLECommunications(void *pvParameters) {
4450

4551
// 250 == Data(60), Spaces(Data/2), Arrow(4), SvrUUID(37), Sep(3), ChrUUID(37), Sep(3),
4652
// Name(10), Prefix(2), HR(8), SEP(1), CD(10), SEP(1), PW(8), SEP(1), SP(7), Suffix(2), Nul(1) - 225 rounded up
47-
char logBuf[250];
48-
char *logBufP = logBuf;
49-
for (int i = 0; i < length; i++) {
50-
logBufP += sprintf(logBufP, "%02x ", pData[i]);
51-
}
52-
logBufP += sprintf(logBufP, "<- %.8s | %.8s", myAdvertisedDevice.serviceUUID.toString().c_str(), myAdvertisedDevice.charUUID.toString().c_str());
53+
const int kLogBufMaxLength = 250;
54+
char logBuf[kLogBufMaxLength];
55+
SS2K_LOG("BLE_Common", "Data length: %d", data.length());
56+
int logBufLength = ss2k_log_hex_to_buffer(pData, length, logBuf, 0, kLogBufMaxLength);
57+
58+
logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, "<- %.8s | %.8s", myAdvertisedDevice.serviceUUID.toString().c_str(),
59+
myAdvertisedDevice.charUUID.toString().c_str());
5360

54-
std::shared_ptr<SensorData> sensorData = sensorDataFactory.getSensorData(pRemoteBLECharacteristic->getUUID(), pData, length);
61+
std::shared_ptr<SensorData> sensorData = sensorDataFactory.getSensorData(
62+
pRemoteBLECharacteristic->getUUID(), (uint64_t)pRemoteBLECharacteristic->getRemoteService()->getClient()->getPeerAddress(), pData, length);
5563

56-
logBufP += sprintf(logBufP, " | %s:[", sensorData->getId().c_str());
64+
logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " | %s[", sensorData->getId().c_str());
5765
if (sensorData->hasHeartRate() && !userConfig.getSimulateHr()) {
5866
int heartRate = sensorData->getHeartRate();
5967
userConfig.setSimulatedHr(heartRate);
6068
spinBLEClient.connectedHR |= true;
61-
logBufP += sprintf(logBufP, " HR(%d)", heartRate % 1000);
69+
logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " HR(%d)", heartRate % 1000);
6270
}
6371
if (sensorData->hasCadence() && !userConfig.getSimulateCad()) {
6472
float cadence = sensorData->getCadence();
6573
userConfig.setSimulatedCad(cadence);
6674
spinBLEClient.connectedCD |= true;
67-
logBufP += sprintf(logBufP, " CD(%.2f)", fmodf(cadence, 1000.0));
75+
logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " CD(%.2f)", fmodf(cadence, 1000.0));
6876
}
6977
if (sensorData->hasPower() && !userConfig.getSimulateWatts()) {
7078
int power = sensorData->getPower() * userConfig.getPowerCorrectionFactor();
7179
userConfig.setSimulatedWatts(power);
7280
spinBLEClient.connectedPM |= true;
73-
logBufP += sprintf(logBufP, " PW(%d)", power % 10000);
81+
logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " PW(%d)", power % 10000);
7482
}
7583
if (sensorData->hasSpeed()) {
7684
float speed = sensorData->getSpeed();
7785
userConfig.setSimulatedSpeed(speed);
78-
logBufP += sprintf(logBufP, " SD(%.2f)", fmodf(speed, 1000.0));
86+
logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " SD(%.2f)", fmodf(speed, 1000.0));
7987
}
80-
strcat(logBufP, " ]");
81-
debugDirector(String(logBuf), true, true);
88+
strncat(logBuf + logBufLength, " ]", kLogBufMaxLength - logBufLength);
89+
SS2K_LOG("BLE_Common", "%s", logBuf);
90+
SEND_TO_TELEGRAM(String(logBuf));
8291
} else if (!pClient->isConnected()) { // This shouldn't ever be
8392
// called...
8493
if (pClient->disconnect() == 0) { // 0 is a successful disconnect
8594
BLEDevice::deleteClient(pClient);
8695
vTaskDelay(100 / portTICK_PERIOD_MS);
87-
debugDirector("Workaround connect");
96+
SS2K_LOG("BLE_Common", "Workaround connect");
8897
myAdvertisedDevice.doConnect = true;
8998
}
9099
}
@@ -116,9 +125,8 @@ void BLECommunications(void *pvParameters) {
116125

117126
if (connectedClientCount() > 0) {
118127
// update the BLE information on the server
119-
computeCSC();
120128
updateIndoorBikeDataChar();
121-
updateCyclingPowerMesurementChar();
129+
updateCyclingPowerMeasurementChar();
122130
updateHeartRateMeasurementChar();
123131

124132
if (updateConnParametersFlag) {
@@ -135,7 +143,7 @@ void BLECommunications(void *pvParameters) {
135143
}
136144
if (BLEDevice::getAdvertising()) {
137145
if (!(BLEDevice::getAdvertising()->isAdvertising()) && (BLEDevice::getServer()->getConnectedCount() < CONFIG_BT_NIMBLE_MAX_CONNECTIONS - NUM_BLE_DEVICES)) {
138-
debugDirector("Starting Advertising From Communication Loop");
146+
SS2K_LOG("BLE_Common", "Starting Advertising From Communication Loop");
139147
BLEDevice::startAdvertising();
140148
}
141149
}

‎src/BLE_Server.cpp

+86-71
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include "Main.h"
9+
#include "SS2KLog.h"
910
#include "BLE_Common.h"
1011

1112
#include <ArduinoJson.h>
@@ -21,8 +22,7 @@ BLECharacteristic *cyclingPowerMeasurementCharacteristic;
2122
BLECharacteristic *fitnessMachineFeature;
2223
BLECharacteristic *fitnessMachineIndoorBikeData;
2324

24-
/********************************Bit field Flag
25-
* Example***********************************/
25+
/******** Bit field Flag Example ********/
2626
// 00000000000000000001 - 1 - 0x001 - Pedal Power Balance Present
2727
// 00000000000000000010 - 2 - 0x002 - Pedal Power Balance Reference
2828
// 00000000000000000100 - 4 - 0x004 - Accumulated Torque Present
@@ -63,7 +63,7 @@ uint8_t ftmsPowerRange[6] = {0x00, 0x00, 0xA0, 0x0F, 0x01, 0x00};
6363

6464
void startBLEServer() {
6565
// Server Setup
66-
debugDirector("Starting BLE Server");
66+
SS2K_LOG("BLE_Server", "Starting BLE Server");
6767
pServer = BLEDevice::createServer();
6868

6969
// HEART RATE MONITOR SERVICE SETUP
@@ -130,7 +130,7 @@ void startBLEServer() {
130130
pAdvertising->setScanResponse(true);
131131
BLEDevice::startAdvertising();
132132

133-
debugDirector("Bluetooth Characteristic defined!");
133+
SS2K_LOG("BLE_Server", "Bluetooth Characteristic defined!");
134134
}
135135

136136
void computeERG(int currentWatts, int setPoint) {
@@ -166,25 +166,6 @@ void computeERG(int currentWatts, int setPoint) {
166166
userConfig.setIncline(newIncline);
167167
}
168168

169-
void computeCSC() { // What was SIG smoking when they came up with the Cycling
170-
// Speed and Cadence Characteristic?
171-
if (userConfig.getSimulatedCad() > 0) {
172-
float crankRevPeriod = (60 * 1024) / userConfig.getSimulatedCad();
173-
spinBLEClient.cscCumulativeCrankRev++;
174-
spinBLEClient.cscLastCrankEvtTime += crankRevPeriod;
175-
int remainder, quotient;
176-
quotient = spinBLEClient.cscCumulativeCrankRev / 256;
177-
remainder = spinBLEClient.cscCumulativeCrankRev % 256;
178-
cyclingPowerMeasurement[5] = remainder;
179-
cyclingPowerMeasurement[6] = quotient;
180-
quotient = spinBLEClient.cscLastCrankEvtTime / 256;
181-
remainder = spinBLEClient.cscLastCrankEvtTime % 256;
182-
cyclingPowerMeasurement[7] = remainder;
183-
cyclingPowerMeasurement[8] = quotient;
184-
} // ^^Using the old way of setting bytes because I like it and it makes
185-
// more sense to me looking at it.
186-
}
187-
188169
void updateIndoorBikeDataChar() {
189170
float cadRaw = userConfig.getSimulatedCad();
190171
int cad = static_cast<int>(cadRaw * 2);
@@ -208,106 +189,141 @@ void updateIndoorBikeDataChar() {
208189
ftmsIndoorBikeData[7] = (uint8_t)(watts >> 8); // power value, constrained to avoid negative values,
209190
// although the specification allows for a sint16
210191
ftmsIndoorBikeData[8] = (uint8_t)hr;
192+
193+
// 200 == Data(30), Sep(data/2), Arrow(3), CharId(37), Sep(3), CharId(37), Sep(3), Name(10), Prefix(2), HR(7), SEP(1), CD(10), SEP(1), PW(8), SEP(1), SD(7), Suffix(2), Nul(1) ==
194+
// 178, rounded up
195+
const int kLogBufMaxLength = 200;
196+
char logBuf[kLogBufMaxLength];
197+
int logBufLength = ss2k_log_hex_to_buffer(ftmsIndoorBikeData, *(&ftmsIndoorBikeData + 1) - ftmsIndoorBikeData, logBuf, 0, kLogBufMaxLength);
198+
logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, "-> %s | %s | FTMS(IBD)[", FITNESSMACHINESERVICE_UUID.toString().c_str(),
199+
fitnessMachineIndoorBikeData->getUUID().toString().c_str());
200+
logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " HR(%d)", hr % 1000);
201+
logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " CD(%.2f)", fmodf(cadRaw, 1000.0));
202+
logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " PW(%d)", watts % 10000);
203+
logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " SD(%.2f)", fmodf(speed, 1000.0));
204+
strncat(logBuf + logBufLength, " ]", kLogBufMaxLength - logBufLength);
205+
211206
fitnessMachineIndoorBikeData->setValue(ftmsIndoorBikeData, 9);
212207
fitnessMachineFeature->notify();
213208
fitnessMachineIndoorBikeData->notify();
209+
210+
SS2K_LOG("BLE_Server", "%s", logBuf);
214211
} // ^^Using the New Way of setting Bytes.
215212

216-
void updateCyclingPowerMesurementChar() {
213+
void updateCyclingPowerMeasurementChar() {
214+
int power = userConfig.getSimulatedWatts();
217215
int remainder, quotient;
218-
quotient = userConfig.getSimulatedWatts() / 256;
219-
remainder = userConfig.getSimulatedWatts() % 256;
216+
quotient = power / 256;
217+
remainder = power % 256;
220218
cyclingPowerMeasurement[2] = remainder;
221219
cyclingPowerMeasurement[3] = quotient;
222220
cyclingPowerMeasurementCharacteristic->setValue(cyclingPowerMeasurement, 9);
223221

224-
// Data(18), Sep(data/2), Static(13), Nul(1) == 41, rounded up
225-
char logBuf[50];
226-
char *logBufP = logBuf;
227-
for (const auto &it : cyclingPowerMeasurement) {
228-
logBufP += sprintf(logBufP, "%02x ", it);
222+
float cadence = userConfig.getSimulatedCad();
223+
if (cadence > 0) {
224+
float crankRevPeriod = (60 * 1024) / cadence;
225+
spinBLEClient.cscCumulativeCrankRev++;
226+
spinBLEClient.cscLastCrankEvtTime += crankRevPeriod;
227+
int remainder, quotient;
228+
quotient = spinBLEClient.cscCumulativeCrankRev / 256;
229+
remainder = spinBLEClient.cscCumulativeCrankRev % 256;
230+
cyclingPowerMeasurement[5] = remainder;
231+
cyclingPowerMeasurement[6] = quotient;
232+
quotient = spinBLEClient.cscLastCrankEvtTime / 256;
233+
remainder = spinBLEClient.cscLastCrankEvtTime % 256;
234+
cyclingPowerMeasurement[7] = remainder;
235+
cyclingPowerMeasurement[8] = quotient;
236+
} // ^^Using the old way of setting bytes because I like it and it makes more sense to me looking at it.
237+
238+
// 150 == Data(18), Sep(data/2), Arrow(3), CharId(37), Sep(3), CharId(37), Sep(3),Name(8), Prefix(2), CD(10), SEP(1), PW(8), Suffix(2), Nul(1) == 142, rounded up
239+
const int kLogBufMaxLength = 150;
240+
char logBuf[kLogBufMaxLength];
241+
int logBufLength = ss2k_log_hex_to_buffer(cyclingPowerMeasurement, *(&cyclingPowerMeasurement + 1) - cyclingPowerMeasurement, logBuf, 0, kLogBufMaxLength);
242+
logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, "-> %s | %s | CPS(CPM)[ ", CYCLINGPOWERSERVICE_UUID.toString().c_str(),
243+
cyclingPowerMeasurementCharacteristic->getUUID().toString().c_str());
244+
245+
if (cadence > 0) {
246+
logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, "CD(%.2f) ", fmodf(cadence, 1000.0));
229247
}
230-
strcat(logBufP, "<-- CPMC sent");
248+
logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, "PW(%d) ", power % 10000);
249+
strncat(logBuf + logBufLength, "]", kLogBufMaxLength - logBufLength);
231250

232251
cyclingPowerMeasurementCharacteristic->notify();
233-
debugDirector(String(logBuf), true);
252+
SS2K_LOG("BLE_Server", "%s", logBuf);
234253
}
235254

236255
void updateHeartRateMeasurementChar() {
237-
heartRateMeasurement[1] = userConfig.getSimulatedHr();
256+
int hr = userConfig.getSimulatedHr();
257+
heartRateMeasurement[1] = hr;
238258
heartRateMeasurementCharacteristic->setValue(heartRateMeasurement, 2);
239259

240-
// Data(10), Sep(data/2), Static(11), Nul(1) == 26, rounded up
241-
char logBuf[35];
242-
char *logBufP = logBuf;
243-
for (const auto &it : heartRateMeasurement) {
244-
logBufP += sprintf(logBufP, "%02x ", it);
245-
}
246-
strcat(logBufP, "<-- HR sent");
260+
// 125 == Data(10), Sep(data/2), Arrow(3), CharId(37), Sep(3), CharId(37), Sep(3), Name(8), Prefix(2), HR(7), Suffix(2), Nul(1) == 118, rounded up
261+
const int kLogBufMaxLength = 125;
262+
char logBuf[kLogBufMaxLength];
263+
int logBufLength = ss2k_log_hex_to_buffer(heartRateMeasurement, *(&heartRateMeasurement + 1) - heartRateMeasurement, logBuf, 0, kLogBufMaxLength);
264+
snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, "-> %s | %s | HRS(HRM)[ HR(%d) ]", HEARTSERVICE_UUID.toString().c_str(),
265+
heartRateMeasurementCharacteristic->getUUID().toString().c_str(), hr % 1000);
247266

248267
heartRateMeasurementCharacteristic->notify();
249-
debugDirector(String(logBuf), true);
268+
SS2K_LOG("BLE_Server", "%s", logBuf);
250269
}
251270

252271
// Creating Server Connection Callbacks
253272

254273
void MyServerCallbacks::onConnect(BLEServer *pServer, ble_gap_conn_desc *desc) {
255-
debugDirector("Bluetooth Remote Client Connected: " + String(NimBLEAddress(desc->peer_ota_addr).toString().c_str()) +
256-
" Connected Clients: " + String(pServer->getConnectedCount()));
274+
SS2K_LOG("BLE_Server", "Bluetooth Remote Client Connected: %s Connected Clients: %d", NimBLEAddress(desc->peer_ota_addr).toString().c_str(), pServer->getConnectedCount());
257275
updateConnParametersFlag = true;
258276
bleConnDesc = desc->conn_handle;
259277

260278
if (pServer->getConnectedCount() < CONFIG_BT_NIMBLE_MAX_CONNECTIONS - NUM_BLE_DEVICES) {
261279
BLEDevice::startAdvertising();
262280
} else {
263-
debugDirector("Max Remote Client Connections Reached");
281+
SS2K_LOG("BLE_Server", "Max Remote Client Connections Reached");
264282
BLEDevice::stopAdvertising();
265283
}
266284
}
267285

268286
void MyServerCallbacks::onDisconnect(BLEServer *pServer) {
269-
debugDirector("Bluetooth Remote Client Disconnected. Remaining Clients: " + String(pServer->getConnectedCount()));
287+
SS2K_LOG("BLE_Server", "Bluetooth Remote Client Disconnected. Remaining Clients: %d", pServer->getConnectedCount());
270288
BLEDevice::startAdvertising();
271289
}
272290

273291
void MyCallbacks::onWrite(BLECharacteristic *pCharacteristic) {
274292
std::string rxValue = pCharacteristic->getValue();
275293

276294
if (rxValue.length() > 1) {
277-
for (const auto &text : rxValue) { // Range-for!
278-
debugDirector(String(text, HEX) + " ", false);
279-
}
280-
debugDirector("<-- From APP ", false);
281-
/* 0x11 17 means FTMS Incline Control Mode (aka SIM mode)*/
282-
283-
if (static_cast<int>(rxValue[0]) == 17) {
295+
// 175 == Data(16), Spaces(Data/2), Arrow(3), ChrUUID(37), Sep(3), ChrUUID(37), Sep(3),
296+
// Name(8), Prefix(2), TGT(9), SEP(1), CUR(9), SEP(1), INC(11), Suffix(2), Nul(1) - 151 rounded up
297+
const int kLogBufMaxLength = 175;
298+
char logBuf[kLogBufMaxLength];
299+
int logBufLength = ss2k_log_hex_to_buffer(reinterpret_cast<const unsigned char *>(rxValue.c_str()), rxValue.length(), logBuf, 0, kLogBufMaxLength);
300+
logBufLength += snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, "<- %s | %s ", FITNESSMACHINESERVICE_UUID.toString().c_str(),
301+
pCharacteristic->getUUID().toString().c_str());
302+
303+
if (static_cast<int>(rxValue[0]) == 17) { // 0x11 17 means FTMS Incline Control Mode (aka SIM mode)
284304
signed char buf[2];
285305
buf[0] = rxValue[3]; // (Least significant byte)
286306
buf[1] = rxValue[4]; // (Most significant byte)
287307

288-
int port = bytes_to_u16(buf[1], buf[0]);
289-
userConfig.setIncline(port);
308+
int targetIncline = bytes_to_u16(buf[1], buf[0]);
309+
userConfig.setIncline(targetIncline);
290310
if (userConfig.getERGMode()) {
291311
userConfig.setERGMode(false);
292312
}
293-
debugDirector(" Target Incline: " + String((userConfig.getIncline() / 100)), false);
313+
snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " | FTMS(CP)[ INC(%.2f) ]", fmodf(targetIncline / 100, 1000.0));
314+
SS2K_LOG("BLE_Server", "%s", logBuf);
315+
SEND_TO_TELEGRAM(String(logBuf));
294316
}
295-
debugDirector("");
296-
297-
/* 0x05 5 means FTMS Watts Control Mode (aka ERG mode) */
298-
if ((static_cast<int>(rxValue[0]) == 5) && (spinBLEClient.connectedPM)) {
317+
if ((static_cast<int>(rxValue[0]) == 5) && (spinBLEClient.connectedPM)) { // 0x05 5 means FTMS Watts Control Mode (aka ERG mode)
299318
int targetWatts = bytes_to_u16(rxValue[2], rxValue[1]);
300319
if (!userConfig.getERGMode()) {
301320
userConfig.setERGMode(true);
302321
}
303322
computeERG(userConfig.getSimulatedWatts(), targetWatts);
304-
debugDirector("ERG MODE", false);
305-
debugDirector(" Target: " + String(targetWatts), false);
306-
debugDirector(" Current: " + String(userConfig.getSimulatedWatts()),
307-
false); // not displaying numbers less than 256 correctly
308-
// but they do get sent to Zwift correctly.
309-
debugDirector(" Incline: " + String(userConfig.getIncline() / 100), false);
310-
debugDirector("");
323+
snprintf(logBuf + logBufLength, kLogBufMaxLength - logBufLength, " | FTMS(CP)[ TGT(%d) CUR(%d) INC(%.2f) ]", targetWatts % 10000, userConfig.getSimulatedWatts() % 10000,
324+
fmodf(userConfig.getIncline() / 100, 1000.0));
325+
SS2K_LOG("BLE_Server", "%s", logBuf);
326+
SEND_TO_TELEGRAM(String(logBuf));
311327
}
312328
}
313329
}
@@ -325,9 +341,8 @@ void calculateInstPwrFromHR() {
325341
static int oldHR = userConfig.getSimulatedHr();
326342
static int newHR = userConfig.getSimulatedHr();
327343
static double delta = 0;
328-
329-
oldHR = newHR; // Copying HR from Last loop
330-
newHR = userConfig.getSimulatedHr();
344+
oldHR = newHR; // Copying HR from Last loop
345+
newHR = userConfig.getSimulatedHr();
331346

332347
delta = (newHR - oldHR) / (BLE_CLIENT_DELAY / 1000);
333348

@@ -352,5 +367,5 @@ void calculateInstPwrFromHR() {
352367
userConfig.setSimulatedCad(90);
353368
#endif
354369

355-
debugDirector("Power From HR: " + String(avgP));
370+
SS2K_LOG("BLE_Server", "Power From HR: %d", avgP);
356371
}

‎src/BLE_Setup.cpp

+7-6
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77

88
#include "BLE_Common.h"
99
#include "Main.h"
10+
#include "SS2KLog.h"
1011
#include <ArduinoJson.h>
1112
#include <NimBLEDevice.h>
1213

1314
void setupBLE() { // Common BLE setup for both client and server
14-
debugDirector("Starting Arduino BLE Client application...");
15+
SS2K_LOG("BLE_Setup", "Starting Arduino BLE Client application...");
1516
BLEDevice::init(userConfig.getDeviceName());
1617
spinBLEClient.start();
1718
startBLEServer();
@@ -24,12 +25,12 @@ void setupBLE() { // Common BLE setup for both client and server
2425
&BLECommunicationTask, /* Task handle to keep track of created task */
2526
1); /* pin task to core 0 */
2627

27-
debugDirector("BLE Notify Task Started");
28+
SS2K_LOG("BLE_Setup", "BLE Notify Task Started");
2829
vTaskDelay(100 / portTICK_PERIOD_MS);
29-
if (!((String(userConfig.getconnectedPowerMeter()) == "none") && (String(userConfig.getconnectedHeartMonitor()) == "none"))) {
30+
if (strcmp(userConfig.getconnectedPowerMeter(), "none") != 0 || strcmp(userConfig.getconnectedHeartMonitor(), "none") != 0) {
3031
spinBLEClient.serverScan(true);
31-
debugDirector("Scanning");
32+
SS2K_LOG("BLE_Setup", "Scanning");
3233
}
33-
debugDirector(String(userConfig.getconnectedPowerMeter()) + " " + String(userConfig.getconnectedHeartMonitor()));
34-
debugDirector("End BLE Setup");
34+
SS2K_LOG("BLE_Setup", "%s %s", userConfig.getconnectedPowerMeter(), userConfig.getconnectedHeartMonitor());
35+
SS2K_LOG("BLE_Setup", "End BLE Setup");
3536
}

‎src/HTTP_Server_Basic.cpp

+57-58
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "Builtin_Pages.h"
1111
#include "HTTP_Server_Basic.h"
1212
#include "cert.h"
13+
#include "SS2KLog.h"
1314
#include <WebServer.h>
1415
#include <HTTPClient.h>
1516
#include <HTTPUpdate.h>
@@ -47,7 +48,7 @@ void startWifi() {
4748
int i = 0;
4849

4950
// Trying Station mode first:
50-
debugDirector("Connecting to: " + String(userConfig.getSsid()));
51+
SS2K_LOG("HTTP_Server", "Connecting to: %s", userConfig.getSsid());
5152
if (String(WiFi.SSID()) != userConfig.getSsid()) {
5253
WiFi.mode(WIFI_STA);
5354
WiFi.setTxPower(WIFI_POWER_19_5dBm);
@@ -56,11 +57,11 @@ void startWifi() {
5657

5758
while (WiFi.status() != WL_CONNECTED) {
5859
vTaskDelay(1000 / portTICK_RATE_MS);
59-
debugDirector(".", false);
60+
SS2K_LOG("HTTP_Server", "Waiting for connection to be established...");
6061
i++;
6162
if (i > WIFI_CONNECT_TIMEOUT || (String(userConfig.getSsid()) == DEVICE_NAME)) {
6263
i = 0;
63-
debugDirector("Couldn't Connect. Switching to AP mode");
64+
SS2K_LOG("HTTP_Server", "Couldn't Connect. Switching to AP mode");
6465
WiFi.disconnect();
6566
WiFi.mode(WIFI_AP);
6667
break;
@@ -89,30 +90,32 @@ void startWifi() {
8990
}
9091

9192
if (!MDNS.begin(userConfig.getDeviceName())) {
92-
debugDirector("Error setting up MDNS responder!");
93+
SS2K_LOG("HTTP_Server", "Error setting up MDNS responder!");
9394
}
9495

9596
MDNS.addService("http", "_tcp", 80);
9697
MDNS.addServiceTxt("http", "_tcp", "lf", "0");
97-
debugDirector("Connected to " + String(userConfig.getSsid()) + " IP address: " + myIP.toString(), true, true);
98-
debugDirector(String("Open http://") + userConfig.getDeviceName() + ".local/");
98+
SS2K_LOG("HTTP_Server", "Connected to %s IP address: %s", userConfig.getSsid(), myIP.toString().c_str());
99+
SEND_TO_TELEGRAM("Connected to " + String(userConfig.getSsid()) + " IP address: " + myIP.toString());
100+
SS2K_LOG("HTTP_Server", "Open http://%s.local/", userConfig.getDeviceName());
99101
WiFi.setTxPower(WIFI_POWER_19_5dBm);
100102

101103
if (WiFi.getMode() == WIFI_STA) {
102-
Serial.print("Retrieving time: ");
104+
SS2K_LOG("HTTP_Server", "Syncing clock...");
103105
configTime(0, 0, "pool.ntp.org"); // get UTC time via NTP
104106
time_t now = time(nullptr);
105107
while (now < 10) { // wait 10 seconds
106-
Serial.print(".");
108+
SS2K_LOG("HTTP_Server", "Waiting for clock sync...");
107109
delay(100);
108110
now = time(nullptr);
109111
}
112+
SS2K_LOG("HTTP_Server", "Clock synced to: %.f", difftime(now, (time_t)0));
110113
Serial.println(now);
111114
}
112115
}
113116

114117
void startHttpServer() {
115-
server.onNotFound([]() { debugDirector("Link Not Found: " + server.uri()); });
118+
server.onNotFound([]() { SS2K_LOG("HTTP_Server", "Link Not Found: %s", server.uri().c_str()); });
116119

117120
/********************************************Begin
118121
* Handlers***********************************/
@@ -132,7 +135,7 @@ void startHttpServer() {
132135
server.on("/jquery.js.gz", handleSpiffsFile);
133136

134137
server.on("/BLEScan", []() {
135-
debugDirector("Scanning from web request");
138+
SS2K_LOG("HTTP_Server", "Scanning from web request");
136139
String response =
137140
"<!DOCTYPE html><html><body>Scanning for BLE Devices. Please wait "
138141
"15 seconds.</body><script> setTimeout(\"location.href = 'http://" +
@@ -143,7 +146,7 @@ void startHttpServer() {
143146
});
144147

145148
server.on("/load_defaults.html", []() {
146-
debugDirector("Setting Defaults from Web Request");
149+
SS2K_LOG("HTTP_Server", "Setting Defaults from Web Request");
147150
SPIFFS.format();
148151
userConfig.setDefaults();
149152
userConfig.saveToSPIFFS();
@@ -157,7 +160,7 @@ void startHttpServer() {
157160
});
158161

159162
server.on("/reboot.html", []() {
160-
debugDirector("Rebooting from Web Request");
163+
SS2K_LOG("HTTP_Server", "Rebooting from Web Request");
161164
String response = "Rebooting....<script> setTimeout(\"location.href = 'http://" + myIP.toString() + "/index.html';\",500); </script>";
162165
server.send(200, "text/html", response);
163166
vTaskDelay(100 / portTICK_PERIOD_MS);
@@ -169,14 +172,14 @@ void startHttpServer() {
169172
if (value == "enable") {
170173
userConfig.setSimulateHr(true);
171174
server.send(200, "text/plain", "OK");
172-
debugDirector("HR Simulator turned on");
175+
SS2K_LOG("HTTP_Server", "HR Simulator turned on");
173176
} else if (value == "disable") {
174177
userConfig.setSimulateHr(false);
175178
server.send(200, "text/plain", "OK");
176-
debugDirector("HR Simulator turned off");
179+
SS2K_LOG("HTTP_Server", "HR Simulator turned off");
177180
} else {
178181
userConfig.setSimulatedHr(value.toInt());
179-
debugDirector("HR is now: " + String(userConfig.getSimulatedHr()));
182+
SS2K_LOG("HTTP_Server", "HR is now: %d", userConfig.getSimulatedHr());
180183
server.send(200, "text/plain", "OK");
181184
}
182185
});
@@ -186,14 +189,14 @@ void startHttpServer() {
186189
if (value == "enable") {
187190
userConfig.setSimulateWatts(true);
188191
server.send(200, "text/plain", "OK");
189-
debugDirector("Watt Simulator turned on");
192+
SS2K_LOG("HTTP_Server", "Watt Simulator turned on");
190193
} else if (value == "disable") {
191194
userConfig.setSimulateWatts(false);
192195
server.send(200, "text/plain", "OK");
193-
debugDirector("Watt Simulator turned off");
196+
SS2K_LOG("HTTP_Server", "Watt Simulator turned off");
194197
} else {
195198
userConfig.setSimulatedWatts(value.toInt());
196-
debugDirector("Watts are now: " + String(userConfig.getSimulatedWatts()));
199+
SS2K_LOG("HTTP_Server", "Watts are now: %d", userConfig.getSimulatedWatts());
197200
server.send(200, "text/plain", "OK");
198201
}
199202
});
@@ -203,32 +206,28 @@ void startHttpServer() {
203206
if (value == "enable") {
204207
userConfig.setSimulateCad(true);
205208
server.send(200, "text/plain", "OK");
206-
debugDirector("CAD Simulator turned on");
209+
SS2K_LOG("HTTP_Server", "CAD Simulator turned on");
207210
} else if (value == "disable") {
208211
userConfig.setSimulateCad(false);
209212
server.send(200, "text/plain", "OK");
210-
debugDirector("CAD Simulator turned off");
213+
SS2K_LOG("HTTP_Server", "CAD Simulator turned off");
211214
} else {
212215
userConfig.setSimulatedCad(value.toInt());
213-
debugDirector("CAD is now: " + String(userConfig.getSimulatedCad()));
216+
SS2K_LOG("HTTP_Server", "CAD is now: %f", userConfig.getSimulatedCad());
214217
server.send(200, "text/plain", "OK");
215218
}
216219
});
217220

218221
server.on("/configJSON", []() {
219222
String tString;
220-
tString = userConfig.returnJSON();
221-
tString.remove(tString.length() - 1, 1);
222-
tString += String(",\"debug\":\"") + debugToHTML + "\",\"firmwareVersion\":\"" + String(FIRMWARE_VERSION) + "\"}";
223+
tString = userConfig.returnJSON(!server.arg("includeDebugLog").isEmpty());
223224
server.send(200, "text/plain", tString);
224-
debugToHTML = " ";
225225
});
226226

227227
server.on("/PWCJSON", []() {
228228
String tString;
229229
tString = userPWC.returnJSON();
230230
server.send(200, "text/plain", tString);
231-
debugToHTML = " ";
232231
});
233232

234233
server.on("/login", HTTP_GET, []() {
@@ -253,7 +252,7 @@ void startHttpServer() {
253252
HTTPUpload &upload = server.upload();
254253
if (upload.filename == String("firmware.bin").c_str()) {
255254
if (upload.status == UPLOAD_FILE_START) {
256-
debugDirector("Update: " + upload.filename);
255+
SS2K_LOG("HTTP_Server", "Update: %s", upload.filename.c_str());
257256
if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { // start with max
258257
// available size
259258
Update.printError(Serial);
@@ -279,7 +278,7 @@ void startHttpServer() {
279278
if (!filename.startsWith("/")) {
280279
filename = "/" + filename;
281280
}
282-
debugDirector("handleFileUpload Name: " + filename);
281+
SS2K_LOG("HTTP_Server", "handleFileUpload Name: %s", filename.c_str());
283282
fsUploadFile = SPIFFS.open(filename, "w");
284283
filename = String();
285284
} else if (upload.status == UPLOAD_FILE_WRITE) {
@@ -290,7 +289,7 @@ void startHttpServer() {
290289
if (fsUploadFile) {
291290
fsUploadFile.close();
292291
}
293-
debugDirector(String("handleFileUpload Size: ") + String(upload.totalSize));
292+
SS2K_LOG("HTTP_Server", "handleFileUpload Size: %zu", upload.totalSize);
294293
server.send(200, "text/plain", String(upload.filename + " Uploaded Sucessfully."));
295294
}
296295
}
@@ -299,13 +298,13 @@ void startHttpServer() {
299298
/********************************************End Server
300299
* Handlers*******************************/
301300

302-
xTaskCreatePinnedToCore(webClientUpdate, /* Task function. */
303-
"webClientUpdate", /* name of task. */
304-
4500, /* Stack size of task Used to be 3000*/
305-
NULL, /* parameter of the task */
306-
1, /* priority of the task - 29 worked*/
307-
&webClientTask, /* Task handle to keep track of created task */
308-
1); /* pin task to core 1 */
301+
xTaskCreatePinnedToCore(webClientUpdate, /* Task function. */
302+
"webClientUpdate", /* name of task. */
303+
4500 + (DEBUG_LOG_BUFFER_SIZE * 2), /* Stack size of task Used to be 3000*/
304+
NULL, /* parameter of the task */
305+
1, /* priority of the task - 29 worked*/
306+
&webClientTask, /* Task handle to keep track of created task */
307+
1); /* pin task to core 1 */
309308

310309
#ifdef USE_TELEGRAM
311310
xTaskCreatePinnedToCore(telegramUpdate, /* Task function. */
@@ -316,9 +315,8 @@ void startHttpServer() {
316315
&telegramTask, /* Task handle to keep track of created task */
317316
1); /* pin task to core 1 */
318317
#endif
319-
320318
server.begin();
321-
debugDirector("HTTP server started");
319+
SS2K_LOG("HTTP_Server", "HTTP server started");
322320
}
323321

324322
void webClientUpdate(void *pvParameters) {
@@ -343,8 +341,9 @@ void handleIndexFile() {
343341
File file = SPIFFS.open(filename, FILE_READ);
344342
server.streamFile(file, "text/html");
345343
file.close();
344+
SS2K_LOG("HTTP_Server", "Served %s", filename.c_str());
346345
} else {
347-
debugDirector(filename + " not found. Sending builtin Index.html");
346+
SS2K_LOG("HTTP_Server", "%s not found. Sending builtin Index.html", filename.c_str());
348347
server.send(200, "text/html", noIndexHTML);
349348
}
350349
}
@@ -360,9 +359,9 @@ void handleSpiffsFile() {
360359
}
361360
server.streamFile(file, "text/" + fileType);
362361
file.close();
363-
debugDirector("Served " + filename);
362+
SS2K_LOG("HTTP_Server", "Served %s", filename.c_str());
364363
} else {
365-
debugDirector(filename + " not found. Sending builtin Index.html");
364+
SS2K_LOG("HTTP_Server", "%s not found. Sending 404.", filename.c_str());
366365
server.send(404, "text/html",
367366
"<html><body><h1>ERROR 404 <br> FILE NOT "
368367
"FOUND!</h1></body></html>");
@@ -482,7 +481,7 @@ void settingsProcessor() {
482481
myIP.toString() + "/index.html';\",1000);</script></html>";
483482
}
484483
server.send(200, "text/html", response);
485-
debugDirector("Config Updated From Web");
484+
SS2K_LOG("HTTP_Server", "Config Updated From Web");
486485
userConfig.saveToSPIFFS();
487486
userConfig.printFile();
488487
userPWC.saveToSPIFFS();
@@ -497,7 +496,7 @@ void FirmwareUpdate() {
497496
// WiFiClientSecure client;
498497

499498
client.setCACert(rootCACertificate);
500-
debugDirector("Checking for newer firmware:");
499+
SS2K_LOG("HTTP_Server", "Checking for newer firmware:");
501500
http.begin(userConfig.getFirmwareUpdateURL() + String(FW_VERSIONFILE),
502501
rootCACertificate); // check version URL
503502
delay(100);
@@ -507,10 +506,10 @@ void FirmwareUpdate() {
507506
if (httpCode == HTTP_CODE_OK) { // if version received
508507
payload = http.getString(); // save received version
509508
payload.trim();
510-
debugDirector(" - Server version: " + payload);
509+
SS2K_LOG("HTTP_Server", " - Server version: %s", payload.c_str());
511510
internetConnection = true;
512511
} else {
513-
debugDirector("error downloading " + String(FW_VERSIONFILE) + " " + String(httpCode));
512+
SS2K_LOG("HTTP_Server", "error downloading %s %d", FW_VERSIONFILE, httpCode);
514513
internetConnection = false;
515514
}
516515

@@ -519,54 +518,54 @@ void FirmwareUpdate() {
519518
bool updateAnyway = false;
520519
if (!SPIFFS.exists("/index.html")) {
521520
updateAnyway = true;
522-
debugDirector(" -index.html not found. Forcing update");
521+
SS2K_LOG("HTTP_Server", " -index.html not found. Forcing update");
523522
}
524523
Version availiableVer(payload.c_str());
525524
Version currentVer(FIRMWARE_VERSION);
526525

527526
if ((availiableVer > currentVer) || (updateAnyway)) {
528-
debugDirector("New firmware detected!");
529-
debugDirector("Upgrading from " + String(FIRMWARE_VERSION) + " to " + payload);
527+
SS2K_LOG("HTTP_Server", "New firmware detected!");
528+
SS2K_LOG("HTTP_Server", "Upgrading from %s to %s", FIRMWARE_VERSION, payload.c_str());
530529

531530
// Update Spiffs
532531
httpUpdate.setLedPin(LED_BUILTIN, LOW);
533-
debugDirector("Updating FileSystem");
532+
SS2K_LOG("HTTP_Server", "Updating FileSystem");
534533
t_httpUpdate_return ret = httpUpdate.updateSpiffs(client, userConfig.getFirmwareUpdateURL() + String(FW_SPIFFSFILE));
535534
vTaskDelay(100 / portTICK_PERIOD_MS);
536535
switch (ret) {
537536
case HTTP_UPDATE_OK:
538-
debugDirector("Saving Config.txt");
537+
SS2K_LOG("HTTP_Server", "Saving Config.txt");
539538
userConfig.saveToSPIFFS();
540539
userPWC.saveToSPIFFS();
541-
debugDirector("Updating Program");
540+
SS2K_LOG("HTTP_Server", "Updating Program");
542541
break;
543542

544543
case HTTP_UPDATE_NO_UPDATES:
545-
debugDirector("HTTP_UPDATE_NO_UPDATES");
544+
SS2K_LOG("HTTP_Server", "HTTP_UPDATE_NO_UPDATES");
546545
break;
547546

548547
case HTTP_UPDATE_FAILED:
549-
debugDirector("SPIFFS Update Failed: " + String(httpUpdate.getLastError()) + " : " + httpUpdate.getLastErrorString());
548+
SS2K_LOG("HTTP_Server", "SPIFFS Update Failed: %d : %s", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
550549
break;
551550
}
552551

553552
// Update Firmware
554553
ret = httpUpdate.update(client, userConfig.getFirmwareUpdateURL() + String(FW_BINFILE));
555554
switch (ret) {
556555
case HTTP_UPDATE_FAILED:
557-
debugDirector("HTTP_UPDATE_FAILD Error " + String(httpUpdate.getLastError()) + " : " + httpUpdate.getLastErrorString());
556+
SS2K_LOG("HTTP_Server", "HTTP_UPDATE_FAILD Error %d : %s", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
558557
break;
559558

560559
case HTTP_UPDATE_NO_UPDATES:
561-
debugDirector("HTTP_UPDATE_NO_UPDATES");
560+
SS2K_LOG("HTTP_Server", "HTTP_UPDATE_NO_UPDATES");
562561
break;
563562

564563
case HTTP_UPDATE_OK:
565-
debugDirector("HTTP_UPDATE_OK");
564+
SS2K_LOG("HTTP_Server", "HTTP_UPDATE_OK");
566565
break;
567566
}
568567
} else { // don't update
569-
debugDirector(" - Current Version: " + String(FIRMWARE_VERSION));
568+
SS2K_LOG("HTTP_Server", " - Current Version: %s", FIRMWARE_VERSION);
570569
}
571570
}
572571
}
@@ -601,7 +600,7 @@ void telegramUpdate(void *pvParameters) {
601600
bool rm = (bot.sendMessage(TELEGRAM_CHAT_ID, telegramMessage, ""));
602601
if (!rm) {
603602
telegramFailures++;
604-
debugDirector("Telegram failed to send!", +TELEGRAM_CHAT_ID);
603+
SS2K_LOG("HTTP_Server", "Telegram failed to send! %s", TELEGRAM_CHAT_ID);
605604
if (telegramFailures > 2) {
606605
internetConnection = false;
607606
}

‎src/Main.cpp

+29-42
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,23 @@
66
*/
77

88
#include "Main.h"
9+
#include "SS2KLog.h"
910
#include <TMCStepper.h>
1011
#include <Arduino.h>
1112
#include <SPIFFS.h>
1213
#include <HardwareSerial.h>
1314

14-
String debugToHTML = "<br>Firmware Version " + String(FIRMWARE_VERSION);
15-
bool lastDir = true; // Stepper Last Direction
15+
bool lastDir = true; // Stepper Last Direction
1616

1717
// Debounce Setup
1818
uint64_t lastDebounceTime = 0; // the last time the output pin was toggled
1919
uint64_t debounceDelay = 500; // the debounce time; increase if the output flickers
2020

2121
// Stepper Speed - Lower is faster
22-
int maxStepperSpeed = 500;
23-
int shifterPosition = 0;
24-
int stepperPosition = 0;
22+
int maxStepperSpeed = 500;
23+
int lastShifterPosition = 0;
24+
int shifterPosition = 0;
25+
int stepperPosition = 0;
2526
HardwareSerial stepperSerial(2);
2627
TMC2208Stepper driver(&SERIAL_PORT, R_SENSE); // Hardware Serial
2728

@@ -45,12 +46,12 @@ void setup() {
4546
// Serial port for debugging purposes
4647
Serial.begin(512000);
4748
stepperSerial.begin(57600, SERIAL_8N2, STEPPERSERIAL_RX, STEPPERSERIAL_TX);
48-
debugDirector("Compiled " + String(__DATE__) + String(__TIME__));
49+
SS2K_LOG("Main", "Compiled %s%s", __DATE__, __TIME__);
4950

5051
// Initialize SPIFFS
51-
debugDirector("Mounting Filesystem");
52+
SS2K_LOG("Main", "Mounting Filesystem");
5253
if (!SPIFFS.begin(true)) {
53-
debugDirector("An Error has occurred while mounting SPIFFS");
54+
SS2K_LOGE("Main", "An Error has occurred while mounting SPIFFS");
5455
return;
5556
}
5657

@@ -80,7 +81,7 @@ void setup() {
8081

8182
setupTMCStepperDriver();
8283

83-
debugDirector("Setting up cpu Tasks");
84+
SS2K_LOG("Main", "Setting up cpu Tasks");
8485
disableCore0WDT(); // Disable the watchdog timer on core 0 (so long stepper
8586
// moves don't cause problems)
8687

@@ -106,7 +107,7 @@ void setup() {
106107
setupBLE();
107108
startHttpServer();
108109
resetIfShiftersHeld();
109-
debugDirector("Creating Shifter Interrupts");
110+
SS2K_LOG("Main", "Creating Shifter Interrupts");
110111
// Setup Interrups so shifters work anytime
111112
attachInterrupt(digitalPinToInterrupt(SHIFT_UP_PIN), shiftUp, CHANGE);
112113
attachInterrupt(digitalPinToInterrupt(SHIFT_DOWN_PIN), shiftDown, CHANGE);
@@ -115,11 +116,15 @@ void setup() {
115116

116117
void loop() {
117118
vTaskDelay(1000 / portTICK_RATE_MS);
118-
scanIfShiftersHeld();
119119

120-
if (debugToHTML.length() > 500) { // Clear up memory
121-
debugToHTML = "<br>HTML Debug Truncated. Increase buffer if required.";
120+
if (shifterPosition > lastShifterPosition) {
121+
SS2K_LOG("Main", "Shift UP: %d", shifterPosition);
122+
} else if (shifterPosition < lastShifterPosition) {
123+
SS2K_LOG("Main", "Shift DOWN: %d", shifterPosition);
122124
}
125+
lastShifterPosition = shifterPosition;
126+
127+
scanIfShiftersHeld();
123128

124129
#ifdef DEBUG_STACK
125130
Serial.printf("Stepper: %d \n", uxTaskGetStackHighWaterMark(moveStepperTask));
@@ -186,7 +191,6 @@ void IRAM_ATTR shiftUp() { // Handle the shift up interrupt IRAM_ATTR is to kee
186191
if (deBounce()) {
187192
if (!digitalRead(SHIFT_UP_PIN)) { // double checking to make sure the interrupt wasn't triggered by emf
188193
shifterPosition = (shifterPosition + userConfig.getShiftStep());
189-
debugDirector("Shift UP: " + String(shifterPosition));
190194
} else {
191195
lastDebounceTime = 0;
192196
} // Probably Triggered by EMF, reset the debounce
@@ -197,7 +201,6 @@ void IRAM_ATTR shiftDown() { // Handle the shift down interrupt
197201
if (deBounce()) {
198202
if (!digitalRead(SHIFT_DOWN_PIN)) { // double checking to make sure the interrupt wasn't triggered by emf
199203
shifterPosition = (shifterPosition - userConfig.getShiftStep());
200-
debugDirector("Shift DOWN: " + String(shifterPosition));
201204
} else {
202205
lastDebounceTime = 0;
203206
} // Probably Triggered by EMF, reset the debounce
@@ -206,8 +209,8 @@ void IRAM_ATTR shiftDown() { // Handle the shift down interrupt
206209

207210
void resetIfShiftersHeld() {
208211
if ((digitalRead(SHIFT_UP_PIN) == LOW) && (digitalRead(SHIFT_DOWN_PIN) == LOW)) {
209-
debugDirector("Resetting to defaults via shifter buttons.");
210-
for (int x = 0; x < 10; x++) { // blink fast to acknoledge
212+
SS2K_LOG("Main", "Resetting to defaults via shifter buttons.");
213+
for (int x = 0; x < 10; x++) { // blink fast to acknowledge
211214
digitalWrite(LED_PIN, HIGH);
212215
vTaskDelay(200 / portTICK_PERIOD_MS);
213216
digitalWrite(LED_PIN, LOW);
@@ -224,18 +227,18 @@ void resetIfShiftersHeld() {
224227

225228
void scanIfShiftersHeld() {
226229
if ((digitalRead(SHIFT_UP_PIN) == LOW) && (digitalRead(SHIFT_DOWN_PIN) == LOW)) { // are both shifters held?
227-
debugDirector("Shifters Held " + String(shiftersHoldForScan));
230+
SS2K_LOG("Main", "Shifters Held %d", shiftersHoldForScan);
228231
if (shiftersHoldForScan < 1) { // have they been held for enough loops?
229-
debugDirector("Shifters Held < 1 " + String(shiftersHoldForScan));
232+
SS2K_LOG("Main", "Shifters Held < 1 %d", shiftersHoldForScan);
230233
if ((millis() - scanDelayStart) >= scanDelayTime) { // Has this already been done within 10 seconds?
231234
scanDelayStart += scanDelayTime;
232235
spinBLEClient.resetDevices();
233236
spinBLEClient.serverScan(true);
234237
shiftersHoldForScan = SHIFTERS_HOLD_FOR_SCAN;
235238
digitalWrite(LED_PIN, LOW);
236-
debugDirector("Scan From Buttons");
239+
SS2K_LOG("Main", "Scan From Buttons");
237240
} else {
238-
debugDirector("Shifters Held but timer not up " + String((millis() - scanDelayStart) >= scanDelayTime));
241+
SS2K_LOG("Main", "Shifters Held but timer not up %d", (millis() - scanDelayStart) >= scanDelayTime);
239242
shiftersHoldForScan = SHIFTERS_HOLD_FOR_SCAN;
240243
return;
241244
}
@@ -245,29 +248,13 @@ void scanIfShiftersHeld() {
245248
}
246249
}
247250

248-
// String Text to print, Optional Make newline, Optional Send to Telegram
249-
void debugDirector(String textToPrint, bool newline, bool telegram) {
250-
if (newline) {
251-
Serial.println(textToPrint);
252-
debugToHTML += String("<br>") + textToPrint;
253-
} else {
254-
Serial.print(textToPrint);
255-
debugToHTML += textToPrint;
256-
}
257-
#ifdef USE_TELEGRAM
258-
if (telegram) {
259-
sendTelegram(textToPrint);
260-
}
261-
#endif
262-
}
263-
264251
void setupTMCStepperDriver() {
265252
driver.begin();
266253
driver.pdn_disable(true);
267254
driver.mstep_reg_select(true);
268255

269256
uint16_t msread = driver.microsteps();
270-
debugDirector(" read:ms=" + msread);
257+
SS2K_LOG("Main", " read:ms=%ud", msread);
271258

272259
driver.rms_current(userConfig.getStepperPower()); // Set motor RMS current
273260
driver.microsteps(4); // Set microsteps to 1/8th
@@ -279,8 +266,8 @@ void setupTMCStepperDriver() {
279266
msread = driver.microsteps();
280267
uint16_t currentread = driver.cs_actual();
281268

282-
debugDirector(" read:current=" + currentread);
283-
debugDirector(" read:ms=" + msread);
269+
SS2K_LOG("Main", " read:current=%ud", currentread);
270+
SS2K_LOG("Main", " read:ms=%ud", msread);
284271

285272
driver.toff(5);
286273
bool t_bool = userConfig.getStealthchop();
@@ -290,7 +277,7 @@ void setupTMCStepperDriver() {
290277
}
291278

292279
void updateStepperPower() {
293-
debugDirector("Stepper power is now " + String(userConfig.getStepperPower()));
280+
SS2K_LOG("Main", "Stepper power is now %d", userConfig.getStepperPower());
294281
driver.rms_current(userConfig.getStepperPower());
295282
}
296283

@@ -299,5 +286,5 @@ void updateStealthchop() {
299286
driver.en_spreadCycle(!t_bool);
300287
driver.pwm_autoscale(t_bool);
301288
driver.pwm_autograd(t_bool);
302-
debugDirector("Stealthchop is now " + String(t_bool));
289+
SS2K_LOG("Main", "Stealthchop is now %d", t_bool);
303290
}

‎src/SS2KLog.cpp

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright (C) 2020 Anthony Doud & Joel Baranick
3+
* All rights reserved
4+
*
5+
* SPDX-License-Identifier: GPL-2.0-only
6+
*/
7+
8+
#include "SS2KLog.h"
9+
10+
DebugInfo DebugInfo::INSTANCE = DebugInfo();
11+
12+
#if DEBUG_LOG_BUFFER_SIZE > 0
13+
void DebugInfo::appendLog(const char *format, ...) {
14+
va_list args;
15+
va_start(args, format);
16+
DebugInfo::INSTANCE.appendLog_internal(format, args);
17+
va_end(args);
18+
}
19+
20+
const std::string DebugInfo::getAndClearLogs() { return DebugInfo::INSTANCE.getAndClearLogs_internal(); }
21+
22+
void DebugInfo::appendLog_internal(const char *format, va_list args) {
23+
if (xSemaphoreTake(logBufferMutex, 1000) == pdTRUE) {
24+
int written = vsnprintf(logBuffer + logBufferLength, DEBUG_LOG_BUFFER_SIZE - logBufferLength, format, args);
25+
SS2K_LOGD("DebugInfo", "Wrote %d bytes to log", written);
26+
if (written < 0 || logBufferLength + written > DEBUG_LOG_BUFFER_SIZE) {
27+
logBufferLength = snprintf(logBuffer, DEBUG_LOG_BUFFER_SIZE, "...\n");
28+
} else {
29+
logBufferLength += written;
30+
}
31+
SS2K_LOGD("DebugInfo", "Log buffer length %d of %d bytes", logBufferLength, DEBUG_LOG_BUFFER_SIZE);
32+
xSemaphoreGive(logBufferMutex);
33+
}
34+
}
35+
36+
const std::string DebugInfo::getAndClearLogs_internal() {
37+
if (xSemaphoreTake(logBufferMutex, 500) == pdTRUE) {
38+
const std::string debugLog = std::string(logBuffer, logBufferLength);
39+
logBufferLength = 0;
40+
logBuffer[0] = '\0';
41+
xSemaphoreGive(logBufferMutex);
42+
SS2K_LOGD("DebugInfo", "Log buffer read %d bytes and cleared", logBufferLength);
43+
return debugLog;
44+
}
45+
return "";
46+
}
47+
#else
48+
void DebugInfo::appendLog(const char *format, ...) {}
49+
50+
String DebugInfo::getAndClearLogs() { return ""; }
51+
#endif
52+
53+
void ss2k_remove_newlines(std::string *str) {
54+
std::string::size_type pos = 0;
55+
while ((pos = (*str).find("\n", pos)) != std::string::npos) {
56+
(*str).replace(pos, 1, " ");
57+
}
58+
}
59+
60+
int ss2k_log_hex_to_buffer(const byte *data, const size_t data_length, char *buffer, const int buffer_offset, const size_t buffer_length) {
61+
int written = 0;
62+
for (int data_offset = 0; data_offset < data_length; data_offset++) {
63+
written += snprintf(buffer + buffer_offset + written, buffer_length - written + buffer_offset, "%02x ", *(data + data_offset));
64+
}
65+
return written;
66+
}
67+
68+
void ss2k_log_file_internal(const char *tag, File file) {
69+
if (!file.available()) {
70+
return;
71+
}
72+
char char_buffer[DEBUG_FILE_CHARS_PER_LINE + 1];
73+
int bytes_cur_line;
74+
75+
while (file.available()) {
76+
if (file.available() > DEBUG_FILE_CHARS_PER_LINE) {
77+
bytes_cur_line = DEBUG_FILE_CHARS_PER_LINE;
78+
} else {
79+
bytes_cur_line = file.available();
80+
}
81+
for (int i = 0; i < bytes_cur_line; i++) {
82+
sprintf(char_buffer + i, "%c", file.read());
83+
}
84+
SS2K_LOG(tag, "%s", char_buffer);
85+
}
86+
}

‎src/SmartSpin_parameters.cpp

+24-29
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include "Main.h"
9+
#include "SS2KLog.h"
910
#include "SmartSpin_parameters.h"
1011

1112
#include <ArduinoJson.h>
@@ -39,14 +40,15 @@ void userParameters::setDefaults() { // Move these to set the values as #define
3940

4041
//---------------------------------------------------------------------------------
4142
//-- return all config as one a single JSON string
42-
String userParameters::returnJSON() {
43+
String userParameters::returnJSON(bool includeDebugLog) {
4344
// Allocate a temporary JsonDocument
4445
// Don't forget to change the capacity to match your requirements.
4546
// Use arduinojson.org/assistant to compute the capacity.
4647
StaticJsonDocument<USERCONFIG_JSON_SIZE> doc;
4748
// Set the values in the document
4849

4950
doc["firmwareUpdateURL"] = firmwareUpdateURL;
51+
doc["firmwareVersion"] = FIRMWARE_VERSION;
5052
doc["incline"] = incline;
5153
doc["simulatedWatts"] = simulatedWatts;
5254
doc["simulatedHr"] = simulatedHr;
@@ -67,6 +69,9 @@ String userParameters::returnJSON() {
6769
doc["foundDevices"] = foundDevices;
6870
doc["connectedPowerMeter"] = connectedPowerMeter;
6971
doc["connectedHeartMonitor"] = connectedHeartMonitor;
72+
if (includeDebugLog) {
73+
doc["debug"] = DebugInfo::getAndClearLogs();
74+
}
7075
String output;
7176
serializeJson(doc, output);
7277
return output;
@@ -78,10 +83,10 @@ void userParameters::saveToSPIFFS() {
7883
SPIFFS.remove(configFILENAME);
7984

8085
// Open file for writing
81-
debugDirector("Writing File: " + String(configFILENAME));
86+
SS2K_LOG("Config", "Writing File: %s", configFILENAME);
8287
File file = SPIFFS.open(configFILENAME, FILE_WRITE);
8388
if (!file) {
84-
debugDirector(F("Failed to create file"));
89+
SS2K_LOGE("Config", "Failed to create file");
8590
return;
8691
}
8792

@@ -117,7 +122,7 @@ void userParameters::saveToSPIFFS() {
117122

118123
// Serialize JSON to file
119124
if (serializeJson(doc, file) == 0) {
120-
debugDirector(F("Failed to write to file"));
125+
SS2K_LOGE("Config", "Failed to write to file");
121126
}
122127
// Close the file
123128
file.close();
@@ -126,12 +131,12 @@ void userParameters::saveToSPIFFS() {
126131
// Loads the JSON configuration from a file into a userParameters Object
127132
void userParameters::loadFromSPIFFS() {
128133
// Open file for reading
129-
debugDirector("Reading File: " + String(configFILENAME));
134+
SS2K_LOG("Config", "Reading File: %s", configFILENAME);
130135
File file = SPIFFS.open(configFILENAME);
131136

132137
// load defaults if filename doesn't exist
133138
if (!file) {
134-
debugDirector("Couldn't find configuration file. Loading Defaults");
139+
SS2K_LOG("Config", "Couldn't find configuration file. Loading Defaults");
135140
setDefaults();
136141
return;
137142
}
@@ -143,7 +148,7 @@ void userParameters::loadFromSPIFFS() {
143148
// Deserialize the JSON document
144149
DeserializationError error = deserializeJson(doc, file);
145150
if (error) {
146-
debugDirector(F("Failed to read file, using default configuration"));
151+
SS2K_LOGE("Config", "Failed to read file, using default configuration");
147152
setDefaults();
148153
return;
149154
}
@@ -171,25 +176,20 @@ void userParameters::loadFromSPIFFS() {
171176
setConnectedPowerMeter(doc["connectedPowerMeter"]);
172177
setConnectedHeartMonitor(doc["connectedHeartMonitor"]);
173178

174-
debugDirector("Config File Loaded: " + String(configFILENAME));
179+
SS2K_LOG("Config", "Config File Loaded: %s", configFILENAME);
175180
file.close();
176181
}
177182

178183
// Prints the content of a file to the Serial
179184
void userParameters::printFile() {
180185
// Open file for reading
181-
debugDirector("Contents of file: " + String(configFILENAME));
186+
SS2K_LOG("Config", "Contents of file: %s", configFILENAME);
182187
File file = SPIFFS.open(configFILENAME);
183188
if (!file) {
184-
debugDirector(F("Failed to read file"));
189+
SS2K_LOGE("Config", "Failed to read file");
185190
return;
186191
}
187192

188-
// Extract each characters by one by one
189-
while (file.available()) {
190-
debugDirector(String(static_cast<char>(file.read())), false);
191-
}
192-
debugDirector(String(" "));
193193
// Close the file
194194
file.close();
195195
}
@@ -225,10 +225,10 @@ void physicalWorkingCapacity::saveToSPIFFS() {
225225
SPIFFS.remove(userPWCFILENAME);
226226

227227
// Open file for writing
228-
debugDirector("Writing File: " + String(userPWCFILENAME));
228+
SS2K_LOG("Config", "Writing File: %s", userPWCFILENAME);
229229
File file = SPIFFS.open(userPWCFILENAME, FILE_WRITE);
230230
if (!file) {
231-
debugDirector(F("Failed to create file"));
231+
SS2K_LOGE("Config", "Failed to create file");
232232
return;
233233
}
234234

@@ -242,7 +242,7 @@ void physicalWorkingCapacity::saveToSPIFFS() {
242242

243243
// Serialize JSON to file
244244
if (serializeJson(doc, file) == 0) {
245-
debugDirector(F("Failed to write to file"));
245+
SS2K_LOGE("Config", "Failed to write to file");
246246
}
247247
// Close the file
248248
file.close();
@@ -251,12 +251,12 @@ void physicalWorkingCapacity::saveToSPIFFS() {
251251
// Loads the JSON configuration from a file
252252
void physicalWorkingCapacity::loadFromSPIFFS() {
253253
// Open file for reading
254-
debugDirector("Reading File: " + String(userPWCFILENAME));
254+
SS2K_LOG("Config", "Reading File: %s", userPWCFILENAME);
255255
File file = SPIFFS.open(userPWCFILENAME);
256256

257257
// load defaults if filename doesn't exist
258258
if (!file) {
259-
debugDirector("Couldn't find configuration file. Loading Defaults");
259+
SS2K_LOG("Config", "Couldn't find configuration file. Loading Defaults");
260260
setDefaults();
261261
return;
262262
}
@@ -266,7 +266,7 @@ void physicalWorkingCapacity::loadFromSPIFFS() {
266266
// Deserialize the JSON document
267267
DeserializationError error = deserializeJson(doc, file);
268268
if (error) {
269-
debugDirector(F("Failed to read file, using default configuration"));
269+
SS2K_LOGE("Config", "Failed to read file, using default configuration");
270270
setDefaults();
271271
return;
272272
}
@@ -278,25 +278,20 @@ void physicalWorkingCapacity::loadFromSPIFFS() {
278278
session2Pwr = doc["session2Pwr"];
279279
hr2Pwr = doc["hr2Pwr"];
280280

281-
debugDirector("Config File Loaded: " + String(userPWCFILENAME));
281+
SS2K_LOG("Config", "Config File Loaded: %s", userPWCFILENAME);
282282
file.close();
283283
}
284284

285285
// Prints the content of a file to the Serial
286286
void physicalWorkingCapacity::printFile() {
287287
// Open file for reading
288-
debugDirector("Contents of file: " + String(userPWCFILENAME));
288+
SS2K_LOG("Config", "Contents of file: %s", userPWCFILENAME);
289289
File file = SPIFFS.open(userPWCFILENAME);
290290
if (!file) {
291-
debugDirector(F("Failed to read file"));
291+
SS2K_LOGE("Config", "Failed to read file");
292292
return;
293293
}
294294

295-
// Extract each characters by one by one
296-
while (file.available()) {
297-
debugDirector(String(static_cast<char>(file.read())), false);
298-
}
299-
debugDirector(String(" "));
300295
// Close the file
301296
file.close();
302297
}

0 commit comments

Comments
 (0)
Please sign in to comment.