| 
					
				 | 
			
			
				@@ -0,0 +1,238 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Postkastl_MQTT v5
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Author: Flo Kra
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Desc: nach dem Start wird zunächst GPIO0 als output definiert und auf high gesetzt (Selbsthalteschaltung, dieser Pin ist mit CH_PD verbunden)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//       danach wird GPIO3 abgefragt - wenn high ist der Türkontakt und nicht der Klappenkontakt aktiv (event="emptied", da der Postkasten ja gerade entleert wird,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//       ansonsten event="new_post".
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//       dann wird eine WIFI Verbindung aufgebaut, eine Message mit ein paar Daten als JSON string an einen MQTT broker gesendet und nach einer Wartezeit das Modul wieder
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//       abgeschaltet
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// MQTT payload: {"event":"<event>","Vcc":"<vcc>","Batt":"<batt>"}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      event = "new_post"   -> Klappe wurde geöffnet, vermutlich ist neue Post da!
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//              "emptied"    -> Postkasten wurde entleert (wenn die Tür und nicht die Klappe geöffnet ist)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      Vcc = -> Vcc in mV (sollte zwischen 2400 - 3500 liegen)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//      Batt = normalerweise "OK", "LOW" wenn Vcc unter definiertem Wert ist
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <ESP8266WiFi.h>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <PubSubClient.h>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define SerialDebug false
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const char* ssid = "";  // WiFi SSID
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const char* password = "!";  // WiFi PWD
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const char* server = ""; // gateway server IP
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const int port = 1883;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const char* mqtt_user = "";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const char* mqtt_pwd = "";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const char* topic = "Postkasten";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const int BattLowValue = 2600; // mV @ ADC (always some 10 mV less than external supply voltage!)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const int powerdownAfter = 20; // sec
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// NO CONFIG BELOW!
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+byte holdPin = 0;  // GPIO 0 ist via Diode mit CH_PD verbunden, muss high gehalten werden bis das Programm fertig ist, dann wird auf low geschaltet und dadurch das Modul abgeschaltet
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+byte inputPin = 3; // GPIO 3 ist Input, wenn high bedeutet das, dass die Postkastentür und nicht die Klappe geöffnet wurde
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool event_is_emptying = false;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ADC_MODE(ADC_VCC);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int Vcc;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+byte BattLow;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+WiFiClient wifiClient;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+PubSubClient client(server, port, callback, wifiClient);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void setup() {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  pinMode(holdPin, OUTPUT);     // GPIO 0 ist output
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  digitalWrite(holdPin, HIGH);  // setze GPIO 0 auf high, dadurch wird CH_PD high gehalten auch wenn der Kontakt nicht mehr betätigt ist
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Serial TX only!! GPIO3 = RX wird als Input gebraucht
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.begin(9600, SERIAL_8N1, SERIAL_TX_ONLY, 1);   // void begin(unsigned long baud, SerialConfig config, SerialMode mode, uint8_t tx_pin);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // wenn GPIO3 / RX jetzt HIGH ist, dann ist der Kontakt der Postkastentür betätigt, also wird der Postkasten gerade entleert
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  pinMode(inputPin, INPUT);  // GPIO 3 = RX = input
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  delay(100);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if ( digitalRead(inputPin) == HIGH ) event_is_emptying = true;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  delay(1000);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print("begin...\n");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print("inputPin/event_is_emptying=");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print(digitalRead(inputPin));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print("\n");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print("connecting WiFi");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  WiFi.begin(ssid, password);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  uint8_t wifiRetryCounter = 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  while (WiFi.status() != WL_CONNECTED) {  // loop until WiFi connected
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    delay(500);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Serial.print(".");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    wifiRetryCounter++;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (wifiRetryCounter >= 60) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Serial.println();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      break;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (WiFi.status() == WL_CONNECTED) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Serial.println("WiFi connected");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Serial.println("IP: ");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Serial.println(WiFi.localIP());
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Serial.println("ERROR: could not connect WiFi. Powering down now.");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ESP.deepSleep(0);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Generate client name based on MAC address and last 8 bits of microsecond counter
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  String clientName;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  clientName += "esp8266-";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  uint8_t mac[6];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  WiFi.macAddress(mac);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  clientName += macToStr(mac);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  clientName += "-";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  clientName += String(micros() & 0xff, 16);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Vcc = ESP.getVcc();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print("Connecting to ");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print(server);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print(" as ");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.println(clientName);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print("Vcc=");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print(Vcc);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print("\n");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print("Batt=");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if ( Vcc <= BattLowValue ) Serial.print("LOW");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else Serial.print("OK");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print("\n");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //if (client.connect((char*) clientName.c_str())) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //if (client.connect("ESP-Post-5", "espclient", "1Weinum9")) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (client.connect((char*) clientName.c_str(), mqtt_user, mqtt_pwd)) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Serial.println("Connected to MQTT broker");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Serial.print("Topic: ");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Serial.println(topic);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    client.loop();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    String payload = "{\"event\":\"";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if ( !event_is_emptying ) payload += "new_post";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else payload += "emptied";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    payload += "\",\"Vcc\":\"";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    payload += Vcc;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    payload += "\",\"Batt\":";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if ( Vcc <= BattLowValue ) payload += "\"LOW\"";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else payload += "\"OK\"";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    payload += "}";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Serial.print("Sending payload: ");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Serial.println(payload);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    client.loop();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (client.publish(topic, (char*) payload.c_str())) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      client.loop();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Serial.println("Publish ok");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      client.loop();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Serial.println("Publish failed");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    client.loop();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    client.disconnect();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Serial.println("MQTT connect failed");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //Serial.println("Will reset and try again...");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //abort();   // reboot ESP
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print("sent, stopping WIFI...\n");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  WiFi.disconnect();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  WiFi.mode(WIFI_OFF);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  WiFi.forceSleepBegin();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print("WIFI deactivated\n");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // powerdownAfter Sekunden warten bevor PowerDown erfolgt, um doppelausloesung zu vermeiden falls waehrenddessen der Kontakt nochmal betaetigt wird (GPIO2 = HIGH) den Counter reseten
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (int i = 0; i <= powerdownAfter; i++) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    delay(1000);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // power down now
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serial.print("power down now\n");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //digitalWrite(holdPin, LOW);  // setze GPIO 0 auf low. dadurch wird CH_PD low und der ESP abgeschaltet (den Ast auf dem wir sitzen absägen ;-) )
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // nur deepSleep einschalten - müsste auch den GPIO 0 automatisch abschalten ..?
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ESP.deepSleep(0);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //  // ab hier nichts mehr tun, nur mehr auf bessere zeiten warten! (wenn wir hier gelandet sind ist eh etwas schief gelaufen!)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //  delay(5000);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //#if SerialDebug
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //  Serial.print("PWRDOWN failed, check circuit on CH_PD\n");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //#endif
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //  // deep sleep auslösen, da wir nun nichts mehr zu tun haben. falls das powerdown via GPIO0->CH_PD nicht funktioniert sparen wir so zumindest energie
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //  // wieder hochkommen wird zumindest der ESP-01 nie, da hierfür eine Verbindung von GPIO-16 zu RES nötig wäre
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //  ESP.deepSleep(0); // 300 sec
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} // END Setup
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void loop() {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} // END loop
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void callback(char* topic, byte* payload, unsigned int length) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // handle message arrived
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+String macToStr(const uint8_t* mac)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  String result;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (int i = 0; i < 6; ++i) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    result += String(mac[i], 16);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (i < 5)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      result += ':';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return result;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}
 
			 |