Advertisement
Guest User

Livolo gateway

a guest
Sep 6th, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.21 KB | None | 0 0
  1. #include <ESP8266WiFi.h>
  2. #include <PubSubClient.h>
  3.  
  4. //needed for library
  5. #include <LivoloTx.h>
  6. #include <DNSServer.h>
  7. #include <ESP8266WebServer.h>
  8. #include <WiFiManager.h>
  9. #include <ArduinoOTA.h>
  10. #include <EEPROM.h>
  11. #include <ESP8266HTTPClient.h>
  12.  
  13.  
  14. //#include <SoftwareSerial.h>
  15.  
  16. IPAddress ip(192,168,1,1);
  17.  
  18. const int EEPROM_MQTT_SERVER=50;
  19. const int EEPROM_MQTT_TOPIC=100;
  20. const int EEPROM_STRING_MAX=50;
  21.  
  22. const int ENABLE_DEBUG_PRINT = 0;
  23.  
  24. int latestKey = 0;
  25. int latestRemoteId = 0;
  26.  
  27. String latestSerialData;
  28. String latestRequest;
  29. const byte numChars = 200;
  30. char receivedChars[numChars]; // an array to store the received data
  31. boolean newData = false;
  32.  
  33. // Update these with values suitable for your network.
  34.  
  35. String mqtt_server;
  36. char* mqtt_user = "";
  37. char* mqtt_password = "";
  38. String mqtt_topic_out;
  39.  
  40. #include <Ticker.h>
  41. Ticker ticker;
  42. ESP8266WebServer server(80);
  43.  
  44. WiFiClient espClient;
  45. PubSubClient client(espClient);
  46. long lastMsg = 0;
  47. long lastConnectTry = 0;
  48. char msg[50];
  49. int value = 0;
  50. int commandId=0;
  51.  
  52. String http_server;
  53.  
  54. #define TX_PIN 0 // Connect tx pin
  55. LivoloTx gLivolo(TX_PIN);
  56.  
  57.      const uint8_t LIVOLO_KEY_MAX = 10;
  58.      const uint8_t LIVOLO_KEYS[LIVOLO_KEY_MAX] = {
  59.       0,
  60.       96,
  61.       120,
  62.       24,
  63.       80,
  64.       48,
  65.       108,
  66.       12,
  67.       72,
  68.       40,
  69.     };
  70.     static const uint8_t LIVOLO_KEY_OFF = 106;
  71.  
  72.  
  73. void callback(char* topic, byte* payload, unsigned int length) {
  74.   /*
  75.   debugPrint("Message arrived [");
  76.   debugPrint(topic);
  77.   debugPrint("] ");
  78.   for (int i = 0; i < length; i++) {
  79.     debugPrint((char)payload[i]);
  80.   }
  81.   debugPrintln();
  82.   */
  83.  
  84.   // Switch on the LED if an 1 was received as first character
  85.   if ((char)payload[0] == '1') {
  86.     digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
  87.   } else {
  88.     digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  89.   }
  90.  
  91. }
  92.  
  93. void debugPrint(String data) {
  94.   if (ENABLE_DEBUG_PRINT == 1) {
  95.    Serial.print(data);
  96.   }
  97. }
  98.  
  99. void debugPrintln(String data) {
  100.   if (ENABLE_DEBUG_PRINT == 1) {
  101.    Serial.println(data);
  102.   }
  103. }
  104.  
  105. String getFreeMemory() {
  106.   long  fh = ESP.getFreeHeap();
  107.   String freeHeap;
  108.   char  fhc[20];
  109.   ltoa(fh, fhc, 10);
  110.   freeHeap = String(fhc);  
  111.   return freeHeap;
  112. }
  113.  
  114. void reconnect() {
  115.   // Loop until we're reconnected
  116.   if (!client.connected()) {
  117.     digitalWrite(BUILTIN_LED, HIGH);    
  118.     debugPrint("Attempting MQTT connection...");
  119.     // Create a random client ID
  120.     String clientId = "ESP8266Client-";
  121.     clientId += String(random(0xffff), HEX);
  122.     // Attempt to connect
  123.     if (client.connect(clientId.c_str(),mqtt_user,mqtt_password)) {
  124.       debugPrintln("connected");
  125.       // Once connected, publish an announcement...
  126.       client.publish(mqtt_topic_out.c_str(), "hello world");
  127.       // ... and resubscribe
  128.       //client.subscribe(mqtt_topic_in);
  129.       digitalWrite(BUILTIN_LED, LOW);    
  130.     } else {
  131.       debugPrint("failed, rc=");
  132.       //debugPrint(client.state());
  133.       debugPrintln(" try again in 5 seconds");
  134.       // Wait 5 seconds before retrying
  135.     }
  136.   }
  137. }
  138.  
  139. //gets called when WiFiManager enters configuration mode
  140. void configModeCallback (WiFiManager *myWiFiManager) {
  141.   debugPrintln("Entered config mode ");
  142.   //debugPrintln(WiFi.softAPIP());
  143.   debugPrintln(myWiFiManager->getConfigPortalSSID());
  144.   //ticker.attach(0.2, tick);
  145. }
  146.  
  147.  
  148. void handleRoot() {
  149.  
  150.   String freeHeap;
  151.   freeHeap = getFreeMemory();  
  152.  
  153.   String message = "<html><head><title>PZEM Reader</title></head><body><h1>PZEM Reader</h1>\n";
  154.   message += "<p>Status: <span id='latestData'>";
  155.   message += latestSerialData;
  156.   message += " / Memory: ";
  157.   message += freeHeap;  
  158.   message += "</span>\n";
  159.   message += "<h2>Settings</h2><form action='/save' method='get'>MQTT Server:<br/><input type='text' name='server' value='";
  160.   message += mqtt_server;
  161.   message += "' size='60'><br/>";
  162.   message += "Topic:<br/><input type='text' name='base' value='";
  163.   message += mqtt_topic_out;    
  164.   message += "'size='60'><br/><input type='submit' value='Save settings'></form>";
  165.   message += "</p>";  
  166.   message += "<script language='javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js'></script>";  
  167.   message += "<script language=\"javascript\">\n";
  168.   message += "var status_timer;\n";
  169.   message += "function updateStatus() {\n";
  170.   message += "$.ajax({  url: \"/data\"  }).done(function(data) {  $('#latestData').html(data);status_timer=setTimeout('updateStatus();', 500); });";
  171.   message += "}\n";
  172.   message += "$(document).ready(function() {  updateStatus();   });\n";      
  173.   message += "</script>";  
  174.   message += "<p>Livolo Key example: <a href='/rfkey?button=1&remote=8500' target=_blank>/rfkey?button=1&remote=8500</a> (<i>button</i> -- button number (1-10), <i>remote</i> -- remote ID)</p>";  
  175.   message += "<p><a href='/restart' onclick='return confirm(\"Are you sure? Please confirm\");'>Reboot</a></p>";  
  176.   message += "</body></html>";
  177.   server.sendHeader("Connection", "close");
  178.      
  179.   server.send(200, "text/html", message);
  180.  
  181.   server.sendHeader("Connection", "close");
  182.      
  183.   server.send(200, "text/html", message);
  184. }
  185.  
  186.  
  187.  
  188. void handleData() {
  189.  
  190.   String freeHeap;
  191.   freeHeap = getFreeMemory();  
  192.  
  193.   String message = "";
  194.  
  195.   if (client.connected()) {
  196.     message += "<font color='green'>MQTT Connected</font> Data: ";
  197.   } else {
  198.    message += "<font color='red'>MQTT Disconnected</font> Data: ";
  199.   }
  200.   message += latestSerialData;
  201.   message += "; Memory: ";
  202.   message += freeHeap;  
  203.   server.sendHeader("Connection", "close");
  204.   server.send(200, "text/plain", message);
  205. }
  206.  
  207. void handleKey() {
  208.     const String& strButton = server.arg("button");
  209.     const String& strRemote = server.arg("remote");
  210.  
  211.   String message = "";
  212.  
  213.     if (strButton.equals("off")) {
  214.       latestKey = 106;
  215.     } else {
  216.      int keyIndex=strButton.toInt();
  217.      if (keyIndex<1) keyIndex=1;
  218.      latestKey = LIVOLO_KEYS[keyIndex-1];
  219.     }
  220.     latestRemoteId = strRemote.toInt();
  221.     if (latestRemoteId==0) {
  222.       latestRemoteId = 6400;
  223.     }
  224.     message += "Sending key code ";
  225.     message += latestKey;
  226.     message += " by remote ";
  227.     message += latestRemoteId;
  228.     gLivolo.sendButton(latestRemoteId, latestKey);
  229.     message += " ... DONE";
  230.    
  231.   server.sendHeader("Connection", "close");
  232.   server.send(200, "text/plain", message);
  233. }
  234.  
  235. void handleUpdateConfig() {
  236.   debugPrintln("Web: config update.");  
  237.   for (uint8_t i=0; i<server.args(); i++){
  238.     if (server.argName(i)=="server") {
  239.       mqtt_server=server.arg(i);
  240.     }
  241.     if (server.argName(i)=="base") {
  242.       mqtt_topic_out=server.arg(i);
  243.     }
  244.   }
  245.   String message = "<html><body><script language='javascript'>tm=setTimeout(\"window.location.href='/';\",2000);</script>Data saved!</body></html>";  
  246.  
  247.   writeStringEEPROM(mqtt_server,EEPROM_MQTT_SERVER);
  248.   writeStringEEPROM(mqtt_topic_out, EEPROM_MQTT_TOPIC);
  249.  
  250.   server.sendHeader("Connection", "close");  
  251.   server.send(200, "text/html", message);
  252. }
  253.  
  254. void handleRestart() {
  255.   String message = "<html><body><script language='javascript'>tm=setTimeout(\"window.location.href='/';\",2000);</script>Rebooting...</body></html>";  
  256.   server.sendHeader("Connection", "close");  
  257.   server.send(200, "text/html", message);  
  258.   ESP.restart();
  259. }
  260.  
  261. void handleNotFound(){
  262.   String message = "File Not Found\n\n";
  263.   message += "URI: ";
  264.   message += server.uri();
  265.   message += "\nMethod: ";
  266.   message += (server.method() == HTTP_GET)?"GET":"POST";
  267.   message += "\nArguments: ";
  268.   message += server.args();
  269.   message += "\n";
  270.   for (uint8_t i=0; i<server.args(); i++){
  271.     message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  272.   }
  273.   server.sendHeader("Connection", "close");  
  274.   server.send(404, "text/plain", message);
  275. }
  276.  
  277. String readStringEEPROM(int startIdx) {
  278.  
  279.   debugPrint("Reading string from ");
  280.   debugPrint(String(startIdx));
  281.  
  282.  
  283.     String res="";
  284.     for (int i = 0; i < EEPROM_STRING_MAX; ++i)
  285.     {
  286.       byte sm=EEPROM.read(startIdx+i);
  287.       if (sm>0) {
  288.        res+= char(sm);        
  289.       } else {
  290.         break;
  291.       }
  292.     }
  293.     debugPrint(" string: ");
  294.     debugPrintln(res);
  295.     return res;
  296. }
  297.  
  298. void writeStringEEPROM(String str, int startIdx) {
  299.   debugPrint("Writing string to ");
  300.   debugPrint(String(startIdx));
  301.   debugPrint(" string: ");
  302.   debugPrintln(str);
  303.           for (int i = 0; i < EEPROM_STRING_MAX; ++i)
  304.           {
  305.             EEPROM.write(startIdx+i, 0);
  306.           }    
  307.           for (int i = 0; i < str.length(); ++i)
  308.             {
  309.               EEPROM.write(startIdx+i, str[i]);
  310.             }    
  311.           EEPROM.commit();
  312.           delay(500);  
  313. }
  314.  
  315. //This function will write a 2 byte integer to the eeprom at the specified address and address + 1
  316. void writeIntEEPROM(unsigned int p_value, int p_address) {
  317.       byte lowByte = ((p_value >> 0) & 0xFF);
  318.       byte highByte = ((p_value >> 8) & 0xFF);
  319.  
  320.       EEPROM.write(p_address, lowByte);
  321.       EEPROM.write(p_address + 1, highByte);
  322.       }
  323.  
  324. //This function will read a 2 byte integer from the eeprom at the specified address and address + 1
  325. unsigned int readIntEEPROM(int p_address) {
  326.       byte lowByte = EEPROM.read(p_address);
  327.       byte highByte = EEPROM.read(p_address + 1);
  328.  
  329.       return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
  330.       }
  331.  
  332.  
  333.  
  334. void setup() {
  335.   pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  336.   digitalWrite(BUILTIN_LED, HIGH);
  337.  
  338.   if (ENABLE_DEBUG_PRINT == 1) {
  339.    Serial.begin(9600);
  340.   }
  341.  
  342.     pinMode(TX_PIN, OUTPUT);
  343.     digitalWrite(TX_PIN, LOW);
  344.  
  345.     WiFiManager wifiManager;
  346.     wifiManager.setAPCallback(configModeCallback);
  347.     String AcceePointName = "LivoloControl_"+String(random(0xffff), HEX);
  348.    
  349.     if (!wifiManager.autoConnect(AcceePointName.c_str(),"1111")) {
  350.       debugPrintln("Failed to connect!");
  351.       ESP.reset();
  352.       delay(1000);
  353.     }
  354.     digitalWrite(BUILTIN_LED, LOW);
  355.  
  356.     EEPROM.begin(512);
  357.     mqtt_server=readStringEEPROM(EEPROM_MQTT_SERVER);    
  358.     mqtt_topic_out=readStringEEPROM(EEPROM_MQTT_TOPIC);    
  359.  
  360.   client.setServer(mqtt_server.c_str(), 1883);
  361.   client.setCallback(callback);
  362.  
  363.   server.on("/", handleRoot);
  364.   server.on("/data", handleData);
  365.   server.on("/rfkey", handleKey);
  366.   server.on("/restart", handleRestart);
  367.   server.on("/save", handleUpdateConfig);
  368.   server.onNotFound(handleNotFound);  
  369.   server.begin();
  370.  
  371.   ArduinoOTA.setHostname(AcceePointName.c_str());
  372.  
  373.   ArduinoOTA.onStart([]() {
  374.     Serial.println("Start OTA");
  375.   });
  376.  
  377.   ArduinoOTA.onEnd([]() {
  378.     Serial.println("End OTA");
  379.   });
  380.  
  381.   ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
  382.     Serial.printf("Progress: %u%%\n", (progress / (total / 100)));
  383.   });
  384.  
  385.   ArduinoOTA.onError([](ota_error_t error) {
  386.     Serial.printf("Error[%u]: ", error);
  387.     if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
  388.     else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
  389.     else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
  390.     else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
  391.     else if (error == OTA_END_ERROR) Serial.println("End Failed");
  392.   });
  393.   ArduinoOTA.begin();  
  394.  
  395. }
  396.  
  397.  
  398. void sendNewData() {
  399.   String destTopic;
  400.   destTopic = mqtt_topic_out;
  401.   debugPrintln(destTopic);  
  402.   debugPrintln(latestSerialData);  
  403.   client.publish(destTopic.c_str(), latestSerialData.c_str());
  404. }
  405.  
  406.  
  407. void loop() {
  408.  
  409.   long now = millis()/1000;
  410.  
  411.   ArduinoOTA.handle();
  412.   server.handleClient();
  413.  
  414.   if (!client.connected()) {
  415.     if (now-lastConnectTry>=5) {
  416.      reconnect();      
  417.      lastConnectTry = now;      
  418.     }
  419.   } else {
  420.    client.loop();    
  421.   }
  422.  
  423.   if (now > 24*60*60) {
  424.     // auto reboot every 24 hours
  425.     ESP.restart();
  426.   }
  427.  
  428.   if (now - lastMsg > 60) {
  429.  
  430.   latestSerialData="{\"uptime\":\""+String(now)+"\"";
  431.   latestSerialData+=",\"ip\":\""+WiFi.localIP().toString()+"\"";
  432.   latestSerialData+=",\"latestRemoteId\":\""+String(latestRemoteId)+"\"";
  433.   latestSerialData+=",\"latestKey\":\""+String(latestKey)+"\"";
  434.  
  435.   latestSerialData+="}";
  436.  
  437.     delay(1000);
  438.     lastMsg = now;    
  439.     sendNewData();
  440.     debugPrintln(" SENT");    
  441.   }
  442. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement