escape json and adding verbose debug

This commit is contained in:
Robert van den Breemen 2021-03-24 21:12:58 +01:00
parent a34784ca25
commit 8bcd31c715
8 changed files with 151 additions and 58 deletions

View File

@ -10,6 +10,13 @@
***************************************************************************
*/
#define MQTTDebugTln(...) ({ if (bDebugMQTT) DebugTln(__VA_ARGS__); })
#define MQTTDebugln(...) ({ if (bDebugMQTT) Debugln(__VA_ARGS__); })
#define MQTTDebugTf(...) ({ if (bDebugMQTT) DebugTf(__VA_ARGS__); })
#define MQTTDebugf(...) ({ if (bDebugMQTT) Debugf(__VA_ARGS__); })
#define MQTTDebugT(...) ({ if (bDebugMQTT) DebugT(__VA_ARGS__); })
#define MQTTDebug(...) ({ if (bDebugMQTT) Debug(__VA_ARGS__); })
// Declare some variables within global scope
static IPAddress MQTTbrokerIP;
@ -46,12 +53,13 @@ void startMQTT()
// handles MQTT subscribe incoming stuff
void handleMQTTcallback(char* topic, byte* payload, unsigned int length) {
DebugT("Message arrived on topic ["); Debug(topic); Debug("] = [");
for (int i = 0; i < length; i++) {
Debug((char)payload[i]);
}
Debug("] ("); Debug(length); Debug(")"); Debugln();
if (bDebugMQTT) {
DebugT("Message arrived on topic ["); Debug(topic); Debug("] = [");
for (int i = 0; i < length; i++) {
Debug((char)payload[i]);
}
Debug("] ("); Debug(length); Debug(")"); Debugln();
}
char subscribeTopic[100];
// naming convention <mqtt top>/set/<node id>/<command>
snprintf(subscribeTopic, sizeof(subscribeTopic), "%s/", MQTTSubNamespace.c_str());
@ -71,26 +79,33 @@ void handleMQTT()
DECLARE_TIMER_MIN(timerMQTTwaitforconnect, 10, CATCH_UP_MISSED_TICKS); // 10 minutes
DECLARE_TIMER_SEC(timerMQTTwaitforretry, 3, CATCH_UP_MISSED_TICKS); // 3 seconds backoff
//State debug timers
DECLARE_TIMER_SEC(timerMQTTwaitforreconnect, 30);
DECLARE_TIMER_SEC(timerMQTTerrorstate, 30);
DECLARE_TIMER_SEC(timerMQTTwaitconnectionattempt, 1);
DECLARE_TIMER_SEC(timerMQTTisconnected, 60);
switch(stateMQTT)
{
case MQTT_STATE_INIT:
DebugTln(F("MQTT State: MQTT Initializing"));
MQTTDebugTln(F("MQTT State: MQTT Initializing"));
WiFi.hostByName(CSTR(settingMQTTbroker), MQTTbrokerIP); // lookup the MQTTbroker convert to IP
sprintf(MQTTbrokerIPchar, "%d.%d.%d.%d", MQTTbrokerIP[0], MQTTbrokerIP[1], MQTTbrokerIP[2], MQTTbrokerIP[3]);
if (isValidIP(MQTTbrokerIP))
{
DebugTf("[%s] => setServer(%s, %d)\r\n", CSTR(settingMQTTbroker), MQTTbrokerIPchar, settingMQTTbrokerPort);
MQTTDebugTf("[%s] => setServer(%s, %d)\r\n", CSTR(settingMQTTbroker), MQTTbrokerIPchar, settingMQTTbrokerPort);
MQTTclient.disconnect();
MQTTclient.setServer(MQTTbrokerIPchar, settingMQTTbrokerPort);
MQTTclient.setCallback(handleMQTTcallback);
MQTTclient.setSocketTimeout(4);
MQTTclientId = String(_HOSTNAME) + WiFi.macAddress();
//skip try to connect
reconnectAttempts =0;
stateMQTT = MQTT_STATE_TRY_TO_CONNECT;
}
else
{ // invalid IP, then goto error state
DebugTf("ERROR: [%s] => is not a valid URL\r\n", CSTR(settingMQTTbroker));
MQTTDebugTf("ERROR: [%s] => is not a valid URL\r\n", CSTR(settingMQTTbroker));
stateMQTT = MQTT_STATE_ERROR;
//DebugTln(F("Next State: MQTT_STATE_ERROR"));
}
@ -98,21 +113,21 @@ void handleMQTT()
break;
case MQTT_STATE_TRY_TO_CONNECT:
DebugTln(F("MQTT State: MQTT try to connect"));
//DebugTf("MQTT server is [%s], IP[%s]\r\n", settingMQTTbroker.c_str(), MQTTbrokerIPchar);
MQTTDebugTln(F("MQTT State: MQTT try to connect"));
MQTTDebugTf("MQTT server is [%s], IP[%s]\r\n", settingMQTTbroker.c_str(), MQTTbrokerIPchar);
DebugT(F("Attempting MQTT connection .. "));
MQTTDebugT(F("Attempting MQTT connection .. "));
reconnectAttempts++;
//If no username, then anonymous connection to broker, otherwise assume username/password.
if (settingMQTTuser.length() == 0)
{
Debug(F("without a Username/Password "));
MQTTDebug(F("without a Username/Password "));
MQTTclient.connect(CSTR(MQTTclientId), CSTR(MQTTPubNamespace), 0, true, "offline");
}
else
{
Debugf("Username [%s] ", CSTR(settingMQTTuser));
MQTTDebugf("Username [%s] ", CSTR(settingMQTTuser));
MQTTclient.connect(CSTR(MQTTclientId), CSTR(settingMQTTuser), CSTR(settingMQTTpasswd), CSTR(MQTTPubNamespace), 0, true, "offline");
}
@ -120,9 +135,9 @@ void handleMQTT()
if (MQTTclient.connected())
{
reconnectAttempts = 0;
Debugln(F(" .. connected\r"));DebugFlush();
Debugln(F(" .. connected\r"));
stateMQTT = MQTT_STATE_IS_CONNECTED;
//DebugTln(F("Next State: MQTT_STATE_IS_CONNECTED"));
MQTTDebugTln(F("Next State: MQTT_STATE_IS_CONNECTED"));
// birth message, sendMQTT retains by default
sendMQTT(CSTR(MQTTPubNamespace), "online");
//First do AutoConfiguration for Homeassistant
@ -131,38 +146,37 @@ void handleMQTT()
char topic[100];
strcpy(topic, CSTR(MQTTSubNamespace));
strlcat(topic, "/#", sizeof(topic));
DebugTf("Subscribe to MQTT: TopicId [%s]\r\n", topic);
MQTTDebugTf("Subscribe to MQTT: TopicId [%s]\r\n", topic);
if (MQTTclient.subscribe(topic)){
DebugTf("MQTT: Subscribed successfully to TopicId [%s]\r\n", topic);
MQTTDebugTf("MQTT: Subscribed successfully to TopicId [%s]\r\n", topic);
}
else
{
DebugTf("MQTT: Subscribe TopicId [%s] FAILED! \r\n", topic);
MQTTDebugTf("MQTT: Subscribe TopicId [%s] FAILED! \r\n", topic);
}
DebugFlush();
sendMQTTversioninfo();
}
else
{ // no connection, try again, do a non-blocking wait for 3 seconds.
Debugln(F(" .. \r"));
DebugTf("failed, retrycount=[%d], rc=[%d] .. try again in 3 seconds\r\n", reconnectAttempts, MQTTclient.state());
MQTTDebugln(F(" .. \r"));
MQTTDebugTf("failed, retrycount=[%d], rc=[%d] .. try again in 3 seconds\r\n", reconnectAttempts, MQTTclient.state());
RESTART_TIMER(timerMQTTwaitforretry);
stateMQTT = MQTT_STATE_WAIT_CONNECTION_ATTEMPT; // if the re-connect did not work, then return to wait for reconnect
//DebugTln(F("Next State: MQTT_STATE_WAIT_CONNECTION_ATTEMPT"));
MQTTDebugTln(F("Next State: MQTT_STATE_WAIT_CONNECTION_ATTEMPT"));
}
//After 5 attempts... go wait for a while.
if (reconnectAttempts >= 5)
{
DebugTln(F("5 attempts have failed. Retry wait for next reconnect in 10 minutes\r"));
MQTTDebugTln(F("5 attempts have failed. Retry wait for next reconnect in 10 minutes\r"));
RESTART_TIMER(timerMQTTwaitforconnect);
stateMQTT = MQTT_STATE_WAIT_FOR_RECONNECT; // if the re-connect did not work, then return to wait for reconnect
//DebugTln(F("Next State: MQTT_STATE_WAIT_FOR_RECONNECT"));
MQTTDebugTln(F("Next State: MQTT_STATE_WAIT_FOR_RECONNECT"));
}
break;
case MQTT_STATE_IS_CONNECTED:
//if (bDebugMQTT) DebugTln(F("MQTT State: MQTT is Connected"));
if ((bDebugMQTT) && DUE(timerMQTTisconnected)) DebugTln(F("MQTT State: MQTT is Connected"));
if (MQTTclient.connected())
{ //if the MQTT client is connected, then please do a .loop call...
MQTTclient.loop();
@ -171,47 +185,47 @@ void handleMQTT()
{ //else go and wait 10 minutes, before trying again.
RESTART_TIMER(timerMQTTwaitforconnect);
stateMQTT = MQTT_STATE_WAIT_FOR_RECONNECT;
//DebugTln(F("Next State: MQTT_STATE_WAIT_FOR_RECONNECT"));
MQTTDebugTln(F("Next State: MQTT_STATE_WAIT_FOR_RECONNECT"));
}
break;
case MQTT_STATE_WAIT_CONNECTION_ATTEMPT:
//do non-blocking wait for 3 seconds
//DebugTln(F("MQTT State: MQTT_WAIT_CONNECTION_ATTEMPT"));
if ((bDebugMQTT) && DUE(timerMQTTwaitconnectionattempt)) DebugTln(F("MQTT State: MQTT_WAIT_CONNECTION_ATTEMPT"));
if (DUE(timerMQTTwaitforretry))
{
//Try again... after waitforretry non-blocking delay
stateMQTT = MQTT_STATE_TRY_TO_CONNECT;
//DebugTln(F("Next State: MQTT_STATE_TRY_TO_CONNECT"));
MQTTDebugTln(F("Next State: MQTT_STATE_TRY_TO_CONNECT"));
}
break;
case MQTT_STATE_WAIT_FOR_RECONNECT:
//do non-blocking wait for 10 minutes, then try to connect again.
if (bDebugMQTT) DebugTln(F("MQTT State: MQTT wait for reconnect"));
if (DUE(timerMQTTwaitforconnect))
if ((bDebugMQTT) && DUE(timerMQTTwaitforreconnect)) DebugTln(F("MQTT State: MQTT wait for reconnect"));
if (DUE(timerMQTTwaitforreconnect))
{
//remember when you tried last time to reconnect
RESTART_TIMER(timerMQTTwaitforretry);
reconnectAttempts = 0;
stateMQTT = MQTT_STATE_TRY_TO_CONNECT;
//DebugTln(F("Next State: MQTT_STATE_TRY_TO_CONNECT"));
MQTTDebugTln(F("Next State: MQTT_STATE_TRY_TO_CONNECT"));
}
break;
case MQTT_STATE_ERROR:
DebugTln(F("MQTT State: MQTT ERROR, wait for 10 minutes, before trying again"));
if ((bDebugMQTT) && DUE(timerMQTTerrorstate)) DebugTln(F("MQTT State: MQTT ERROR, wait for 10 minutes, before trying again"));
//next retry in 10 minutes.
RESTART_TIMER(timerMQTTwaitforconnect);
stateMQTT = MQTT_STATE_WAIT_FOR_RECONNECT;
//DebugTln(F("Next State: MQTT_STATE_WAIT_FOR_RECONNECT"));
MQTTDebugTln(F("Next State: MQTT_STATE_WAIT_FOR_RECONNECT"));
break;
default:
DebugTln(F("MQTT State: default, this should NEVER happen!"));
MQTTDebugTln(F("MQTT State: default, this should NEVER happen!"));
//do nothing, this state should not happen
stateMQTT = MQTT_STATE_INIT;
//DebugTln(F("Next State: MQTT_STATE_INIT"));
DebugTln(F("Next State: MQTT_STATE_INIT"));
break;
}
statusMQTTconnection = MQTTclient.connected();
@ -245,11 +259,11 @@ void sendMQTTData(const char* topic, const char *json, const bool retain = false
{
if (!settingMQTTenable) return;
if (!MQTTclient.connected() || !isValidIP(MQTTbrokerIP)) return;
// DebugTf("Sending data to MQTT server [%s]:[%d]\r\n", settingMQTTbroker.c_str(), settingMQTTbrokerPort);
MQTTDebugTf("Sending data to MQTT server [%s]:[%d]\r\n", settingMQTTbroker.c_str(), settingMQTTbrokerPort);
char full_topic[100];
snprintf(full_topic, sizeof(full_topic), "%s/", CSTR(MQTTPubNamespace));
strlcat(full_topic, topic, sizeof(full_topic));
//DebugTf("Sending MQTT: TopicId [%s] Message [%s]\r\n", full_topic, json);
MQTTDebugTf("Sending MQTT: TopicId [%s] Message [%s]\r\n", full_topic, json);
if (!MQTTclient.publish(full_topic, json, retain)) DebugTln("MQTT publish failed.");
feedWatchDog();//feed the dog
} // sendMQTTData()
@ -268,8 +282,8 @@ void sendMQTT(const char* topic, const char *json, const size_t len)
{
if (!settingMQTTenable) return;
if (!MQTTclient.connected() || !isValidIP(MQTTbrokerIP)) return;
//DebugTf("Sending data to MQTT server [%s]:[%d] ", settingMQTTbroker.c_str(), settingMQTTbrokerPort);
//DebugTf("Sending MQTT: TopicId [%s] Message [%s]\r\n", topic, json);
MQTTDebugTf("Sending data to MQTT server [%s]:[%d] ", settingMQTTbroker.c_str(), settingMQTTbrokerPort);
MQTTDebugTf("Sending MQTT: TopicId [%s] Message [%s]\r\n", topic, json);
if (MQTTclient.getBufferSize() < len) MQTTclient.setBufferSize(len); //resize buffer when needed
if (MQTTclient.beginPublish(topic, len, true)){
@ -337,15 +351,15 @@ void doAutoConfigure(){
if (splitString(sLine, ',', sTopic, sMsg))
{
// discovery topic prefix
DebugTf("sTopic[%s]==>", CSTR(sTopic));
MQTTDebugTf("sTopic[%s]==>", CSTR(sTopic));
sTopic.replace("%homeassistant%", CSTR(settingMQTThaprefix));
/// node
sTopic.replace("%node_id%", CSTR(NodeId));
Debugf("[%s]\r\n", CSTR(sTopic));
MQTTDebugf("[%s]\r\n", CSTR(sTopic));
/// ----------------------
DebugTf("sMsg[%s]==>", CSTR(sMsg));
MQTTDebugTf("sMsg[%s]==>", CSTR(sMsg));
/// node
sMsg.replace("%node_id%", CSTR(NodeId));
@ -368,7 +382,7 @@ void doAutoConfigure(){
sendMQTT(sTopic, sMsg);
resetMQTTBufferSize();
delay(10);
} else DebugTf("Either comment or invalid config line: [%s]\r\n", CSTR(sLine));
} else MQTTDebugTf("Either comment or invalid config line: [%s]\r\n", CSTR(sLine));
} // while available()
fh.close();

View File

@ -80,7 +80,7 @@ String settingHostname = _HOSTNAME;
//MQTT settings
bool statusMQTTconnection = false;
bool settingMQTTenable = false;
bool settingMQTTenable = true;
bool settingMQTTsecure = false;
String settingMQTTbroker= "192.168.88.254";
int16_t settingMQTTbrokerPort = 1883;
@ -100,12 +100,12 @@ int16_t settingGPIOSENSORSinterval = 5;
// Boot commands
bool settingOTGWcommandenable = false;
String settingOTGWcommands = "GW=1\r\nAA=28\r\n";
String settingOTGWcommands = "";
//debug flags
bool bDebugOTmsg = true;
bool bDebugRestAPI = false;
bool bDebugMQTT = false;
bool bDebugMQTT = true;
//Now load network suff
#include "networkStuff.h"

View File

@ -1 +1 @@
eb7ff52
a34784c

View File

@ -8,7 +8,22 @@ void handleDebug(){
DebugTln("Configure MQTT Discovery");
DebugTf("Enable MQTT: %s", CBOOLEAN(settingMQTTenable));
doAutoConfigure();
break;
break;
case 'r':
if (WiFi.status() != WL_CONNECTED)
{
DebugTln("Reconnecting to wifi");
startWiFi(_HOSTNAME, 240);
//check OTGW and telnet
startTelnet();
startOTGWstream();
} else DebugTln("Wifi is connected");
if (!statusMQTTconnection) {
DebugTln("Reconnecting MQTT");
startMQTT();
} else DebugTln("MQTT is connected");
break;
case '1': bDebugOTmsg = !bDebugOTmsg; DebugTf("\r\nDebug OTmsg: %s\r\n", CBOOLEAN(bDebugOTmsg)); break;
case '2': bDebugRestAPI = !bDebugRestAPI; DebugTf("\r\nDebug RestAPI: %s\r\n", CBOOLEAN(bDebugRestAPI)); break;
case '3': bDebugMQTT = !bDebugMQTT; DebugTf("\r\nDebug MQTT: %s\r\n", CBOOLEAN(bDebugMQTT)); break;

View File

@ -593,6 +593,64 @@ bool checklittlefshash(){
}
return false;
}
/*
** Does not generate hex character constants.
** Always generates triple-digit octal constants.
** Always generates escapes in preference to octal.
** Escape question mark to ensure no trigraphs are generated by repetitive use.
** Handling of 0x80..0xFF is locale-dependent (might be octal, might be literal).
*/
void chr_cstrlit(unsigned char u, char *buffer, size_t buflen)
{
if (buflen < 2)
*buffer = '\0';
else if (isprint(u) && u != '\'' && u != '\"' && u != '\\' && u != '\?')
sprintf(buffer, "%c", u);
else if (buflen < 3)
*buffer = '\0';
else
{
switch (u)
{
case '\a': strcpy(buffer, "\\a"); break;
case '\b': strcpy(buffer, "\\b"); break;
case '\f': strcpy(buffer, "\\f"); break;
case '\n': strcpy(buffer, "\\n"); break;
case '\r': strcpy(buffer, "\\r"); break;
case '\t': strcpy(buffer, "\\t"); break;
case '\v': strcpy(buffer, "\\v"); break;
case '\\': strcpy(buffer, "\\\\"); break;
case '\'': strcpy(buffer, "\\'"); break;
case '\"': strcpy(buffer, "\\\""); break;
case '\?': strcpy(buffer, "\\\?"); break;
default:
if (buflen < 5)
*buffer = '\0';
else
sprintf(buffer, "\\%03o", u);
break;
}
}
}
void str_cstrlit(const char *str, char *buffer, size_t buflen)
{
unsigned char u;
size_t len;
while ((u = (unsigned char)*str++) != '\0')
{
chr_cstrlit(u, buffer, buflen);
if ((len = strlen(buffer)) == 0)
return;
buffer += len;
buflen -= len;
}
*buffer = '\0';
}
/***************************************************************************
*
* Permission is hereby granted, free of charge, to any person obtaining a

View File

@ -278,10 +278,13 @@ void sendJsonSettingObj(const char *cName, int iValue, const char *iType, int mi
//=======================================================================
void sendJsonSettingObj(const char *cName, const char *cValue, const char *sType, int maxLen)
{
char jsonBuff[200] = "";
char jsonBuff[200] = {0};
char buffer[100] = {0};
str_cstrlit(cValue, buffer, sizeof(buffer));
snprintf(jsonBuff, sizeof(jsonBuff), "{\"name\": \"%s\", \"value\":\"%s\", \"type\": \"%s\", \"maxlen\": %d}"
, cName, cValue, sType, maxLen);

View File

@ -104,13 +104,16 @@ void readSettings(bool show)
settingGPIOSENSORSinterval = doc["GPIOSENSORSinterval"] | settingGPIOSENSORSinterval;
settingOTGWcommandenable = doc["OTGWcommandenable"] | settingOTGWcommandenable;
settingOTGWcommands = doc["OTGWcommands"].as<String>();
//if (settingOTGWcommands=="null") settingOTGWcommands = "GW=1\r\nAA=28\r\n";
if (settingOTGWcommands=="null") settingOTGWcommands = "";
// Close the file (Curiously, File's destructor doesn't close the file)
file.close();
//Update some settings right now
MDNS.setHostname(CSTR(settingHostname)); // start advertising with new(?) settingHostname
//Resetart MQTT connection every "save settings"
startMQTT();
DebugTln(F(" .. done\r\n"));

View File

@ -2,15 +2,15 @@
#define _VERSION_MAJOR 0
#define _VERSION_MINOR 8
#define _VERSION_PATCH 2
#define _VERSION_BUILD 898
#define _VERSION_GITHASH "9d3feab"
#define _VERSION_BUILD 920
#define _VERSION_GITHASH "a34784c"
#define _VERSION_PRERELEASE beta
#define _VERSION_DATE "24-03-2021"
#define _VERSION_TIME "00:02:46"
#define _VERSION_TIME "19:42:29"
#define _SEMVER_CORE "0.8.2"
#define _SEMVER_BUILD "0.8.2+898"
#define _SEMVER_GITHASH "0.8.2+9d3feab"
#define _SEMVER_FULL "0.8.2-beta+9d3feab"
#define _SEMVER_BUILD "0.8.2+920"
#define _SEMVER_GITHASH "0.8.2+a34784c"
#define _SEMVER_FULL "0.8.2-beta+a34784c"
#define _SEMVER_NOBUILD "0.8.2-beta (24-03-2021)"
#define _VERSION "0.8.2-beta+9d3feab (24-03-2021)"
#define _VERSION "0.8.2-beta+a34784c (24-03-2021)"
//The version information is created automatically, more information here: https://github.com/rvdbreemen/autoinc-semver