Refactored string in JSON moderator - const char* are BAD AND EVIL in a std::map

MQTT parameter exchange via JSON and NV storage
This commit is contained in:
Ray Jones 2019-05-12 20:15:18 +10:00
parent 38711533cd
commit 04fab40742
20 changed files with 322 additions and 138 deletions

View file

@ -115,9 +115,9 @@
#define RX_DATA_TIMOUT 50 #define RX_DATA_TIMOUT 50
const int FirmwareRevision = 22; const int FirmwareRevision = 23;
const int FirmwareSubRevision = 3; const int FirmwareSubRevision = 0;
const char* FirmwareDate = "11 May 2019"; const char* FirmwareDate = "12 May 2019";
#ifdef ESP32 #ifdef ESP32
@ -267,7 +267,7 @@ const char* print18B20Address(DeviceAddress deviceAddress)
#if USE_SPIFFS == 1 #if USE_SPIFFS == 1
void listDir(fs::FS &fs, const char * dirname, uint8_t levels) void listDir(fs::FS &fs, const char * dirname, uint8_t levels)
{ {
DebugPort.print("Listing directory: "); DebugPort.println(dirname); DebugPort.printf("Listing directory: %s\r\n", dirname);
File root = fs.open(dirname); File root = fs.open(dirname);
if (!root) { if (!root) {
@ -282,16 +282,12 @@ void listDir(fs::FS &fs, const char * dirname, uint8_t levels)
File file = root.openNextFile(); File file = root.openNextFile();
while (file) { while (file) {
if (file.isDirectory()) { if (file.isDirectory()) {
DebugPort.print(" DIR : "); DebugPort.printf(" DIR : %s\r\n", file.name());
DebugPort.println(file.name());
if (levels) { if (levels) {
listDir(fs, file.name(), levels - 1); listDir(fs, file.name(), levels - 1);
} }
} else { } else {
DebugPort.print(" FILE: "); DebugPort.printf(" FILE: %s SIZE: %ld\r\n", file.name(), file.size());
DebugPort.print(file.name());
DebugPort.print(" SIZE: ");
DebugPort.println(file.size());
} }
file = root.openNextFile(); file = root.openNextFile();
} }
@ -314,11 +310,10 @@ void setup() {
DebugPort.println("_______________________________________________________________"); DebugPort.println("_______________________________________________________________");
DebugPort.println("DS18B20 status dump"); DebugPort.println("DS18B20 status dump");
sprintf(msg, " Temperature for device#1 (idx 0) is: %.1f", TempSensor.getTempCByIndex(0)); DebugPort.printf(" Temperature for device#1 (idx 0) is: %.1f\r\n", TempSensor.getTempCByIndex(0));
DebugPort.println(msg);
BoardRevision = BoardDetect(); BoardRevision = BoardDetect();
DebugPort.print("Board revision: V"); DebugPort.println(float(BoardRevision) * 0.1, 1); DebugPort.printf("Board revision: V%.1f\r\n", float(BoardRevision) * 0.1);
#if USE_SPIFFS == 1 #if USE_SPIFFS == 1
// Initialize SPIFFS // Initialize SPIFFS
@ -338,12 +333,10 @@ void setup() {
// Grab a count of devices on the wire // Grab a count of devices on the wire
int numberOfDevices = TempSensor.getDeviceCount(); int numberOfDevices = TempSensor.getDeviceCount();
sprintf(msg, " Found %d devices", numberOfDevices); DebugPort.printf(" Found %d devices\r\n", numberOfDevices);
DebugPort.println(msg);
// report parasite power requirements // report parasite power requirements
sprintf(msg, " Parasite power is: %s", TempSensor.isParasitePowerMode() ? "ON" : "OFF"); DebugPort.printf(" Parasite power is: %s\r\n", TempSensor.isParasitePowerMode() ? "ON" : "OFF");
DebugPort.println(msg);
// Loop through each device, print out address // Loop through each device, print out address
for(int i=0;i<numberOfDevices; i++) for(int i=0;i<numberOfDevices; i++)
@ -351,14 +344,11 @@ void setup() {
// Search the wire for address // Search the wire for address
DeviceAddress tempDeviceAddress; DeviceAddress tempDeviceAddress;
if(TempSensor.getAddress(tempDeviceAddress, i)) { if(TempSensor.getAddress(tempDeviceAddress, i)) {
sprintf(msg, " Found DS18B20 device#%d with address: %s", i+1, print18B20Address(tempDeviceAddress)); DebugPort.printf(" Found DS18B20 device#%d with address: %s\r\n", i+1, print18B20Address(tempDeviceAddress));
DebugPort.println(msg);
sprintf(msg, " Resolution: %d bits", TempSensor.getResolution(tempDeviceAddress)); DebugPort.printf(" Resolution: %d bits\r\n", TempSensor.getResolution(tempDeviceAddress));
DebugPort.println(msg);
} else { } else {
sprintf(msg, " Found ghost @ device#%d, but could not detect address. Check power and cabling", i+1); DebugPort.printf(" Found ghost @ device#%d, but could not detect address. Check power and cabling\r\n", i+1);
DebugPort.println(msg);
} }
} }
memset(tempSensorAddress, 0, 8); memset(tempSensorAddress, 0, 8);
@ -373,6 +363,7 @@ void setup() {
NVstore.init(); NVstore.init();
NVstore.load(); NVstore.load();
initMQTTJSONmoderator(); // prevent JSON for MQTT unless requested
KeyPad.begin(keyLeft_pin, keyRight_pin, keyCentre_pin, keyUp_pin, keyDown_pin); KeyPad.begin(keyLeft_pin, keyRight_pin, keyCentre_pin, keyUp_pin, keyDown_pin);
KeyPad.setCallback(parentKeyHandler); KeyPad.setCallback(parentKeyHandler);
@ -516,8 +507,7 @@ void loop()
if(RxTimeElapsed >= moderator) { if(RxTimeElapsed >= moderator) {
moderator += 10; moderator += 10;
if(bReportRecyleEvents) { if(bReportRecyleEvents) {
DebugPort.print(RxTimeElapsed); DebugPort.printf("%ldms - ", RxTimeElapsed);
DebugPort.print("ms - ");
} }
if(CommState.is(CommStates::OEMCtrlRx)) { if(CommState.is(CommStates::OEMCtrlRx)) {
bHasOEMController = false; bHasOEMController = false;
@ -579,9 +569,7 @@ void loop()
if(BlueWireData.available() && (RxTimeElapsed > RX_DATA_TIMOUT+10)) { if(BlueWireData.available() && (RxTimeElapsed > RX_DATA_TIMOUT+10)) {
if(bReportOEMresync) { if(bReportOEMresync) {
DebugPort.print("Re-sync'd with OEM Controller. "); DebugPort.printf("Re-sync'd with OEM Controller. %ldms Idle time.\r\n", RxTimeElapsed);
DebugPort.print(RxTimeElapsed);
DebugPort.println("ms Idle time.");
} }
bHasHtrData = false; bHasHtrData = false;
@ -785,7 +773,7 @@ void loop()
if(tDelta > TEMPERATURE_INTERVAL) { // maintain a minimum holdoff period if(tDelta > TEMPERATURE_INTERVAL) { // maintain a minimum holdoff period
lastTemperatureTime += TEMPERATURE_INTERVAL; // reset time to observe temeprature lastTemperatureTime += TEMPERATURE_INTERVAL; // reset time to observe temeprature
fTemperature = TempSensor.getTempC(tempSensorAddress); // read sensor fTemperature = TempSensor.getTempC(tempSensorAddress); // read sensor
// DebugPort.print("DS18B20 = "); DebugPort.println(fTemperature); // DebugPort.printf("DS18B20 = %f\r\n", fTemperature);
// initialise filtered temperature upon very first pass // initialise filtered temperature upon very first pass
if(fTemperature > -80) { // avoid disconnected sensor readings being integrated if(fTemperature > -80) { // avoid disconnected sensor readings being integrated
if(DS18B20holdoff) if(DS18B20holdoff)
@ -834,8 +822,7 @@ void manageCyclicMode()
if(cyclic.Stop && bUserON) { // cyclic mode enabled, and user has started heater if(cyclic.Stop && bUserON) { // cyclic mode enabled, and user has started heater
int stopDeltaT = cyclic.Stop + 1; // bump up by 1 degree - no point invoking at 1 deg over! int stopDeltaT = cyclic.Stop + 1; // bump up by 1 degree - no point invoking at 1 deg over!
float deltaT = fFilteredTemperature - getSetTemp(); float deltaT = fFilteredTemperature - getSetTemp();
// DebugPort.print("Cyclic = "); DebugPort.print(cyclic); DebugPort.print(" bUserON = "); DebugPort.print(bUserON); // DebugPort.printf("Cyclic=%d bUserOn=%d deltaT=%d\r\n", cyclic, bUserON, deltaT);
// DebugPort.print(" deltaT = "); DebugPort.println(deltaT);
// ensure we cancel user ON mode if heater throws an error // ensure we cancel user ON mode if heater throws an error
int errState = getHeaterInfo().getErrState(); int errState = getHeaterInfo().getErrState();
@ -848,7 +835,7 @@ void manageCyclicMode()
// check if over temp, turn off heater // check if over temp, turn off heater
if(deltaT > stopDeltaT) { if(deltaT > stopDeltaT) {
if(heaterState > 0 && heaterState <= 5) { if(heaterState > 0 && heaterState <= 5) {
DebugPort.print("CYCLIC MODE: Stopping heater, deltaT > +"); DebugPort.println(stopDeltaT); DebugPort.printf("CYCLIC MODE: Stopping heater, deltaT > +%d\r\n", stopDeltaT);
heaterOff(); // over temp - request heater stop heaterOff(); // over temp - request heater stop
} }
} }
@ -856,7 +843,7 @@ void manageCyclicMode()
if(deltaT < cyclic.Start) { if(deltaT < cyclic.Start) {
// typ. 1 degree below set point - restart heater // typ. 1 degree below set point - restart heater
if(heaterState == 0) { if(heaterState == 0) {
DebugPort.print("CYCLIC MODE: Restarting heater, deltaT <"); DebugPort.println(cyclic.Start); DebugPort.printf("CYCLIC MODE: Restarting heater, deltaT <%d\r\n", cyclic.Start);
heaterOn(); heaterOn();
} }
} }
@ -883,9 +870,7 @@ bool validateFrame(const CProtocol& frame, const char* name)
{ {
if(!frame.verifyCRC()) { if(!frame.verifyCRC()) {
// Bad CRC - restart blue wire Serial port // Bad CRC - restart blue wire Serial port
DebugPort.print("\007Bad CRC detected for "); DebugPort.printf("\007Bad CRC detected for %s frame - restarting blue wire's serial port\r\n", name);
DebugPort.print(name);
DebugPort.println(" frame - restarting blue wire's serial port");
DebugReportFrame("BAD CRC:", frame, "\r\n"); DebugReportFrame("BAD CRC:", frame, "\r\n");
initBlueWireSerial(); initBlueWireSerial();
CommState.set(CommStates::TemperatureRead); CommState.set(CommStates::TemperatureRead);
@ -1101,11 +1086,11 @@ void checkDebugCommands()
DebugPort.print("\014"); DebugPort.print("\014");
DebugPort.println("MENU options"); DebugPort.println("MENU options");
DebugPort.println(""); DebugPort.println("");
DebugPort.print(" <B> - toggle raw blue wire data reporting, currently "); DebugPort.println(bReportBlueWireData ? "ON" : "OFF"); DebugPort.printf(" <B> - toggle raw blue wire data reporting, currently %s\r\n", bReportBlueWireData ? "ON" : "OFF");
DebugPort.print(" <J> - toggle output JSON reporting, currently "); DebugPort.println(bReportJSONData ? "ON" : "OFF"); DebugPort.printf(" <J> - toggle output JSON reporting, currently %s\r\n", bReportJSONData ? "ON" : "OFF");
DebugPort.print(" <W> - toggle reporting of blue wire timeout/recycling event, currently "); DebugPort.println(bReportRecyleEvents ? "ON" : "OFF"); DebugPort.printf(" <W> - toggle reporting of blue wire timeout/recycling event, currently %s\r\n", bReportRecyleEvents ? "ON" : "OFF");
DebugPort.print(" <O> - toggle reporting of OEM resync event, currently "); DebugPort.println(bReportOEMresync ? "ON" : "OFF"); DebugPort.printf(" <O> - toggle reporting of OEM resync event, currently %s\r\n", bReportOEMresync ? "ON" : "OFF");
DebugPort.print(" <S> - toggle reporting of state machine transits "); DebugPort.println(bReportOEMresync ? "ON" : "OFF"); DebugPort.printf(" <S> - toggle reporting of state machine transits %s\r\n", CommState.isReporting() ? "ON" : "OFF");
DebugPort.println(" <+> - request heater turns ON"); DebugPort.println(" <+> - request heater turns ON");
DebugPort.println(" <-> - request heater turns OFF"); DebugPort.println(" <-> - request heater turns OFF");
DebugPort.println(" <R> - restart the ESP"); DebugPort.println(" <R> - restart the ESP");
@ -1154,19 +1139,19 @@ void checkDebugCommands()
#endif #endif
else if(rxVal == 'b') { else if(rxVal == 'b') {
bReportBlueWireData = !bReportBlueWireData; bReportBlueWireData = !bReportBlueWireData;
DebugPort.print("Toggled raw blue wire data reporting "); DebugPort.println(bReportBlueWireData ? "ON" : "OFF"); DebugPort.printf("Toggled raw blue wire data reporting %s\r\n", bReportBlueWireData ? "ON" : "OFF");
} }
else if(rxVal == 'j') { else if(rxVal == 'j') {
bReportJSONData = !bReportJSONData; bReportJSONData = !bReportJSONData;
DebugPort.print("Toggled JSON data reporting "); DebugPort.println(bReportJSONData ? "ON" : "OFF"); DebugPort.printf("Toggled JSON data reporting %s\r\n", bReportJSONData ? "ON" : "OFF");
} }
else if(rxVal == 'w') { else if(rxVal == 'w') {
bReportRecyleEvents = !bReportRecyleEvents; bReportRecyleEvents = !bReportRecyleEvents;
DebugPort.print("Toggled blue wire recycling event reporting "); DebugPort.println(bReportRecyleEvents ? "ON" : "OFF"); DebugPort.printf("Toggled blue wire recycling event reporting %s\r\n", bReportRecyleEvents ? "ON" : "OFF");
} }
else if(rxVal == 'o') { else if(rxVal == 'o') {
bReportOEMresync = !bReportOEMresync; bReportOEMresync = !bReportOEMresync;
DebugPort.print("Toggled OEM resync event reporting "); DebugPort.println(bReportOEMresync ? "ON" : "OFF"); DebugPort.printf("Toggled OEM resync event reporting %s\r\n", bReportOEMresync ? "ON" : "OFF");
} }
else if(rxVal == 's') { else if(rxVal == 's') {
CommState.toggleReporting(); CommState.toggleReporting();
@ -1197,7 +1182,7 @@ void checkDebugCommands()
DefaultBTCParams.Controller.Unknown2_LSB = (val >> 0) & 0xff; // always 0xac 16bit: "3500" ?? Ignition fan max RPM???? DefaultBTCParams.Controller.Unknown2_LSB = (val >> 0) & 0xff; // always 0xac 16bit: "3500" ?? Ignition fan max RPM????
break; break;
case 4: case 4:
DebugPort.print("Forced controller command = "); DebugPort.println(val&0xff); DebugPort.printf("Forced controller command = %d\r\n", val&0xff);
DefaultBTCParams.Controller.Command = val & 0xff; DefaultBTCParams.Controller.Command = val & 0xff;
break; break;
} }
@ -1224,7 +1209,7 @@ int getBlueWireStat()
const char* getBlueWireStatStr() const char* getBlueWireStatStr()
{ {
const char* BlueWireStates[] = { "BTC,Htr", "BTC", "OEM,Htr", "OEM" }; static const char* BlueWireStates[] = { "BTC,Htr", "BTC", "OEM,Htr", "OEM" };
return BlueWireStates[getBlueWireStat()]; return BlueWireStates[getBlueWireStat()];
} }
@ -1293,14 +1278,14 @@ void setupGPIO()
void setGPIO(int channel, bool state) void setGPIO(int channel, bool state)
{ {
DebugPort.print("setGPIO: Output #"); DebugPort.print(channel+1); DebugPort.print(" = "); DebugPort.println(state); DebugPort.printf("setGPIO: Output #%d = %d\r\n", channel+1, state);
GPIOout.setState(channel, state); GPIOout.setState(channel, state);
} }
bool getGPIO(int channel) bool getGPIO(int channel)
{ {
bool retval = GPIOout.getState(channel); bool retval = GPIOout.getState(channel);
DebugPort.print("getGPIO: Output #"); DebugPort.print(channel+1); DebugPort.print(" = "); DebugPort.println(retval); DebugPort.printf("getGPIO: Output #%d = %d\r\n", channel+1, retval);
return retval; return retval;
} }

View file

@ -63,9 +63,7 @@ CBluetoothHC05::begin()
int BTidx = 0; int BTidx = 0;
int maxTries = sizeof(BTRates)/sizeof(int); int maxTries = sizeof(BTRates)/sizeof(int);
for(BTidx = 0; BTidx < maxTries; BTidx++) { for(BTidx = 0; BTidx < maxTries; BTidx++) {
DebugPort.print(" @ "); DebugPort.printf(" @ %d baud... ", BTRates[BTidx]);
DebugPort.print(BTRates[BTidx]);
DebugPort.print(" baud... ");
openSerial(BTRates[BTidx]); // open serial port at a std. baud rate openSerial(BTRates[BTidx]); // open serial port at a std. baud rate
delay(10); delay(10);
flush(); flush();

View file

@ -298,7 +298,7 @@ CScreenManager::checkUpdate()
} }
else { else {
_rootMenu = _subMenu = 1; _rootMenu = _subMenu = 1;
DebugPort.print("Screen Manager: Menu timeout, falling back to Basic control screen"); DebugPort.println("Screen Manager: Menu timeout, falling back to Basic control screen");
} }
} }
_enterScreen(); _enterScreen();

View file

@ -76,10 +76,7 @@ CProtocol::verifyCRC(bool bSilent) const
unsigned short FrameCRC = getCRC(); unsigned short FrameCRC = getCRC();
bool bOK = (FrameCRC == CRC); bool bOK = (FrameCRC == CRC);
if(!bOK && !bSilent) { if(!bOK && !bSilent) {
DebugPort.print("verifyCRC FAILED: calc:"); DebugPort.printf("verifyCRC FAILED: calc: %04X data: %04X\r\n", CRC, FrameCRC);
DebugPort.print(CRC, HEX);
DebugPort.print(" data:");
DebugPort.println(FrameCRC, HEX);
} }
return bOK; // does it match the stored values? return bOK; // does it match the stored values?
} }

View file

@ -137,7 +137,7 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
float tDelta = tCurrent - tDesired; float tDelta = tCurrent - tDesired;
float fTemp; float fTemp;
#ifdef DEBUG_THERMOSTAT #ifdef DEBUG_THERMOSTAT
DebugPort.print("Window = "); DebugPort.print(Window); DebugPort.print(" tCurrent = "); DebugPort.print(tCurrent); DebugPort.print(" tDesired = "); DebugPort.print(tDesired); DebugPort.print(" tDelta = "); DebugPort.println(tDelta); DebugPort.printf("Window=%.1f tCurrent=%.1f tDesired=%.1f tDelta=%.1f\r\n", Window, tCurrent, tDesired, tDelta);
#endif #endif
Window /= 2; Window /= 2;
switch(ThermoMode) { switch(ThermoMode) {
@ -148,7 +148,7 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
u8Temp = (uint8_t)(tActual + 0.5); u8Temp = (uint8_t)(tActual + 0.5);
m_TxFrame.setTemperature_Actual(u8Temp); m_TxFrame.setTemperature_Actual(u8Temp);
#ifdef DEBUG_THERMOSTAT #ifdef DEBUG_THERMOSTAT
DebugPort.print("Conventional thermostat mode: tActual = "); DebugPort.println(u8Temp); DebugPort.printf("Conventional thermostat mode: tActual = %d\r\n", u8Temp);
#endif #endif
break; break;
@ -165,7 +165,7 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
} }
m_TxFrame.setTemperature_Actual(u8Temp); m_TxFrame.setTemperature_Actual(u8Temp);
#ifdef DEBUG_THERMOSTAT #ifdef DEBUG_THERMOSTAT
DebugPort.print("Heater controlled windowed thermostat mode: tActual = "); DebugPort.println(u8Temp); DebugPort.printf("Heater controlled windowed thermostat mode: tActual=%d\r\n", u8Temp);
#endif #endif
break; break;
@ -175,7 +175,7 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
// so create a desired "temp" according the the current hystersis // so create a desired "temp" according the the current hystersis
tDelta /= Window; // convert tDelta to fraction of window (CAUTION - may be > +-1 !) tDelta /= Window; // convert tDelta to fraction of window (CAUTION - may be > +-1 !)
#ifdef DEBUG_THERMOSTAT #ifdef DEBUG_THERMOSTAT
DebugPort.print("Linear window thermostat mode: Fraction = "); DebugPort.print(tDelta); DebugPort.printf("Linear window thermostat mode: Fraction=%f", tDelta);
#endif #endif
fTemp = (m_TxFrame.getTemperature_Max() + m_TxFrame.getTemperature_Min()) * 0.5; // midpoint - tDelta = 0 hinges here fTemp = (m_TxFrame.getTemperature_Max() + m_TxFrame.getTemperature_Min()) * 0.5; // midpoint - tDelta = 0 hinges here
tDelta *= (m_TxFrame.getTemperature_Max() - fTemp); // linear offset from setpoint tDelta *= (m_TxFrame.getTemperature_Max() - fTemp); // linear offset from setpoint
@ -189,7 +189,7 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster)
m_TxFrame.setThermostatModeProtocol(0); // direct heater to use Hz Mode m_TxFrame.setThermostatModeProtocol(0); // direct heater to use Hz Mode
m_TxFrame.setTemperature_Actual(0); // must force actual to 0 for Hz mode m_TxFrame.setTemperature_Actual(0); // must force actual to 0 for Hz mode
#ifdef DEBUG_THERMOSTAT #ifdef DEBUG_THERMOSTAT
DebugPort.print(" tDesired (pseudo Hz demand) = "); DebugPort.println(u8Temp); DebugPort.printf(" tDesired (pseudo Hz demand) = %d\r\n", u8Temp);
#endif #endif
break; break;
} }

View file

@ -109,7 +109,7 @@ CClock::set(const DateTime& newTimeDate)
void setDateTime(const char* newTime) void setDateTime(const char* newTime)
{ {
DebugPort.print("setting time to: "); DebugPort.println(newTime); DebugPort.printf("setting time to: %s\r\n", newTime);
int month,day,year,hour,minute,second; int month,day,year,hour,minute,second;
if(6 == sscanf(newTime, "%d/%d/%d %d:%d:%d", &day, &month, &year, &hour, &minute, &second)) { if(6 == sscanf(newTime, "%d/%d/%d %d:%d:%d", &day, &month, &year, &hour, &minute, &second)) {
DateTime newDateTime(year, month, day, hour, minute, second); DateTime newDateTime(year, month, day, hour, minute, second);
@ -119,7 +119,7 @@ void setDateTime(const char* newTime)
void setDate(const char* newDate) void setDate(const char* newDate)
{ {
DebugPort.print("setting date to: "); DebugPort.println(newDate); DebugPort.printf("setting date to: %s\r\n", newDate);
int month,day,year; int month,day,year;
if(3 == sscanf(newDate, "%d/%d/%d", &day, &month, &year)) { if(3 == sscanf(newDate, "%d/%d/%d", &day, &month, &year)) {
DateTime currentDateTime = Clock.get(); DateTime currentDateTime = Clock.get();
@ -130,7 +130,7 @@ void setDate(const char* newDate)
void setTime(const char* newTime) void setTime(const char* newTime)
{ {
DebugPort.print("setting time to: "); DebugPort.println(newTime); DebugPort.printf("setting time to: %s\r\n", newTime);
int hour,minute,second; int hour,minute,second;
if(3 == sscanf(newTime, "%d:%d:%d", &hour, &minute, &second)) { if(3 == sscanf(newTime, "%d:%d:%d", &hour, &minute, &second)) {
DateTime currentDateTime = Clock.get(); DateTime currentDateTime = Clock.get();

View file

@ -222,11 +222,9 @@ CTimerManager::manageTime(int _hour, int _minute, int _dow)
int newID = weekTimerIDs[dow][dayMinute]; int newID = weekTimerIDs[dow][dayMinute];
if(activeTimer != newID) { if(activeTimer != newID) {
DebugPort.print("Timer ID change detected "); DebugPort.printf("Timer ID change detected: %d", activeTimer & 0x0f);
DebugPort.print(activeTimer & 0x0f);
if(activeTimer & 0x80) DebugPort.print("(repeating)"); if(activeTimer & 0x80) DebugPort.print("(repeating)");
DebugPort.print(" -> "); DebugPort.printf(" -> %d", newID & 0x0f);
DebugPort.print(newID & 0x0f);
if(newID & 0x80) DebugPort.print("(repeating)"); if(newID & 0x80) DebugPort.print("(repeating)");
DebugPort.println(""); DebugPort.println("");
@ -239,7 +237,7 @@ CTimerManager::manageTime(int _hour, int _minute, int _dow)
} }
else { // non repeating timer else { // non repeating timer
// delete one shot timer - note that this may require ticking off each day as they appear // delete one shot timer - note that this may require ticking off each day as they appear
DebugPort.print("Expired timer does not repeat - Cancelling"); DebugPort.println(activeTimer); DebugPort.printf("Expired timer does not repeat - Cancelling %d\r\n", activeTimer);
int ID = activeTimer & 0x0f; int ID = activeTimer & 0x0f;
if(ID) { if(ID) {
ID--; ID--;
@ -251,7 +249,7 @@ CTimerManager::manageTime(int _hour, int _minute, int _dow)
timer.enabled = 0; // ouright cancel anyday timer timer.enabled = 0; // ouright cancel anyday timer
} }
else { else {
DebugPort.print("Cancelling specific day idx"); DebugPort.println(activeDow); DebugPort.printf("Cancelling specific day idx %d\r\n", activeDow);
timer.enabled &= ~(0x01 << activeDow); // cancel specific day that started the timer timer.enabled &= ~(0x01 << activeDow); // cancel specific day that started the timer
} }
NVstore.setTimerInfo(ID, timer); NVstore.setTimerInfo(ID, timer);

View file

@ -35,6 +35,7 @@ char defaultJSONstr[64];
CModerator JSONmoderator; CModerator JSONmoderator;
CTimerModerator TimerModerator; CTimerModerator TimerModerator;
int timerConflict = 0; int timerConflict = 0;
CModerator MQTTmoderator;
void validateTimer(int ID); void validateTimer(int ID);
@ -43,12 +44,7 @@ void interpretJsonCommand(char* pLine)
if(strlen(pLine) == 0) if(strlen(pLine) == 0)
return; return;
DebugPort.print("JSON parse... "); DebugPort.print(pLine); DebugPort.printf("JSON parse %s...", pLine);
/* for(int i=0; i<strlen(pLine); i++) {
char msg[8];
sprintf(msg, "%02X ", pLine[i]);
DebugPort.print(msg);
}*/
StaticJsonBuffer<512> jsonBuffer; // create a JSON buffer on the heap StaticJsonBuffer<512> jsonBuffer; // create a JSON buffer on the heap
JsonObject& obj = jsonBuffer.parseObject(pLine); JsonObject& obj = jsonBuffer.parseObject(pLine);
@ -157,6 +153,38 @@ void interpretJsonCommand(char* pLine)
else if(strcmp("FanSensor", it->key) == 0) { else if(strcmp("FanSensor", it->key) == 0) {
setFanSensor(it->value.as<unsigned char>()); setFanSensor(it->value.as<unsigned char>());
} }
// MQTT parameters
else if(strcmp("MQuery", it->key) == 0) {
MQTTmoderator.reset(); // force MQTT params to be sent
}
else if(strcmp("MEn", it->key) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
info.enabled = it->value.as<unsigned char>();
NVstore.setMQTTinfo(info);
}
else if(strcmp("MPort", it->key) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
info.port = it->value.as<unsigned short>();
NVstore.setMQTTinfo(info);
}
else if(strcmp("MHost", it->key) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.host, it->value.as<const char*>(), 127);
info.host[127] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("MUser", it->key) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.username, it->value.as<const char*>(), 31);
info.username[31] = 0;
NVstore.setMQTTinfo(info);
}
else if(strcmp("MPasswd", it->key) == 0) {
sMQTTparams info = NVstore.getMQTTinfo();
strncpy(info.password, it->value.as<const char*>(), 31);
info.password[31] = 0;
NVstore.setMQTTinfo(info);
}
} }
} }
@ -259,6 +287,27 @@ bool makeJSONTimerString(int channel, char* opStr, int len)
} }
bool makeJSONStringMQTT(CModerator& moderator, char* opStr, int len)
{
StaticJsonBuffer<800> jsonBuffer; // create a JSON buffer on the stack
JsonObject& root = jsonBuffer.createObject(); // create object to add JSON commands to
bool bSend = false; // reset should send flag
const sMQTTparams& info = NVstore.getMQTTinfo();
bSend |= moderator.addJson("MEn", info.enabled, root);
bSend |= moderator.addJson("MPort", info.port, root);
bSend |= moderator.addJson("MHost", info.host, root);
bSend |= moderator.addJson("MUser", info.username, root);
bSend |= moderator.addJson("MPasswd", info.password, root);
if(bSend) {
root.printTo(opStr, len);
}
return bSend;
}
void updateJSONclients(bool report) void updateJSONclients(bool report)
{ {
@ -267,7 +316,7 @@ void updateJSONclients(bool report)
{ {
if(makeJSONString(JSONmoderator, jsonStr, sizeof(jsonStr))) { if(makeJSONString(JSONmoderator, jsonStr, sizeof(jsonStr))) {
if (report) { if (report) {
DebugPort.print("JSON send: "); DebugPort.println(jsonStr); DebugPort.printf("JSON send: %s\r\n", jsonStr);
} }
sendWebServerString( jsonStr ); sendWebServerString( jsonStr );
getBluetoothClient().send( jsonStr ); getBluetoothClient().send( jsonStr );
@ -277,7 +326,7 @@ void updateJSONclients(bool report)
{ {
if(makeJSONStringEx(JSONmoderator, jsonStr, sizeof(jsonStr))) { if(makeJSONStringEx(JSONmoderator, jsonStr, sizeof(jsonStr))) {
if (report) { if (report) {
DebugPort.print("JSON send: "); DebugPort.println(jsonStr); DebugPort.printf("JSON send: %s\r\n", jsonStr);
} }
sendWebServerString( jsonStr ); sendWebServerString( jsonStr );
getBluetoothClient().send( jsonStr ); getBluetoothClient().send( jsonStr );
@ -291,7 +340,7 @@ void updateJSONclients(bool report)
if(makeJSONTimerString(tmr, jsonStr, sizeof(jsonStr))) { if(makeJSONTimerString(tmr, jsonStr, sizeof(jsonStr))) {
unsigned long tJSON = millis() - tStart; unsigned long tJSON = millis() - tStart;
if (report) { if (report) {
DebugPort.print("JSON send: "); DebugPort.println(jsonStr); DebugPort.printf("JSON send: %s\r\n", jsonStr);
} }
tStart = millis(); tStart = millis();
sendWebServerString( jsonStr ); sendWebServerString( jsonStr );
@ -300,7 +349,7 @@ void updateJSONclients(bool report)
getBluetoothClient().send( jsonStr ); getBluetoothClient().send( jsonStr );
unsigned long tBT = millis() - tStart; unsigned long tBT = millis() - tStart;
bNewTimerInfo = true; bNewTimerInfo = true;
DebugPort.print("JSON times : "); DebugPort.print(tJSON); DebugPort.print(",");DebugPort.print(tBT); DebugPort.print(",");DebugPort.println(tWF); DebugPort.printf("JSON times : %ld,%ld,%ld\r\n", tJSON, tBT, tWF);
} }
} }
// request timer refesh upon clients // request timer refesh upon clients
@ -315,10 +364,21 @@ void updateJSONclients(bool report)
root.set("TimerRefresh", 1); root.set("TimerRefresh", 1);
root.printTo(jsonStr, 800); root.printTo(jsonStr, 800);
DebugPort.print("JSON send: "); DebugPort.println(jsonStr); DebugPort.printf("JSON send: %s\r\n", jsonStr);
sendWebServerString( jsonStr ); sendWebServerString( jsonStr );
getBluetoothClient().send( jsonStr ); getBluetoothClient().send( jsonStr );
} }
// report MQTT params
{
if(makeJSONStringMQTT(MQTTmoderator, jsonStr, sizeof(jsonStr))) {
if (report) {
DebugPort.printf("JSON send: %s\r\n", jsonStr);
}
sendWebServerString( jsonStr );
getBluetoothClient().send( jsonStr );
}
}
} }
@ -328,5 +388,10 @@ void resetJSONmoderator()
TimerModerator.reset(); TimerModerator.reset();
} }
void initMQTTJSONmoderator()
{
char jsonStr[800];
makeJSONStringMQTT(MQTTmoderator, jsonStr, sizeof(jsonStr));
}

View file

@ -31,6 +31,8 @@ bool makeJSONString(CModerator& moderator, char* opStr, int len);
bool makeJSONStringEx(CModerator& moderator, char* opStr, int len); bool makeJSONStringEx(CModerator& moderator, char* opStr, int len);
bool makeJSONTimerString(int channel, char* opStr, int len); bool makeJSONTimerString(int channel, char* opStr, int len);
void updateJSONclients(bool report); void updateJSONclients(bool report);
bool makeJSONStringMQTT(CModerator& moderator, char* opStr, int len);
void initMQTTJSONmoderator();
template<class T> template<class T>
const char* createJSON(const char* name, T value) const char* createJSON(const char* name, T value)

View file

@ -81,7 +81,7 @@ int BoardDetect()
uint8_t revision = 0; uint8_t revision = 0;
uint8_t val = preferences.getUChar("Board Revision", revision); uint8_t val = preferences.getUChar("Board Revision", revision);
if(val != 0) { if(val != 0) {
DebugPort.print("Board detect: Using saved revision V"); DebugPort.println(float(val) * 0.1f, 1); DebugPort.printf("Board detect: Using saved revision V%.1f\r\n", float(val) * 0.1f);
return val; return val;
} }
@ -117,6 +117,6 @@ int BoardDetect()
preferences.putUChar("Board Revision", revision); preferences.putUChar("Board Revision", revision);
} }
DebugPort.print("Board detect: Result = V"); DebugPort.println(float(revision)*0.1f, 1); DebugPort.printf("Board detect: Result = V%.1f\r\n", float(revision)*0.1f);
return revision; return revision;
} }

View file

@ -98,3 +98,45 @@ CTimerModerator::reset(int timer)
} }
} }
bool
CStringModerator::shouldSend(const char* name, const char* value)
{
bool retval = true;
std::string sValue = value;
auto it = Memory.find(name);
if(it != Memory.end()) {
retval = it->second != sValue;
it->second = sValue;
}
else {
Memory[name] = sValue;
}
return retval;
}
bool
CStringModerator::addJson(const char* name, const char* value, JsonObject& root)
{
bool retval;
if( retval = shouldSend(name, value) ) {
root.set(name, value);
}
return retval;
}
void
CStringModerator::reset()
{
for(auto it = Memory.begin(); it != Memory.end(); ++it) {
Memory.erase(it);
}
}
void
CStringModerator::reset(const char* name)
{
auto it = Memory.find(name);
if(it != Memory.end()) {
Memory.erase(it);
}
}

View file

@ -39,6 +39,15 @@ public:
void reset(int channel); void reset(int channel);
}; };
class CStringModerator {
std::map<const char*, std::string> Memory;
public:
bool shouldSend(const char* name, const char* value);
bool addJson(const char* name, const char* value, JsonObject& root);
void reset();
void reset(const char* name);
};
template <class T> template <class T>
class TModerator { class TModerator {
@ -79,12 +88,7 @@ template<class T>
void TModerator<T>::reset() void TModerator<T>::reset()
{ {
for(auto it = Memory.begin(); it != Memory.end(); ++it) { for(auto it = Memory.begin(); it != Memory.end(); ++it) {
if(std::is_pointer<T>::value) { it->second = it->second+100;
it->second = NULL;
}
else {
it->second = it->second+100;
}
} }
} }
@ -93,13 +97,8 @@ void TModerator<T>::reset(const char* name)
{ {
auto it = Memory.find(name); auto it = Memory.find(name);
if(it != Memory.end()) { if(it != Memory.end()) {
DebugPort.print("Resetting moderator: \""); DebugPort.print(name); DebugPort.println("\""); DebugPort.printf("Resetting moderator: \"%s\"", name);
if(std::is_pointer<T>::value) { it->second = it->second+100;
it->second = NULL;
}
else {
it->second = it->second+100;
}
} }
} }
@ -107,7 +106,7 @@ class CModerator {
TModerator<int> iModerator; TModerator<int> iModerator;
TModerator<float> fModerator; TModerator<float> fModerator;
TModerator<unsigned char> ucModerator; TModerator<unsigned char> ucModerator;
TModerator<const char*> szModerator; CStringModerator szModerator;
public: public:
// integer values // integer values
bool shouldSend(const char* name, int value) { bool shouldSend(const char* name, int value) {

View file

@ -375,6 +375,20 @@ CHeaterStorage::setHomeMenu(sHomeMenuActions val)
_calValues.Options.HomeMenu = val; _calValues.Options.HomeMenu = val;
} }
// MQTT parameter read/save
const sMQTTparams&
CHeaterStorage::getMQTTinfo() const
{
return _calValues.MQTT;
}
void
CHeaterStorage::setMQTTinfo(const sMQTTparams& info)
{
_calValues.MQTT = info;
}
/////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////
// ESP32 // ESP32
// //
@ -402,6 +416,7 @@ CESP32HeaterStorage::load()
loadTimer(i); loadTimer(i);
} }
loadUI(); loadUI();
loadMQTT();
} }
void void
@ -413,6 +428,7 @@ CESP32HeaterStorage::save()
saveTimer(i); saveTimer(i);
} }
saveUI(); saveUI();
saveMQTT();
} }
// **** MAX LENGTH is 15 for name and values **** // **** MAX LENGTH is 15 for name and values ****
@ -533,16 +549,38 @@ CESP32HeaterStorage::saveUI()
preferences.end(); preferences.end();
} }
void
CESP32HeaterStorage::loadMQTT()
{
preferences.begin("mqtt", false);
validatedLoad("enabled", _calValues.MQTT.enabled, 0, u8inBounds, 0, 1);
validatedLoad("port", _calValues.MQTT.port, 0, u16inBounds, 0, 0xffff);
preferences.getString("host", _calValues.MQTT.host, 127);
preferences.getString("username", _calValues.MQTT.username, 31);
preferences.getString("password", _calValues.MQTT.password, 31);
preferences.end();
}
void
CESP32HeaterStorage::saveMQTT()
{
preferences.begin("mqtt", false);
preferences.putUChar("enabled", _calValues.MQTT.enabled);
preferences.putUShort("port", _calValues.MQTT.port);
preferences.putString("host", _calValues.MQTT.host);
preferences.putString("username", _calValues.MQTT.username);
preferences.putString("password", _calValues.MQTT.password);
preferences.end();
}
bool bool
CESP32HeaterStorage::validatedLoad(const char* key, uint8_t& val, int defVal, std::function<bool(uint8_t, uint8_t, uint8_t)> validator, int min, int max, uint8_t mask) CESP32HeaterStorage::validatedLoad(const char* key, uint8_t& val, int defVal, std::function<bool(uint8_t, uint8_t, uint8_t)> validator, int min, int max, uint8_t mask)
{ {
val = preferences.getUChar(key, defVal); val = preferences.getUChar(key, defVal);
if(!validator(val & mask, min, max)) { if(!validator(val & mask, min, max)) {
DebugPort.print("CESP32HeaterStorage::validatedLoad<uint8_t> invalid read "); DebugPort.printf("CESP32HeaterStorage::validatedLoad<uint8_t> invalid read %s=%d", key, val);
DebugPort.print(key); DebugPort.print("="); DebugPort.print(val); DebugPort.printf(" validator(%d,%d) reset to %d\r\n", min, max, defVal);
DebugPort.print(" validator("); DebugPort.print(min); DebugPort.print(","); DebugPort.print(max); DebugPort.print(") reset to ");
DebugPort.println(defVal);
val = defVal; val = defVal;
preferences.putUChar(key, val); preferences.putUChar(key, val);
@ -557,10 +595,8 @@ CESP32HeaterStorage::validatedLoad(const char* key, int8_t& val, int defVal, std
val = preferences.getChar(key, defVal); val = preferences.getChar(key, defVal);
if(!validator(val, min, max)) { if(!validator(val, min, max)) {
DebugPort.print("CESP32HeaterStorage::validatedLoad<uint8_t> invalid read "); DebugPort.printf("CESP32HeaterStorage::validatedLoad<int8_t> invalid read %s=%d", key, val);
DebugPort.print(key); DebugPort.print("="); DebugPort.print(val); DebugPort.printf(" validator(%d,%d) reset to %d\r\n", min, max, defVal);
DebugPort.print(" validator("); DebugPort.print(min); DebugPort.print(","); DebugPort.print(max); DebugPort.print(") reset to ");
DebugPort.println(defVal);
val = defVal; val = defVal;
preferences.putChar(key, val); preferences.putChar(key, val);
@ -575,10 +611,8 @@ CESP32HeaterStorage::validatedLoad(const char* key, uint16_t& val, int defVal, s
val = preferences.getUShort(key, defVal); val = preferences.getUShort(key, defVal);
if(!validator(val, min, max)) { if(!validator(val, min, max)) {
DebugPort.print("CESP32HeaterStorage::validatedLoad<uint16_t> invalid read "); DebugPort.printf("CESP32HeaterStorage::validatedLoad<uint16_t> invalid read %s=%d", key, val);
DebugPort.print(key); DebugPort.print("="); DebugPort.print(val); DebugPort.printf(" validator(%d,%d) reset to %d\r\n", min, max, defVal);
DebugPort.print(" validator("); DebugPort.print(min); DebugPort.print(","); DebugPort.print(max); DebugPort.print(") reset to ");
DebugPort.println(defVal);
val = defVal; val = defVal;
preferences.putUShort(key, val); preferences.putUShort(key, val);
@ -593,10 +627,8 @@ CESP32HeaterStorage::validatedLoad(const char* key, long& val, long defVal, std:
val = preferences.getLong(key, defVal); val = preferences.getLong(key, defVal);
if(!validator(val, min, max)) { if(!validator(val, min, max)) {
DebugPort.print("CESP32HeaterStorage::validatedLoad<long> invalid read "); DebugPort.printf("CESP32HeaterStorage::validatedLoad<long> invalid read %s=%ld", key, val);
DebugPort.print(key); DebugPort.print("="); DebugPort.print(val); DebugPort.printf(" validator(%ld,%ld) reset to %ld\r\n", min, max, defVal);
DebugPort.print(" validator("); DebugPort.print(min); DebugPort.print(","); DebugPort.print(max); DebugPort.print(") reset to ");
DebugPort.println(defVal);
val = defVal; val = defVal;
preferences.putLong(key, val); preferences.putLong(key, val);

View file

@ -103,6 +103,31 @@ struct sCyclicThermostat {
} }
}; };
struct sMQTTparams {
uint8_t enabled;
uint16_t port;
char host[128];
char username[32];
char password[32];
void init() {
enabled = false;
port = 1234;
memset(host, 0, 128);
memset(username, 0, 32);
memset(password, 0, 32);
}
sMQTTparams& operator=(const sMQTTparams& rhs) {
enabled = rhs.enabled;
port = rhs.port;
memcpy(host, rhs.host, 128);
memcpy(username, rhs.username, 32);
memcpy(password, rhs.password, 32);
host[127] = 0;
username[31] = 0;
password[31] = 0;
}
};
struct sBTCoptions { struct sBTCoptions {
long dimTime; long dimTime;
long menuTimeout; long menuTimeout;
@ -154,6 +179,7 @@ struct sNVStore {
sHeater Heater; sHeater Heater;
sBTCoptions Options; sBTCoptions Options;
sTimer timer[14]; sTimer timer[14];
sMQTTparams MQTT;
bool valid(); bool valid();
void init(); void init();
}; };
@ -200,6 +226,7 @@ public:
unsigned char getWifiEnabled(); unsigned char getWifiEnabled();
unsigned char getOTAEnabled(); unsigned char getOTAEnabled();
const sCyclicThermostat& getCyclicMode() const; const sCyclicThermostat& getCyclicMode() const;
const sMQTTparams& getMQTTinfo() const;
GPIOinModes getGPIOinMode(); GPIOinModes getGPIOinMode();
GPIOoutModes getGPIOoutMode(); GPIOoutModes getGPIOoutMode();
GPIOalgModes getGPIOalgMode(); GPIOalgModes getGPIOalgMode();
@ -231,11 +258,12 @@ public:
void getTimerInfo(int idx, sTimer& timerInfo); void getTimerInfo(int idx, sTimer& timerInfo);
void setTimerInfo(int idx, const sTimer& timerInfo); void setTimerInfo(int idx, const sTimer& timerInfo);
void setMQTTinfo(const sMQTTparams& info);
}; };
#ifdef ESP32 //#ifdef ESP32
#include <Preferences.h> #include <Preferences.h>
#include <functional> #include <functional>
@ -254,13 +282,15 @@ public:
void saveTimer(int idx); void saveTimer(int idx);
void loadUI(); void loadUI();
void saveUI(); void saveUI();
void loadMQTT();
void saveMQTT();
bool validatedLoad(const char* key, int8_t& val, int defVal, std::function<bool(int8_t, int8_t, int8_t)> validator, int min, int max); bool validatedLoad(const char* key, int8_t& val, int defVal, std::function<bool(int8_t, int8_t, int8_t)> validator, int min, int max);
bool validatedLoad(const char* key, uint8_t& val, int defVal, std::function<bool(uint8_t, uint8_t, uint8_t)> validator, int min, int max, uint8_t mask=0xff); bool validatedLoad(const char* key, uint8_t& val, int defVal, std::function<bool(uint8_t, uint8_t, uint8_t)> validator, int min, int max, uint8_t mask=0xff);
bool validatedLoad(const char* key, uint16_t& val, int defVal, std::function<bool(uint16_t, uint16_t, uint16_t)> validator, int min, int max); bool validatedLoad(const char* key, uint16_t& val, int defVal, std::function<bool(uint16_t, uint16_t, uint16_t)> validator, int min, int max);
bool validatedLoad(const char* key, long& val, long defVal, std::function<bool(long, long, long)> validator, long min, long max); bool validatedLoad(const char* key, long& val, long defVal, std::function<bool(long, long, long)> validator, long min, long max);
}; };
#endif //#endif
extern CHeaterStorage& NVstore; extern CHeaterStorage& NVstore;

View file

@ -38,7 +38,7 @@ CommStates::set(eCS eState)
"BTC_Tx", "HeaterRx2", "HeaterValidate2", "HeaterReport2", "TemperatureRead" "BTC_Tx", "HeaterRx2", "HeaterValidate2", "HeaterReport2", "TemperatureRead"
}; };
if(_State == Idle) DebugPort.println(""); // clear screen if(_State == Idle) DebugPort.println(""); // clear screen
DebugPort.print("State:");DebugPort.println(stateNames[_State]); DebugPort.printf("State: %s\r\n", stateNames[_State]);
} }
} }

View file

@ -62,7 +62,7 @@ public:
void setDelay(int ms); void setDelay(int ms);
bool delayExpired(); bool delayExpired();
bool toggleReporting() { _report = !_report; }; bool toggleReporting() { _report = !_report; };
bool isReporting() {return _report != 0;};
}; };
@ -124,22 +124,18 @@ public:
refTime = millis(); refTime = millis();
}; };
void report(bool isDelta) { void report(bool isDelta) {
char msg[32];
if(isDelta) { if(isDelta) {
long delta = millis() - prevTime; long delta = millis() - prevTime;
sprintf(msg, "%+8ldms ", delta); DebugPort.printf("%+8ldms ", delta);
} }
else { else {
prevTime = millis(); prevTime = millis();
sprintf(msg, "%8dms ", prevTime - refTime); DebugPort.printf("%8ldms ", prevTime - refTime);
} }
DebugPort.print(msg);
}; };
void report() { void report() {
char msg[32];
prevTime = millis(); prevTime = millis();
sprintf(msg, "%8dms ", prevTime - refTime); DebugPort.printf("%8dlms ", prevTime - refTime);
DebugPort.print(msg);
}; };
}; };

View file

@ -90,7 +90,6 @@ void handleBTCRoot() {
} }
#endif #endif
void handleWMConfig() { void handleWMConfig() {
server.send(200, "text/plain", "Start Config Portal - Retaining credential"); server.send(200, "text/plain", "Start Config Portal - Retaining credential");
DebugPort.println("Starting web portal for wifi config"); DebugPort.println("Starting web portal for wifi config");
@ -138,6 +137,8 @@ void handleBTCNotFound() {
digitalWrite(led, 0); digitalWrite(led, 0);
} }
const char* serverIndex = "<form method='POST' action='/updatenow' enctype='multipart/form-data'><input type='file' name='update'><input type='submit' value='Update'></form>";
void initWebServer(void) { void initWebServer(void) {
@ -150,6 +151,44 @@ void initWebServer(void) {
server.on("/wmconfig", handleWMConfig); server.on("/wmconfig", handleWMConfig);
server.on("/resetwifi", handleReset); server.on("/resetwifi", handleReset);
server.on("/formatspiffs", handleFormat); server.on("/formatspiffs", handleFormat);
// magical code shaemlessly lifted from Arduino WebUpdate example, slightly modified in paths
// this allows pushing new firmware to the ESP via OTA from a WEB BROWSER!
//
// Initial launch page
server.on("/update", HTTP_GET, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/html", serverIndex);
});
// actual guts that manages the new firmware upload
server.on("/updatenow", HTTP_POST, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
ESP.restart();
}, []() {
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
DebugPort.setDebugOutput(true);
DebugPort.printf("Update: %s\n", upload.filename.c_str());
if (!Update.begin()) { //start with max available size
Update.printError(DebugPort);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
Update.printError(DebugPort);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { //true to set the size to the current progress
DebugPort.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
} else {
Update.printError(DebugPort);
}
DebugPort.setDebugOutput(false);
} else {
DebugPort.printf("Update Failed Unexpectedly (likely broken connection): status=%d\n", upload.status);
}
});
#if USE_SPIFFS == 1 #if USE_SPIFFS == 1
// NOTE: this serves the default home page, and favicon.ico // NOTE: this serves the default home page, and favicon.ico
server.onNotFound([]() server.onNotFound([]()
@ -199,7 +238,7 @@ bool sendWebServerString(const char* Str)
bTxWebData = true; // OLED tx data animation flag bTxWebData = true; // OLED tx data animation flag
webSocket.broadcastTXT(Str); webSocket.broadcastTXT(Str);
unsigned long tWeb = millis() - tStart; unsigned long tWeb = millis() - tStart;
// DebugPort.print("Websend times : "); DebugPort.print(tCon); DebugPort.print(","); DebugPort.println(tWeb); // DebugPort.printf("Websend times : %ld,%ld\r\n", tCon, tWeb);
return true; return true;
} }
return false; return false;

View file

@ -35,6 +35,7 @@
#include <WiFiClient.h> #include <WiFiClient.h>
#include <WebServer.h> #include <WebServer.h>
#include <ESPmDNS.h> #include <ESPmDNS.h>
#include <Update.h>
#include <WebSocketsServer.h> #include <WebSocketsServer.h>

View file

@ -59,10 +59,10 @@ bool initWifi(int initpin,const char *failedssid, const char *failedpassword)
uint8_t MAC[6]; uint8_t MAC[6];
esp_read_mac(MAC, ESP_MAC_WIFI_STA); esp_read_mac(MAC, ESP_MAC_WIFI_STA);
sprintf(MACstr[0], "%02X:%02X:%02X:%02X:%02X:%02X", MAC[0], MAC[1], MAC[2], MAC[3], MAC[4], MAC[5]); sprintf(MACstr[0], "%02X:%02X:%02X:%02X:%02X:%02X", MAC[0], MAC[1], MAC[2], MAC[3], MAC[4], MAC[5]);
DebugPort.print(" STA MAC address: "); DebugPort.println(MACstr[0]); DebugPort.printf(" STA MAC address: %s\r\n", MACstr[0]);
esp_read_mac(MAC, ESP_MAC_WIFI_SOFTAP); esp_read_mac(MAC, ESP_MAC_WIFI_SOFTAP);
sprintf(MACstr[1], "%02X:%02X:%02X:%02X:%02X:%02X", MAC[0], MAC[1], MAC[2], MAC[3], MAC[4], MAC[5]); sprintf(MACstr[1], "%02X:%02X:%02X:%02X:%02X:%02X", MAC[0], MAC[1], MAC[2], MAC[3], MAC[4], MAC[5]);
DebugPort.print(" AP MAC address: "); DebugPort.println(MACstr[1]); DebugPort.printf(" AP MAC address: %s\r\n", MACstr[1]);
char APname[32]; char APname[32];
sprintf(APname, "%s", failedssid); sprintf(APname, "%s", failedssid);
@ -99,7 +99,7 @@ bool initWifi(int initpin,const char *failedssid, const char *failedpassword)
// bool res = wm.autoConnect(failedssid, failedpassword); // auto generated AP name from chipid // bool res = wm.autoConnect(failedssid, failedpassword); // auto generated AP name from chipid
bool res = wm.autoConnect(APname, failedpassword); // auto generated AP name from chipid bool res = wm.autoConnect(APname, failedpassword); // auto generated AP name from chipid
DebugPort.print("WifiMode after autoConnect = "); DebugPort.println(WiFi.getMode()); DebugPort.printf("WifiMode after autoConnect = "); DebugPort.println(WiFi.getMode());
int chnl = 1; int chnl = 1;
bool retval = false; bool retval = false;
@ -113,10 +113,10 @@ bool initWifi(int initpin,const char *failedssid, const char *failedpassword)
// if you get here you have connected to the WiFi // if you get here you have connected to the WiFi
isSTA = true; isSTA = true;
DebugPort.println("WiFiManager connected in STA mode OK"); DebugPort.println("WiFiManager connected in STA mode OK");
DebugPort.print(" STA IP address: "); DebugPort.println(WiFi.localIP()); DebugPort.printf(" STA IP address: %s\r\n", WiFi.localIP());
// must use same radio channel as STA to go to STA+AP, otherwise we drop the STA! // must use same radio channel as STA to go to STA+AP, otherwise we drop the STA!
chnl = WiFi.channel(); chnl = WiFi.channel();
DebugPort.print("Now promoting to STA+AP mode"); DebugPort.println("Now promoting to STA+AP mode...");
retval = true; retval = true;
} }
#ifdef USE_AP #ifdef USE_AP
@ -127,9 +127,9 @@ bool initWifi(int initpin,const char *failedssid, const char *failedpassword)
// WiFi.softAP(failedssid, failedpassword, chnl); // WiFi.softAP(failedssid, failedpassword, chnl);
WiFi.softAP(APname, failedpassword, chnl); WiFi.softAP(APname, failedpassword, chnl);
WiFi.enableAP(true); WiFi.enableAP(true);
DebugPort.print(" AP SSID: "); DebugPort.println(WiFi.softAPgetHostname()); DebugPort.printf(" AP SSID: %s\r\n", WiFi.softAPgetHostname());
DebugPort.print(" AP IP address: "); DebugPort.println(WiFi.softAPIP()); DebugPort.printf(" AP IP address: %s\r\n", WiFi.softAPIP());
DebugPort.print("WifiMode after initWifi = "); DebugPort.println(WiFi.getMode()); DebugPort.printf("WifiMode after initWifi = %d\r\n", WiFi.getMode());
#endif #endif
// even though we may have started in STA mode - start the config portal if demanded via the NV flag // even though we may have started in STA mode - start the config portal if demanded via the NV flag
@ -177,7 +177,7 @@ void doWiFiManager()
if(pinDown) { if(pinDown) {
pinDown = false; pinDown = false;
tDelta = millis() - pinTime; tDelta = millis() - pinTime;
DebugPort.print("Wifi config button tDelta = "); DebugPort.println(tDelta); DebugPort.printf("Wifi config button tDelta = %ld\r\n", tDelta);
// > 5 second press? // > 5 second press?
if(tDelta > 5000) { if(tDelta > 5000) {
wifiEnterConfigPortal(true, true); // very long press - clear credentials, reboot into portal wifiEnterConfigPortal(true, true); // very long press - clear credentials, reboot into portal
@ -311,7 +311,7 @@ void prepBootIntoConfigPortal(bool state)
NV.begin("user"); NV.begin("user");
NV.putBool("bootPortal", state); NV.putBool("bootPortal", state);
NV.end(); NV.end();
DebugPort.print("Setting boot config portal if WiFiManager fails = "); DebugPort.println(state); DebugPort.printf("Setting boot config portal if WiFiManager fails = %d\r\n", state);
} }
// test the NV flag whether the config portal should run after reboot // test the NV flag whether the config portal should run after reboot
@ -321,7 +321,7 @@ bool shouldBootIntoConfigPortal()
NV.begin("user"); NV.begin("user");
bool retval = NV.getBool("bootPortal", false); bool retval = NV.getBool("bootPortal", false);
NV.end(); NV.end();
DebugPort.print("Boot config portal if WiFiManager fails = "); DebugPort.println(retval); DebugPort.printf("Boot config portal if WiFiManager fails = %d\r\n", retval);
return retval; return retval;
} }

Binary file not shown.