/* SimpleMQTTClient.ino The purpose of this exemple is to illustrate a simple handling of MQTT and Wifi connection. Once it connects successfully to a Wifi network and a MQTT broker, it subscribe to a topic and send a message to it. It will also send a message delayed 5 seconds later. */ //Define DEBUG to get the Output from DEBUG_PRINTLN #define DEBUG 1 #ifdef DEBUG #define DEBUG_PRINTLN(x) Serial.println (x) #else #define DEBUG_PRINTLN(x) #endif #include "EspMQTTClient.h" #include #define WDT_TIMEOUT 900 //Seconds timeout, 15min static const String HOSTNAME = "gartensteuerung"; static const String HEARTBEATTOPIC = "stat/hs2/hk2/temperature"; static const int ResetPin = 35; static const int GartenSteuerungPumpenPin[5] = {32,33,25,26,27}; int GartenSteuerungPumpenTarget[5] = {0,0,0,0,0}; int GartenSteuerungPumpenStatus[5] = {1,1,1,1,1}; String GartenSteuerungDebugMessage; String GartenSteuerungPumpenStatusTopic[5]; // PumpIterator1 1/0 status information String GartenSteuerungPumpenTargetTopic[5]; // target from APP/Web String Output; int PumpIterator; int CountHeartBeats; bool resetWDT; EspMQTTClient client( "EasyBox-368239", "inginf95", "192.168.178.36", // MQTT Broker server ip "", // Can be omitted if not needed "", // Can be omitted if not needed "Gartensteuerung", // Client name that uniquely identify your device 1883 // The MQTT port, default to 1883. this line can be omitted ); void setup() { Serial.begin(115200); DEBUG_PRINTLN("**** STARTING SETUP ****"); //Set up Relais Pins for (int i=0;i<=4;i++){ pinMode(GartenSteuerungPumpenPin[i],OUTPUT); digitalWrite(GartenSteuerungPumpenPin[i], HIGH); } for (int i=0;i<=4;i++){ PumpIterator=i+1; GartenSteuerungPumpenStatusTopic[i] = "stat/"+HOSTNAME+"/pump"+PumpIterator+"/status"; GartenSteuerungPumpenTargetTopic[i] = "stat/"+HOSTNAME+"/pump"+PumpIterator+"/target"; } GartenSteuerungDebugMessage = "stat/"+HOSTNAME+"/debug"; // Optionnal functionnalities of EspMQTTClient : client.enableDebuggingMessages(); // Enable debugging messages sent to serial output client.enableHTTPWebUpdater("nils","inginf"); // Enable the web updater. User and password default to values of MQTTUsername and MQTTPassword. These can be overrited with enableHTTPWebUpdater("user", "password"). //client.enableLastWillMessage("TestClient/lastwill", "I am going offline"); // You can activate the retain flag by setting the third parameter to true GartenSteuerungDebugMessage = "stat/"+HOSTNAME+"/debug"; esp_task_wdt_init(WDT_TIMEOUT, true); //enable panic so ESP32 restarts esp_task_wdt_add(NULL); //add current thread to WDT watch } //This function transfers the state of the sensor. That includes the door status, battery status and level void transmitStatus() { DEBUG_PRINTLN(__func__); String Output = ""; bool publish = false; for (int i=0;i<=4;i++){ PumpIterator=i+1; if (GartenSteuerungPumpenStatus[i] != GartenSteuerungPumpenTarget[i]) { GartenSteuerungPumpenStatus[i] = GartenSteuerungPumpenTarget[i]; if (GartenSteuerungPumpenStatus[i]==1) { digitalWrite(GartenSteuerungPumpenPin[i], LOW); client.publish(GartenSteuerungPumpenStatusTopic[i].c_str(), "ON" ); Output += "Pump"+String(PumpIterator); Output += " turned on."; } else { digitalWrite(GartenSteuerungPumpenPin[i], HIGH); client.publish(GartenSteuerungPumpenStatusTopic[i].c_str(), "OFF" ); Output += "Pump"+String(PumpIterator); Output += " turned off."; } publish = true; Output += "\n"; //publish always } } if (publish==true) { client.publish(GartenSteuerungDebugMessage.c_str(), Output.c_str() ); DEBUG_PRINTLN(Output.c_str()); } } // This function is called once everything is connected (Wifi and MQTT) // WARNING : YOU MUST IMPLEMENT IT IF YOU USE EspMQTTClient void onConnectionEstablished() { client.subscribe(HEARTBEATTOPIC, [](const String & payload) { resetWDT = true; CountHeartBeats++; Output = "Heart-Beat count: "+String(CountHeartBeats); client.publish(GartenSteuerungDebugMessage.c_str(), Output.c_str() ); DEBUG_PRINTLN(Output.c_str()); //automatically turn off all pumps after 15-20min if (CountHeartBeats >= 3){ for (int i=0;i<=4;i++){ GartenSteuerungPumpenTarget[i] = 0; } CountHeartBeats = 0; Output = "Deactivated all pumps due to longer inactivity"; client.publish(GartenSteuerungDebugMessage.c_str(), Output.c_str() ); DEBUG_PRINTLN(Output.c_str()); } transmitStatus(); DEBUG_PRINTLN("received heartbeat topic"); }); client.subscribe("stat/"+HOSTNAME+"/#", [](const String & topic, const String & payload) { bool publish = false; //Check all other messages for (int i=0;i<=4;i++){ PumpIterator=i+1; if (topic.equals(GartenSteuerungPumpenTargetTopic[i])) { resetWDT = true; publish = true; Output = "Neue Target Message (Pumpe"+String(PumpIterator); Output += "): "; //Update PumpIteratoriTarget... if (payload.equals("ON")) { GartenSteuerungPumpenTarget[i] = 1; } else { GartenSteuerungPumpenTarget[i] = 0; } Output += String(GartenSteuerungPumpenTarget[i]); Output += " payload: "; Output += payload; client.publish(GartenSteuerungDebugMessage.c_str(), Output.c_str() ); DEBUG_PRINTLN(Output.c_str()); } } if (publish){ transmitStatus(); CountHeartBeats = 0; //reset heartbeatcounter Output = "Heart-Beat count: "+String(CountHeartBeats); DEBUG_PRINTLN(Output.c_str()); } }); DEBUG_PRINTLN("**** ENDING SETUP ****"); } void loop() { if (resetWDT){ esp_task_wdt_reset(); resetWDT = false; } client.loop(); }