PowerTGS440

ESP8266 Mesh Bridge v0.02

Apr 10th, 2021
376
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.45 KB | None | 0 0
  1. // ------------------------------------------------------------------------------------------------------------ //
  2. // --- M E S H   B R I D G E   B Y   T O M A S Z   M A J C H E R ---------------------------------------------- //
  3. // ------------------------------------------------------------------------------------------------------------ //
  4. //
  5. // MESH-SERVER Wi-Fi BRIDGE v0.02 dla ESP8266
  6. //
  7. //
  8. // ------------------------------------------------------------------------------------------------------------ //
  9. // --- DOŁĄCZONE NAGŁÓWKI BIBLIOTEK --------------------------------------------------------------------------- //
  10. // ------------------------------------------------------------------------------------------------------------ //
  11.  
  12. #include <Arduino.h>
  13. #include <painlessMesh.h>
  14. #include <PubSubClient.h>
  15. #include <WiFiClient.h>
  16. #include <NTPClient.h>                                           // NTP klient (czas)
  17. #include <TimeLib.h>                                             // parser
  18. #include <WiFiUdp.h>                                             // UDP Wi-Fi
  19. #include <ESP8266HTTPClient.h>    
  20.                                                        
  21. #include <WiFiClient.h>
  22. #include <Arduino_JSON.h>
  23.  
  24. // ------------------------------------------------------------------------------------------------------------ //
  25. // --- D E F I N I C J E -------------------------------------------------------------------------------------- //
  26. // ------------------------------------------------------------------------------------------------------------ //
  27.  
  28. #define   MESH_PREFIX         "ESP_Root"                  // nazwa sieci MESH
  29. #define   MESH_PASSWORD       "ESP_Root"                  // hasło sieci MESH
  30. #define   MESH_PORT           5555                        // port  sieci MESH
  31.  
  32. #define   STATION_SSID        "DIABLO"                    // nazwa sieci Wi-Fi (router podłączony do sieci)
  33. #define   STATION_PASSWORD    "XXXXXXXXXXX"               // hasło sieci Wi-Fi (router podłączony do sieci)
  34.  
  35. #define   HOSTNAME            "ESP_Bridge"                // nazwa hosta (bridge) most sieci MESH i INTERNET
  36.  
  37. const String s_geo = "51.40";                             // szerokosc geograficzna Twojego Miasta
  38. const String d_geo = "16.20";                             // dlugosc geograficzna Twojego Miasta
  39.  
  40. String serverPath = "http://fcc-weather-api.glitch.me/api/current";       // darmowy serwer pogody
  41.  
  42. #define   TRUE      true
  43. #define   FALSE     false
  44.  
  45. #define   SERIAL  TRUE                                // włącz terminal
  46. #define   SPEED   115200                              // prędkość terminala
  47.  
  48. // ------------------------------------------------------------------------------------------------------------ //
  49. // --- P R O T O T Y P Y -------------------------------------------------------------------------------------- //
  50. // ------------------------------------------------------------------------------------------------------------ //
  51.  
  52. void receivedCallback( const uint32_t &from, const String &msg );
  53. void mqttCallback(char* topic, byte* payload, unsigned int length);
  54. void TimeDateUpdate();                                                      // aktualizuj czas z Serwera NTP
  55. void WeatherUpdate();                                                       // aktualizuj pogodę z Serwera FCC
  56.  
  57. // ------------------------------------------------------------------------------------------------------------ //
  58. // --- O B I E K T Y ------------------------------------------------------------------------------------------ //
  59. // ------------------------------------------------------------------------------------------------------------ //
  60.  
  61. WiFiUDP ntpUDP;                                                 // dla NTP (pobieranie czasu z internetu)
  62. NTPClient timeClient(ntpUDP, "pool.ntp.org", 3600);             // dla NTP (pobieranie czasu z internetu)
  63.  
  64. IPAddress getlocalIP();                                         // pobierz adres lokalny IP
  65. IPAddress myIP(0,0,0,0);                                        // mój adres IP
  66. IPAddress mqttBroker(192, 168, 1, 1);                           // mój adres IP
  67.  
  68. painlessMesh  mesh;                                             // obiekt mesh
  69.                                                                
  70. WiFiClient wifiClient;                                          // obiekt WiFi
  71. HTTPClient http;                                                // obiket HTTP
  72.  
  73. PubSubClient mqttClient(mqttBroker, 1883, mqttCallback, wifiClient);
  74.  
  75. // ------------------------------------------------------------------------------------------------------------ //
  76. // --- Z M I E N N E   G L O B A L N E ------------------------------------------------------------------------ //
  77. // ------------------------------------------------------------------------------------------------------------ //
  78.  
  79. struct NTP
  80. {
  81.     int8_t    Godzina;
  82.     int8_t    Minuta;
  83.     int8_t    Sekunda;
  84.     int8_t    Dzien;
  85.     int8_t    Miesiac;
  86.     int16_t   Rok;    
  87.     String    SformatowanyCzas;
  88.     String    SformatowanaData;
  89.     String    SformatowanyNTP;
  90. } ntp;
  91.  
  92. unsigned long time_ZERO = 0;    
  93. unsigned long time_01S = 0;    
  94. unsigned long time_60S = 0;
  95. unsigned long time_out_01S = 0;
  96. unsigned long time_out_60S = 0;
  97.  
  98.  
  99. // ------------------------------------------------------------------------------------------------------------ //
  100. // --- o d b i o r n i k   b r o a d c a s t ------------------------------------------------------------------ //
  101. // ------------------------------------------------------------------------------------------------------------ //
  102.  
  103. void receivedCallback( const uint32_t &from, const String &msg )
  104. {
  105.     Serial.printf("ESP Bridge: Odebralem wiadomosc od wezla: %u o tresci: %s\n", from, msg.c_str());  
  106.    
  107.     mesh.sendSingle(from, ntp.SformatowanyNTP.c_str());          // wysyłam do nadawcy (tylko do nadawcy) !!!      
  108.  
  109.     #if SERIAL
  110.         Serial.printf("\n *** wysłałem do nadawcy - aktualny czas i datę ***\n");
  111.     #endif
  112. }
  113.  
  114. // ------------------------------------------------------------------------------------------------------------ //
  115. // --- m q t t   C a l l b a c k  ----------------------------------------------------------------------------- //
  116. // ------------------------------------------------------------------------------------------------------------ //
  117.  
  118. void mqttCallback(char* topic, uint8_t* payload, unsigned int length)
  119. {
  120.     char* cleanPayload = (char*)malloc(length+1);
  121.     memcpy(cleanPayload, payload, length);
  122.     cleanPayload[length] = '\0';
  123.     String msg = String(cleanPayload);
  124.     free(cleanPayload);
  125.  
  126.     String targetStr = String(topic).substring(16);
  127.  
  128.     if(targetStr == "gateway")
  129.     {
  130.         if(msg == "getNodes")
  131.         {
  132.             auto nodes = mesh.getNodeList(true);
  133.             String str;
  134.             for (auto &&id : nodes)
  135.                 str += String(id) + String(" ");
  136.                 mqttClient.publish("painlessMesh/from/gateway", str.c_str());
  137.         }
  138.     }
  139.     else
  140.     if(targetStr == "broadcast")
  141.     {
  142.         mesh.sendBroadcast(msg);
  143.     }
  144.     else
  145.     {
  146.         uint32_t target = strtoul(targetStr.c_str(), NULL, 10);
  147.         if(mesh.isConnected(target))
  148.         {
  149.           mesh.sendSingle(target, msg);
  150.         }
  151.         else
  152.         {
  153.           mqttClient.publish("painlessMesh/from/gateway", "Klient nie podłaczony!");
  154.         }
  155.     }
  156. }
  157.  
  158. // ------------------------------------------------------------------------------------------------------------ //
  159. // --- p o b i e r z   a d r e s   I P  ----------------------------------------------------------------------- //
  160. // ------------------------------------------------------------------------------------------------------------ //
  161.  
  162. IPAddress getlocalIP()
  163. {
  164.     return IPAddress(mesh.getStationIP());
  165. }
  166.  
  167. // ------------------------------------------------------------------------------------------------------------ //
  168. // --- Aktualizacja Czasu i Daty  ----------------------------------------------------------------------------- //
  169. // ------------------------------------------------------------------------------------------------------------ //
  170.  
  171. void TimeDateUpdate()                                                                  
  172. {                            
  173.     timeClient.update();                                    // pobierz aktualny czas i datę z serwera NTP
  174.  
  175.     unsigned long epochTime = timeClient.getEpochTime();    // zapisz EpochTime                                            
  176.     struct tm *ptm = gmtime ((time_t *)&epochTime);         // struktura daty EpochTime                        
  177.  
  178.     ntp.Godzina    =   timeClient.getHours();               // zapisz godzinę z serwera NTP do struktury
  179.     ntp.Minuta     =   timeClient.getMinutes();             // zapisz minutę z serwera NTP do struktury
  180.     ntp.Sekunda    =   timeClient.getSeconds();             // zapisz sekundę z serwera NTP do stuktury
  181.  
  182.     ntp.Dzien     =   ptm->tm_mday;                         // dzień miesiąca                                                  
  183.     ntp.Miesiac   =   ptm->tm_mon+1;                        // aktualny miesiąc (musimy dodać +1)                
  184.     ntp.Rok       =   ptm->tm_year+1900;                    // aktualny rok (musimy dodać +1900)
  185.  
  186.     ntp.SformatowanyCzas  =   timeClient.getFormattedTime();
  187.     ntp.SformatowanaData  =   String(ntp.Dzien) + "." + String(ntp.Miesiac) + "." + String(ntp.Rok);
  188.    
  189.     ntp.SformatowanyNTP = ntp.SformatowanaData + " " + ntp.SformatowanyCzas;
  190. }    
  191.  
  192. // ------------------------------------------------------------------------------------------------------------ //
  193. // --- Aktualizacja Pogody z Serwera  ------------------------------------------------------------------------- //
  194. // ------------------------------------------------------------------------------------------------------------ //
  195.  
  196. void WeatherUpdate()
  197. {
  198.     String path = serverPath + "?lat=" + s_geo + "&lon=" + d_geo;       // ścieżka do serwera pogody
  199.  
  200.     String jsonBuffer = httpGETRequest(path.c_str());  
  201.      
  202.     #if SERIAL
  203.         Serial.println(jsonBuffer);            
  204.     #endif
  205.  
  206.     Serial.println(path);  
  207. }
  208.  
  209. // ------------------------------------------------------------------------------------------------------------ //
  210. // --- Aktualizacja Pogody z Serwera  ------------------------------------------------------------------------- //
  211. // ------------------------------------------------------------------------------------------------------------ //
  212.  
  213. String httpGETRequest(const char* serverName)                                                        
  214. {                                                                                                    
  215.     HTTPClient http;                                                                                  
  216.     http.begin(serverName);                                                                          
  217.     int httpResponseCode = http.GET();                                                                
  218.     String bufor = "{}";                                                                              
  219.                                                                                                      
  220.     if ( httpResponseCode > 0 )                                                                      
  221.     {                                                                                                
  222.         #if SERIAL
  223.             //Serial.print("\nHTTP Response code: ");                                                  
  224.             //Serial.print(httpResponseCode);                                                      
  225.         #endif          
  226.                                                                                      
  227.         bufor = http.getString();                                                                    
  228.     }                                                                                                
  229.     else                                                                                              
  230.     {                                                                                                
  231.         #if SERIAL                                                                                  
  232.             //Serial.print("Error code: ");                                                          
  233.             //Serial.println(httpResponseCode);                                                      
  234.         #endif                                                                                        
  235.     }                                                                                                
  236.     http.end();                                                                                      
  237.     return bufor;                                                                                    
  238. }      
  239.  
  240. // ------------------------------------------------------------------------------------------------------------ //
  241. // --- MY TASK ------------------------------------------------------------------------------------------------ //
  242. // ------------------------------------------------------------------------------------------------------------ //
  243.  
  244. void my_task()
  245. {
  246.     time_ZERO =  millis();
  247.     time_01S  =  time_ZERO - time_out_01S;
  248.     time_60S  =  time_ZERO - time_out_60S;
  249.  
  250.     if(time_01S >= 1000UL)                          
  251.     {                  
  252.         TimeDateUpdate();        
  253.         time_out_01S = time_ZERO;                        
  254.     }  
  255.  
  256.     if(time_60S >= 60000UL)                          
  257.     {                  
  258.         WeatherUpdate();        
  259.         time_out_60S = time_ZERO;                        
  260.     }
  261. }
  262.  
  263. // ------------------------------------------------------------------------------------------------------------ //
  264. // --- S E T U P ---------------------------------------------------------------------------------------------- //
  265. // ------------------------------------------------------------------------------------------------------------ //
  266.  
  267. void setup()
  268. {
  269.    
  270.     #if SERIAL
  271.         Serial.begin(SPEED);                // ustaw prędkość terminala SERIAL
  272.     #endif
  273.          
  274.     mesh.setDebugMsgTypes( ERROR | STARTUP | CONNECTION );  // ustaw przed init (), abyś mógł zobaczyć komunikaty startowe
  275.  
  276.     mesh.init( MESH_PREFIX, MESH_PASSWORD, MESH_PORT, WIFI_AP_STA, 6 );
  277.     mesh.onReceive(&receivedCallback);
  278.     mesh.stationManual(STATION_SSID, STATION_PASSWORD);
  279.     mesh.setHostname(HOSTNAME);
  280.  
  281.     mesh.setRoot(true);                           // sieć MESH na tym urządzeniu jako ROOT  
  282.     mesh.setContainsRoot(true);                   // sieć MESH na tym urządzeniu jako ROOT
  283.  
  284.     timeClient.begin();                           // włącz klienta NTP (pobieranie czasu z internetu)
  285.  
  286. }
  287.  
  288. // ------------------------------------------------------------------------------------------------------------ //
  289. // --- L O O P ------------------------------------------------------------------------------------------------ //
  290. // ------------------------------------------------------------------------------------------------------------ //
  291.  
  292. void loop()
  293. {
  294.     mesh.update();                                                                // aktulizuj MESH
  295.     mqttClient.loop();                                                            // pętla dla klienta mqtt
  296.  
  297.     if(myIP != getlocalIP())                                                      // jeśli moje IP różne od lokalnego IP
  298.     {                                                                          
  299.         myIP = getlocalIP();                                                      // zapisz lokalne IP
  300.  
  301.         #if SERIAL
  302.             Serial.println("Adres lokalny IP: " + myIP.toString());
  303.         #endif
  304.  
  305.         if (mqttClient.connect("painlessMeshClient"))                             // jeśli client
  306.         {
  307.             mqttClient.publish("painlessMesh/from/gateway","Gotowe!");
  308.             mqttClient.subscribe("painlessMesh/to/#");
  309.         }
  310.     }  
  311.  
  312.     my_task();
  313. }
  314.  
  315.  
  316. // ------------------------------------------------------------------------------------------------------------ //
  317. // --- E N D  ------------------------------------------------------------------------------------------------- //
  318. // ------------------------------------------------------------------------------------------------------------ //
  319.  
Advertisement
Add Comment
Please, Sign In to add comment