Adding a MQTT set commands to firmware

Replacing the original MQTT command with a MQTT handler for set that can handle a number of commands and then translates and transmits the commands to OTGW serial device.
This commit is contained in:
Robert van den Breemen 2021-11-28 13:06:25 +01:00
parent 34a8070ac3
commit bbe0fa819a
3 changed files with 198 additions and 33 deletions

View File

@ -19,23 +19,70 @@
// Declare some variables within global scope
static IPAddress MQTTbrokerIP;
static char MQTTbrokerIPchar[20];
#include <PubSubClient.h> // MQTT client publish and subscribe functionality
static IPAddress MQTTbrokerIP;
static char MQTTbrokerIPchar[20];
static PubSubClient MQTTclient(wifiClient);
#include <PubSubClient.h> // MQTT client publish and subscribe functionality
int8_t reconnectAttempts = 0;
char lastMQTTtimestamp[15] = "";
static PubSubClient MQTTclient(wifiClient);
enum states_of_MQTT { MQTT_STATE_INIT, MQTT_STATE_TRY_TO_CONNECT, MQTT_STATE_IS_CONNECTED, MQTT_STATE_WAIT_CONNECTION_ATTEMPT, MQTT_STATE_WAIT_FOR_RECONNECT, MQTT_STATE_ERROR };
enum states_of_MQTT stateMQTT = MQTT_STATE_INIT;
int8_t reconnectAttempts = 0;
char lastMQTTtimestamp[15] = "";
enum states_of_MQTT { MQTT_STATE_INIT, MQTT_STATE_TRY_TO_CONNECT, MQTT_STATE_IS_CONNECTED, MQTT_STATE_WAIT_CONNECTION_ATTEMPT, MQTT_STATE_WAIT_FOR_RECONNECT, MQTT_STATE_ERROR };
enum states_of_MQTT stateMQTT = MQTT_STATE_INIT;
String MQTTclientId;
String MQTTPubNamespace = "";
String MQTTSubNamespace = "";
String NodeId = "";
//set command list
struct MQTT_set_cmd_t
{
char* setcmd;
char* otgwcmd;
char* ottype;
};
const MQTT_set_cmd_t setcmds[] {
{ "command", "", "raw" },
{ "setpoint", "TT", "temp" },
{ "constant", "TC", "temp" },
{ "outside", "OT", "temp" },
{ "hotwater", "HW", "on" },
{ "gatewaymode", "GW", "on" },
{ "setback", "SB", "temp" },
{ "maxchsetpt", "SH", "temp" },
{ "maxdhwsetpt", "SW", "temp" },
{ "maxmodulation", "MM", "level" },
{ "ctrlsetpt", "CS", "temp" },
{ "ctrlsetpt2", "C2", "temp" },
{ "chenable", "CH", "on" },
{ "chenable2", "H2", "on" },
{ "ventsetpt", "VS", "level" },
{ "temperaturesensor", "TS", "function" },
{ "addalternative", "AA", "function" },
{ "delalternative", "DA", "function" },
{ "unknownid", "UI", "function" },
{ "knownid", "KI", "function" },
{ "priomsg", "PM", "function" },
{ "setresponse", "SR", "function" },
{ "clearrespons", "CR", "function" },
{ "resetcounter", "RS", "function" },
{ "ignoretransitations", "IT", "function" },
{ "overridehb", "OH", "function" },
{ "forcethermostat", "FT", "function" },
{ "voltageref", "VR", "function" },
{ "debugptr", "DP", "function" },
} ;
const int nrcmds = sizeof(setcmds) / sizeof(setcmds[0]);
// const char learnmsg[] { "LA", "PR=L", "LB", "PR=L", "LC", "PR=L", "LD", "PR=L", "LE", "PR=L", "LF", "PR=L", "GA", "PR=G", "GB", "PR=G", "VR", "PR=V", "GW", "PR=M", "IT", "PR=T", "SB", "PR=S", "HW", "PR=W" } ;
// const int nrlearnmsg = sizeof(learnmsg) / sizeof(learnmsg[0]);
String MQTTclientId;
String MQTTPubNamespace = "";
String MQTTSubNamespace = "";
String NodeId = "";
//===========================================================================================
void startMQTT()
{
@ -60,16 +107,7 @@ void handleMQTTcallback(char* topic, byte* payload, unsigned int length) {
}
Debug("] ("); Debug(length); Debug(")"); Debugln();
}
char subscribeTopic[100];
// naming convention <mqtt top>/set/<node id>/<command>
snprintf(subscribeTopic, sizeof(subscribeTopic), "%s/", MQTTSubNamespace.c_str());
strlcat(subscribeTopic, OTGW_COMMAND_TOPIC, sizeof(subscribeTopic));
//what is the incoming message?
if (stricmp(topic, subscribeTopic) == 0)
{
//incoming command to be forwarded to OTGW
addOTWGcmdtoqueue((char *)payload, length, false);
}
//detect home assistant going down...
char msgPayload[50];
int msglen = min((int)(length)+1, (int)sizeof(msgPayload));
@ -87,6 +125,52 @@ void handleMQTTcallback(char* topic, byte* payload, unsigned int length) {
DebugTf("Home Assistant Status=[%s]\r\n", msgPayload);
}
}
// parse the incoming topic and execute commands
char* token;
char otgwcmd[20]={0};
// naming convention <mqtt top>/set/<node id>/<command>
token = strtok(topic, "/");
MQTTDebugT("Parsing topic: ");
MQTTDebugf("%s/", token);
if (stricmp(token, CSTR(settingMQTTtopTopic)) == 0) {
token = strtok(NULL, "/");
MQTTDebugf("%s/", token);
if (stricmp(token, "set") == 0) {
token = strtok(NULL, "/");
MQTTDebugf("%s/", token);
if (stricmp(token, CSTR(NodeId)) == 0) {
token = strtok(NULL, "/");
MQTTDebugf("%s", token);
if (token != NULL){
//loop thru command list
int i;
for (i=0; i<nrcmds; i++){
if (stricmp(token, setcmds[i].setcmd) == 0){
//found a match
if (setcmds[i].ottype == "raw"){
//raw command
snprintf(otgwcmd, sizeof(otgwcmd), "%s", msgPayload);
MQTTDebugf(" found command, sending payload [%s]\r\n", otgwcmd);
addOTWGcmdtoqueue((char *)otgwcmd, strlen(otgwcmd), true);
} else {
//all other commands are <otgwcmd>=<payload message>
snprintf(otgwcmd, sizeof(otgwcmd), "%s=%s", setcmds[i].otgwcmd, msgPayload);
MQTTDebugf(" found command, sending payload [%s]\r\n", otgwcmd);
addOTWGcmdtoqueue((char *)otgwcmd, strlen(otgwcmd), true);
}
break; //exit loop
}
}
if (i >= nrcmds){
//no match found
MQTTDebugln();
MQTTDebugTf("No match found for command: [%s]\r\n", token);
}
}
}
}
}
}
//===========================================================================================

View File

@ -500,6 +500,91 @@ struct OpenthermData {
void s16(int16_t value);
};
//** Moet ik nog iets mee? Of niet...**//
// array set learn {
// LA PR=L LB PR=L LC PR=L LD PR=L LE PR=L LF PR=L GA PR=G GB PR=G
// VR PR=V GW PR=M IT PR=T SB PR=S HW PR=W
// }
// BoilerWaterTemperature boilertemp d
// BoilerWaterTemperature2 boilertemp2 d
// CHEnable chenable b
// CH2Enable ch2enable b
// CHSetpoint chsetpoint d
// CentralHeating chmode b
// CentralHeating2 ch2mode b
// ControlSetpoint controlsp d
// ControlSetpoint2 controlsp2 d
// DHWEnable dhwenable b
// DHWSetpoint dhwsetpoint d
// DHWTemperature dhwtemp d
// DHWTemperature2 dhwtemp2 d
// Fault fault b
// Flame flame b
// HotWater dhwmode b
// Modulation modulation d
// OutsideTemperature outside d
// ReturnWaterTemperature returntemp d
// RoomTemperature roomtemp d
// RoomTemperature2 roomtemp2 d
// Setpoint setpoint d
// Setpoint2 setpoint2 d
// airpresfault "Air pressure fault"
// boilertemp "Boiler water temperature"
// boilertemp2 "Boiler water temperature 2"
// exhausttemp "Boiler exhaust temperature"
// ch2enable "Central heating 2 enable"
// ch2mode "Central heating 2 mode"
// chenable "Central heating enable"
// chmode "Central heating mode"
// chwsetpoint "Central heating setpoint"
// chbh "CH burner hours"
// chbs "CH burner starts"
// chph "CH pump hours"
// chps "CH pump starts"
// pressure "CH water pressure"
// controlsp "Control setpoint"
// controlsp2 "Control setpoint 2"
// coolingenable "Cooling enable"
// coolingstatus "Cooling status"
// diag "Diagnostic indication"
// dhwbh "DHW burner hours"
// dhwbs "DHW burner starts"
// dhwflowrate "DHW flow rate"
// dhwph "DHW pump hours"
// dhwps "DHW pump starts"
// dhwenable "Domestic hot water enable"
// dhwmode "Domestic hot water mode"
// dhwsetpoint "Domestic hot water setpoint"
// dhwtemp "Domestic hot water temp"
// dhwtemp2 "Domestic hot water temp 2"
// fault "Fault indication"
// flame "Flame"
// flamefault "Gas/flame fault"
// lockoutreset "Lockout-reset"
// lowpressure "Low water pressure"
// maxmod "Max rel modulation level"
// modulation "Modulation"
// faultcode "OEM fault/error code"
// otcstate "Outside temp compensation"
// outside "Outside temperature"
// override "Rem override room setpoint"
// returntemp "Return water temperature"
// setpoint "Room setpoint"
// setpoint2 "Room setpoint 2"
// roomtemp "Room temperature"
// roomtemp2 "Room temperature 2"
// service "Service request"
// timestamp "Time stamp"
// overtemp "Water over-temperature"
#endif

View File

@ -347,22 +347,18 @@ void sendDeviceInfo()
FlashMode_t ideMode = ESP.getFlashChipMode();
sendNestedJsonObj("flashchipmode", flashMode[ideMode]);
sendNestedJsonObj("boardtype",
#ifdef ARDUINO_ESP8266_NODEMCU
#if defined(ARDUINO_ESP8266_NODEMCU)
"ESP8266_NODEMCU"
#endif
#ifdef ARDUINO_ESP8266_GENERIC
#elif defined(ARDUINO_ESP8266_GENERIC)
"ESP8266_GENERIC"
#endif
#ifdef ESP8266_ESP01
#elif defined(ESP8266_ESP01)
"ESP8266_ESP01"
#endif
#ifdef ESP8266_ESP12
#elif defined(ESP8266_ESP12)
"ESP8266_ESP12"
#endif
#ifdef ARDUINO_ESP8266_WEMOS_D1MINI
#elif defined(ARDUINO_ESP8266_WEMOS_D1MINI)
"WEMOS_D1MINI"
#else
"Unknown board"
"Unknown board"
#endif
);