PowerTGS440

LESZEK_ESP32

Apr 17th, 2021
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 51.10 KB | None | 0 0
  1. // ------------------------------------------------------------------------------------------------------------ //
  2. // --- D a r k N e t S e r v e r & M e s h & B T B Y T O M A S Z M A J C H E R --------- //
  3. // ------------------------------------------------------------------------------------------------------------ //
  4. //
  5. // by Tomasz Majcher (TLG) Trans Line Group, Lubin POLSKA
  6. // NIP: 692-201-09-78
  7. // TEL: 667-08-21-21
  8. //
  9. //
  10. //
  11. //
  12. //
  13. //
  14. // ------------------------------------------------------------------------------------------------------------ //
  15. // --- HISTORIA WERSJI ---------------------------------------------------------------------------------------- //
  16. // ------------------------------------------------------------------------------------------------------------ //
  17. //
  18. // DarkNet Server v0.02 - rozbudowa usług MESH
  19. // DarkNet Server v0.01 - budowa pod serwer WEATHER
  20. //
  21. // ------------------------------------------------------------------------------------------------------------ //
  22. // --- DOŁĄCZONE NAGŁÓWKI BIBLIOTEK --------------------------------------------------------------------------- //
  23. // ------------------------------------------------------------------------------------------------------------ //
  24.  
  25. #include <Arduino.h>
  26. #include <painlessMesh.h>
  27. #include <PubSubClient.h>
  28. #include <WiFiClient.h>
  29. #include <NTPClient.h> // NTP klient (czas)
  30. #include <TimeLib.h> // parser
  31. #include <WiFiUdp.h> // UDP Wi-Fi
  32. #include <HTTPClient.h>
  33. #include <WiFiClient.h>
  34. #include <Arduino_JSON.h>
  35. #include <ESP32Time.h> // zegar RTC ESP32
  36. #include "tools.h" // dołącz moje narzędzia
  37.  
  38.  
  39. // ------------------------------------------------------------------------------------------------------------ //
  40. // --- D E F I N I C J E -------------------------------------------------------------------------------------- //
  41. // ------------------------------------------------------------------------------------------------------------ //
  42.  
  43. #define MESH_PREFIX "ESP_Root" // nazwa sieci MESH
  44. #define MESH_PASSWORD "ESP_Root" // hasło sieci MESH
  45. #define MESH_PORT 5555 // port sieci MESH
  46.  
  47. #define STATION_SSID "XXXXXXXXXX" // nazwa sieci Wi-Fi (router podłączony do sieci)
  48. #define STATION_PASSWORD "XXXXXXXXXX" // hasło sieci Wi-Fi (router podłączony do sieci)
  49.  
  50. #define HOSTNAME "DarkNet" // nazwa hosta (bridge) most sieci MESH i INTERNET
  51.  
  52. #define SERIAL 1 // włącz terminal SERIAL.MONITOR
  53. #define SPEED 115200 // prędkość terminala SERIAL
  54. #define THREAD_INFO 0
  55. #define CORE0_TASK1 1
  56.  
  57.  
  58. // ------------------------------------------------------------------------------------------------------------ //
  59. // --- P R O T O T Y P Y -------------------------------------------------------------------------------------- //
  60. // ------------------------------------------------------------------------------------------------------------ //
  61.  
  62. void receivedCallback( const uint32_t &from, const String &msg );
  63. void mqttCallback(char* topic, byte* payload, unsigned int length);
  64.  
  65. // ------------------------------------------------------------------------------------------------------------ //
  66. // --- O B I E K T Y ------------------------------------------------------------------------------------------ //
  67. // ------------------------------------------------------------------------------------------------------------ //
  68.  
  69. WiFiUDP ntpUDP; // dla NTP (pobieranie czasu z internetu)
  70. NTPClient timeClient(ntpUDP, "pool.ntp.org", 7200); // dla NTP (pobieranie czasu z internetu)
  71. IPAddress getlocalIP(); // pobierz adres lokalny IP
  72. IPAddress myIP(0,0,0,0); // mój adres IP
  73. IPAddress mqttBroker(192, 168, 1, 1); // mój adres IP
  74. painlessMesh mesh; // obiekt mesh
  75. WiFiClient wifiClient; // obiekt WiFi
  76. HTTPClient http; // obiekt HTTP
  77. PubSubClient mqttClient(mqttBroker, 1883, mqttCallback, wifiClient);
  78. ESP32Time rtc;
  79.  
  80. JSONVar JSON_Astronomy; // obiekt Astronomia
  81. JSONVar JSON_Weather; // obiekt Pogoda
  82. JSONVar JSON_Forecast; // obiekt Forecast
  83. JSONVar JSON_Air; // obiekt Powietrze
  84. JSONVar JSON_Mesh; // obiekt Mesh Incoming
  85.  
  86. void Core0_Task1( void * pvParameters ); // funkcja Task1 dla rdzenia nr. 0 CPU
  87. void Core0_Task2( void * pvParameters ); // funkcja Task2 dla rdzenia nr. 0 CPU
  88.  
  89. void Core1_Task1( void * pvParameters ); // funkcja Task1 dla rdzenia nr. 1 CPU
  90. void Core1_Task2( void * pvParameters ); // funkcja Tasl2 dla rdzenia nr. 1 CPU
  91.  
  92. TaskHandle_t CPU_Core_0; // rdzeń nr. 0 CPU - ESP32
  93. TaskHandle_t CPU_Core_1; // rdzeń nr. 1 CPU - ESP32
  94.  
  95. // ------------------------------------------------------------------------------------------------------------ //
  96. // --- Z M I E N N E G L O B A L N E ------------------------------------------------------------------------ //
  97. // ------------------------------------------------------------------------------------------------------------ //
  98. // --- M I E S I Ą C E P L ---------------------------------------------------------------------------------- //
  99. // ------------------------------------------------------------------------------------------------------------ //
  100.  
  101. const char MONTH_00 [] = "Error";
  102. const char MONTH_01 [] = "Styczeń";
  103. const char MONTH_02 [] = "Luty";
  104. const char MONTH_03 [] = "Marzec";
  105. const char MONTH_04 [] = "Kwiecień";
  106. const char MONTH_05 [] = "Maj";
  107. const char MONTH_06 [] = "Czerwiec";
  108. const char MONTH_07 [] = "Lipiec";
  109. const char MONTH_08 [] = "Sierpień";
  110. const char MONTH_09 [] = "Wrzesień";
  111. const char MONTH_10 [] = "Pazdziernik";
  112. const char MONTH_11 [] = "Listopad";
  113. const char MONTH_12 [] = "Grudzień";
  114.  
  115. const char* const MONTH [] = {
  116. MONTH_00,
  117. MONTH_01, MONTH_02, MONTH_03, MONTH_04, MONTH_05, MONTH_06,
  118. MONTH_07, MONTH_08, MONTH_09, MONTH_10, MONTH_11, MONTH_12
  119. };
  120.  
  121. // ------------------------------------------------------------------------------------------------------------ //
  122. // --- Z E G A R N T P ------------------------------------------------------------------------------------- //
  123. // ------------------------------------------------------------------------------------------------------------ //
  124.  
  125. struct NTP_TIME
  126. {
  127. String SformatowanaData;
  128. String SformatowanaDataPL;
  129. int DzienTygodnia;
  130. int DzienMiesiaca;
  131. int Miesiac;
  132. int Rok;
  133. String SformatowanyCzas;
  134. String SformatowanyCzasHM;
  135. int Godzina;
  136. int Minuta;
  137. int Sekunda;
  138. }
  139. zegar;
  140.  
  141. // ------------------------------------------------------------------------------------------------------------ //
  142. // --- Z M I E N N E G L O B A L N E ------------------------------------------------------------------------ //
  143. // ------------------------------------------------------------------------------------------------------------ //
  144. // --- A S T R O N O M I A ------------------------------------------------------------------------------------ //
  145. // ------------------------------------------------------------------------------------------------------------ //
  146.  
  147. struct ASTRONOMY
  148. {
  149. String miejscowosc = "";
  150. String kraj = "";
  151. double szerokosc_geograficzna = 0;
  152. double dlugosc_geograficzna = 0;
  153. long czas_epoch = 0;
  154. String czas_lokalny = "";
  155. String wschod_slonca = "";
  156. String zachod_slonca = "";
  157. String wschod_ksiezyca = "";
  158. String zachod_ksiezyca = "";
  159. String faza_ksiezyca = "";
  160. String oswietlenie_ksiezyca = "";
  161. }
  162. astronomia;
  163.  
  164. // ------------------------------------------------------------------------------------------------------------ //
  165. // --- Z M I E N N E G L O B A L N E ------------------------------------------------------------------------ //
  166. // ------------------------------------------------------------------------------------------------------------ //
  167. // --- P O G O D A -------------------------------------------------------------------------------------------- //
  168. // ------------------------------------------------------------------------------------------------------------ //
  169.  
  170. struct Weather
  171. {
  172. String miejscowosc = "";
  173. String kraj = "";
  174. double szerokosc_geograficzna = 0;
  175. double dlugosc_geograficzna = 0;
  176. String id = "";
  177. long czas_epoch = 0;
  178. String czas_lokalny = "";
  179. String ostatnia_aktualizacja = "";
  180. double temperatura_C = 0;
  181. double temperatura_C_odczuwalna = 0;
  182. String kondycja = "";
  183. double predkosc_wiatru_kph = 0;
  184. double podmuchy_wiatru = 0;
  185. int kierunek_wiatru_stopnie = 0;
  186. String kierunek_wiatru_kompas = "";
  187. int cisnienie = 0;
  188. double opady = 0;
  189. int wilgotnosc = 0;
  190. int zachmurzenie = 0;
  191. int widzialnosc = 0;
  192. int index_uv = 0;
  193. }
  194. pogoda;
  195.  
  196. // ------------------------------------------------------------------------------------------------------------ //
  197. // --- Z M I E N N E G L O B A L N E ------------------------------------------------------------------------ //
  198. // ------------------------------------------------------------------------------------------------------------ //
  199. // --- P O W I E T R Z E -------------------------------------------------------------------------------------- //
  200. // ------------------------------------------------------------------------------------------------------------ //
  201.  
  202. struct Air
  203. {
  204. double co = 0; // Carbon Monoxide (μg/m3) - Tlenek węgla (μg / m3)
  205. double o3 = 0; // Ozone (μg/m3) - Ozon (μg / m3)
  206. double no2 = 0; // Nitrogen dioxide (μg/m3) - Dwutlenek azotu (μg / m3)
  207. double so2 = 0; // Sulphur dioxide (μg/m3) - Dwutlenek siarki (μg / m3)
  208. double pm25 = 0; // PM2.5 (μg/m3) - aerozole atmosferyczne o średnicy nie większej niż 2,5 μm
  209. double pm10 = 0; // PM10 (μg/m3) - mieszanina zawieszonych w powietrzu cząsteczek o średnicy nie większej niż 10 μm
  210. int Defra = 0; // Air Quality Index - index jakości powietrza
  211. }
  212. powietrze;
  213.  
  214. // ------------------------------------------------------------------------------------------------------------ //
  215. // --- Z M I E N N E G L O B A L N E ------------------------------------------------------------------------ //
  216. // ------------------------------------------------------------------------------------------------------------ //
  217. // --- P A R S E R M S G S E N D ------------------------------------------------------------------------- //
  218. // ------------------------------------------------------------------------------------------------------------ //
  219.  
  220. struct JSON_MSG
  221. {
  222. String czas; // JSON czas HH:MM:SS
  223. String czasHM; // JSON czas HH:MM
  224. String data; // JSON data DD.MM.YYYY
  225. String dataPL; // JSON data DD miesiac YYYY
  226. }
  227. jmsg;
  228.  
  229. // ------------------------------------------------------------------------------------------------------------ //
  230. // --- Z M I E N N E G L O B A L N E ------------------------------------------------------------------------ //
  231. // ------------------------------------------------------------------------------------------------------------ //
  232. // --- F L A G I ---------------------------------------------------------------------------------------------- //
  233. // ------------------------------------------------------------------------------------------------------------ //
  234.  
  235. bool F_Astronomia = false;
  236. bool F_Pogoda = false;
  237. bool F_Prognoza = false;
  238. bool F_Powietrze = false;
  239. bool F_Zegar = false;
  240.  
  241. // ------------------------------------------------------------------------------------------------------------ //
  242. // --- Z M I E N N E G L O B A L N E ------------------------------------------------------------------------ //
  243. // ------------------------------------------------------------------------------------------------------------ //
  244. // --- M I L L I S -------------------------------------------------------------------------------------------- //
  245. // ------------------------------------------------------------------------------------------------------------ //
  246.  
  247. unsigned long timeZERO = 0;
  248. unsigned long task01m = 0;
  249. unsigned long task05m = 0;
  250. unsigned long task10m = 0;
  251. unsigned long task15m = 0;
  252. unsigned long timeout_task01m = 0;
  253. unsigned long timeout_task05m = 0;
  254. unsigned long timeout_task10m = 0;
  255. unsigned long timeout_task15m = 0;
  256.  
  257. String root = "{\"ID\":\"ROOT\",\"CODE\":0000,\"ROOT\":\"Ja tu rządze [DarkNet] mesh serwer\"}";
  258.  
  259. // ------------------------------------------------------------------------------------------------------------ //
  260. // --- Z M I E N N E G L O B A L N E ------------------------------------------------------------------------ //
  261. // ------------------------------------------------------------------------------------------------------------ //
  262. // --- P A R S E R M E S H ---------------------------------------------------------------------------------- //
  263. // ------------------------------------------------------------------------------------------------------------ //
  264.  
  265. struct MeshParser
  266. {
  267. long Id;
  268. int Code;
  269. }
  270. meshParser;
  271.  
  272. // ------------------------------------------------------------------------------------------------------------ //
  273. // --- p a r s e r m s g ------------------------------------------------------------------------------------ //
  274. // ------------------------------------------------------------------------------------------------------------ //
  275.  
  276. void parserMsg(const String &msg)
  277. {
  278. JSON_Mesh = JSON.parse(msg);
  279.  
  280. meshParser.Id = JSON_Mesh["ID"]; // ID urządzenia ESP w sieci MESH
  281. meshParser.Code = JSON_Mesh["CODE"]; // KOD rządania z ESP w sieci MESH
  282. }
  283.  
  284. // ------------------------------------------------------------------------------------------------------------ //
  285. // --- o d b i o r n i k b r o a d c a s t ------------------------------------------------------------------ //
  286. // ------------------------------------------------------------------------------------------------------------ //
  287.  
  288. void receivedCallback( const uint32_t &from, const String &msg )
  289. {
  290. Serial.printf("\n[ESP Bridge] [otrzymałem od] %u [wiadomosc JSON] %s", from, msg.c_str());
  291.  
  292. parserMsg(msg);
  293.  
  294. switch(meshParser.Code)
  295. {
  296. case 0000 : mesh.sendSingle ( from, root.c_str());
  297. break;
  298.  
  299. case 1001 : mesh.sendSingle ( from, jmsg.czas.c_str() ); // jeśli nadawca wysłał kod 1001 wyślij mu aktualny czas
  300. Serial.printf("\n[ESP Bridge] [wysyłam do] %u [wiadomosc JSON] %s", from, jmsg.czas.c_str());
  301. break;
  302.  
  303. case 1002 : mesh.sendSingle ( from, jmsg.czasHM.c_str() ); // jeśli nadawca wysłał kod 1002 wyślij mu aktualny czas
  304. Serial.printf("\n[ESP Bridge] [wysyłam do] %u [wiadomosc JSON] %s", from, jmsg.czasHM.c_str());
  305. break;
  306.  
  307. case 1011 : mesh.sendSingle ( from, jmsg.data.c_str() ); // jeśli nadawca wysłał kod 1011 wyślij mu aktualną datę - format: DD.MM.RRRR
  308. Serial.printf("\n[ESP Bridge] [wysyłam do] %u [wiadomosc JSON] %s", from, jmsg.data.c_str());
  309. break;
  310.  
  311. case 1012 : mesh.sendSingle ( from, jmsg.dataPL.c_str() ); // jeśli nadawca wysłał kod 1012 wyślij mu aktualną datę - format: DD miesiac RRRR
  312. Serial.printf("\n[ESP Bridge] [wysyłam do] %u [wiadomosc JSON] %s", from, jmsg.dataPL.c_str());
  313. break;
  314.  
  315. default : mesh.sendSingle ( from, "nieznany kod mesh" ); break;
  316. }
  317.  
  318. }
  319.  
  320. // ------------------------------------------------------------------------------------------------------------ //
  321. // --- m q t t C a l l b a c k ----------------------------------------------------------------------------- //
  322. // ------------------------------------------------------------------------------------------------------------ //
  323.  
  324. void mqttCallback(char* topic, uint8_t* payload, unsigned int length)
  325. {
  326. char* cleanPayload = (char*)malloc(length+1);
  327. memcpy(cleanPayload, payload, length);
  328. cleanPayload[length] = '\0';
  329. String msg = String(cleanPayload);
  330. free(cleanPayload);
  331.  
  332. String targetStr = String(topic).substring(16);
  333.  
  334. if(targetStr == "gateway")
  335. {
  336. if(msg == "getNodes")
  337. {
  338. auto nodes = mesh.getNodeList(true);
  339. String str;
  340. for (auto &&id : nodes)
  341. str += String(id) + String(" ");
  342. mqttClient.publish("painlessMesh/from/gateway", str.c_str());
  343. }
  344. }
  345. else
  346. if(targetStr == "broadcast")
  347. {
  348. mesh.sendBroadcast(msg);
  349. }
  350. else
  351. {
  352. uint32_t target = strtoul(targetStr.c_str(), NULL, 10);
  353. if(mesh.isConnected(target))
  354. {
  355. mesh.sendSingle(target, msg);
  356. }
  357. else
  358. {
  359. mqttClient.publish("painlessMesh/from/gateway", "Klient nie podłaczony!");
  360. }
  361. }
  362. }
  363. //
  364. // ------------------------------------------------------------------------------------------------------------ //
  365. // --- M U L T I - C O R E T A S K --- //
  366. // ------------------------------------------------------------------------------------------------------------ //
  367. //
  368. //
  369. //
  370. //
  371. // ------------------------------------------------------------------------------------------------------------ //
  372. // --- CORE0 TASK1 POBIERANIE CZASU i DATY Z SERWERA NTP i AKTUALIZACJA ZEGARA ESP32 RTC --- //
  373. // ------------------------------------------------------------------------------------------------------------ //
  374. //
  375. void Core0_Task1( void * pvParameters )
  376. {
  377. for(;;)
  378. {
  379. #if THREAD_INFO
  380. PrintLine(60);
  381. PrintMSG("ESP32","CORE", "Wykonuje watek TASK1 na CORE0");
  382. #endif
  383.  
  384. timeClient.update();
  385.  
  386. unsigned long epochTime = timeClient.getEpochTime();
  387. struct tm *ptm = gmtime ((time_t *)&epochTime);
  388.  
  389. zegar.Godzina = timeClient.getHours();
  390. zegar.Minuta = timeClient.getMinutes();
  391. zegar.Sekunda = timeClient.getSeconds();
  392. zegar.SformatowanyCzas = timeClient.getFormattedTime();
  393. zegar.DzienTygodnia = timeClient.getDay();
  394. zegar.DzienMiesiaca = ptm->tm_mday;
  395. zegar.Miesiac = ptm->tm_mon+1;
  396. zegar.Rok = ptm->tm_year+1900;
  397.  
  398. if (zegar.Godzina < 10)
  399. {
  400. zegar.SformatowanyCzasHM = "0" + String (zegar.Godzina) + ":";
  401. }
  402. else zegar.SformatowanyCzasHM = String(zegar.Godzina) + ":";
  403.  
  404. if (zegar.Minuta < 10)
  405. {
  406. zegar.SformatowanyCzasHM += "0" + String (zegar.Minuta) + ":";
  407. }
  408. else zegar.SformatowanyCzasHM += String(zegar.Minuta);
  409.  
  410.  
  411. if (zegar.Rok !=1970)
  412. {
  413. if(zegar.DzienMiesiaca < 10)
  414. {
  415. zegar.SformatowanaData = "0" + String(zegar.DzienMiesiaca) + ".";
  416. zegar.SformatowanaDataPL = "0" + String(zegar.DzienMiesiaca) + " ";
  417. }
  418. else
  419. {
  420. zegar.SformatowanaData = String(zegar.DzienMiesiaca) + ".";
  421. zegar.SformatowanaDataPL = String(zegar.DzienMiesiaca) + " ";
  422. }
  423.  
  424. if(zegar.Miesiac < 10)
  425. {
  426. zegar.SformatowanaData += "0" + String(zegar.Miesiac) + ".";
  427. zegar.SformatowanaDataPL += String(MONTH[zegar.Miesiac]) + " ";
  428. }
  429. else
  430. {
  431. zegar.SformatowanaData += String(zegar.Miesiac) + ".";
  432. zegar.SformatowanaDataPL += String(MONTH[zegar.Miesiac]) + " ";
  433. }
  434.  
  435. zegar.SformatowanaData += String(zegar.Rok);
  436. zegar.SformatowanaDataPL += String(zegar.Rok);
  437.  
  438. // --- zapisz aktualny czas pobrany z serwera NTP do zegara RTC --------------------------------------- //
  439.  
  440. rtc.setTime(zegar.Sekunda, zegar.Minuta, zegar.Godzina, zegar.DzienMiesiaca, zegar.Miesiac, zegar.Rok);
  441.  
  442. // --- zbuduj obiekty typu (JSON STRING) do odesłania na żadanie do innego ESP w sieci MESH
  443.  
  444. jmsg.czas = "{\"ID\":\"ROOT\",\"CODE\":1001,\"CZAS\":\"" + zegar.SformatowanyCzas + "\"}";
  445. jmsg.czasHM = "{\"ID\":\"ROOT\",\"CODE\":1002,\"CZAS\":\"" + zegar.SformatowanyCzasHM + "\"}";
  446. jmsg.data = "{\"ID\":\"ROOT\",\"CODE\":1011,\"DATA\":\"" + zegar.SformatowanaData + "\"}";
  447. jmsg.dataPL = "{\"ID\":\"ROOT\",\"CODE\":1012,\"DATA\":\"" + zegar.SformatowanaDataPL + "\"}";
  448.  
  449. #if CORE0_TASK1
  450. PrintLine(60);
  451. PrintMSG("CORE0_TASK1", "NTP Time", zegar.SformatowanyCzas.c_str());
  452. PrintMSG("CORE0_TASK1", "NTP Date", zegar.SformatowanaData.c_str());
  453. Serial.printf("\n[CORE0_TASK1] [RTC Time] ");
  454. Serial.print(rtc.getTime());
  455. Serial.printf("\n[CORE0_TASK1] [RTC Date] ");
  456. Serial.print(rtc.getDate());
  457. Serial.printf("\n[CORE0_TASK1] [FREE RAM] ");
  458. Serial.print(ESP.getFreeHeap());
  459. PrintLine(60);
  460. PrintEND();
  461. #endif
  462.  
  463. F_Zegar = true; // dane OK, flaga na true
  464. }
  465. else F_Zegar = false; // dane złe, flaga na false
  466.  
  467. vTaskDelay(60000 / portTICK_PERIOD_MS); // wykonuj 1 minutę
  468. }
  469. }
  470. //
  471. // ------------------------------------------------------------------------------------------------------------ //
  472. // --- CORE0 TASK2 POBIERANIE ASTRONOMII --- //
  473. // ------------------------------------------------------------------------------------------------------------ //
  474. //
  475. void Core0_Task2( void * pvParameters ) // Rdzeń 0 Zadanie 1
  476. { // początek
  477. for(;;) // nieskończona pętla
  478. { // początek FOR
  479. delay(3600000); // sprawdzaj co 1 godzinę
  480. }
  481. }
  482. //
  483. // ------------------------------------------------------------------------------------------------------------ //
  484. // --- CORE1 TASK1
  485. // ------------------------------------------------------------------------------------------------------------ //
  486.  
  487. void Core1_Task1( void * pvParameters ) // Rdzeń 0 Zadanie 1
  488. { // początek
  489. for(;;) // nieskończona pętla
  490. { // początek FOR
  491. #if SERIAL
  492. PrintLine(60);
  493. PrintMSG("ESP32","CORE", "Wykonuje watek Task1 na CORE-1");
  494. #endif
  495.  
  496. delay(1800000); // wykonuj co 30 minut
  497. }
  498. }
  499.  
  500. // ------------------------------------------------------------------------------------------------------------ //
  501. // --- CORE1 TASK2
  502. // ------------------------------------------------------------------------------------------------------------ //
  503.  
  504. void Core1_Task2( void * pvParameters ) // Rdzeń 0 Zadanie 1
  505. { // początek
  506. for(;;) // nieskończona pętla
  507. { // początek FOR
  508. #if SERIAL
  509. PrintLine(60);
  510. PrintMSG("ESP32","CORE", "Wykonuje watek Task2 na CORE-1");
  511. #endif
  512.  
  513. mesh.sendBroadcast( root.c_str() ); // roześlij Broadcast co wszystkich w sieci MESH
  514. delay(900000); // wykonuj co 15 minut
  515. }
  516. }
  517.  
  518. // ------------------------------------------------------------------------------------------------------------ //
  519. // --- p o b i e r z a d r e s I P ----------------------------------------------------------------------- //
  520. // ------------------------------------------------------------------------------------------------------------ //
  521.  
  522. IPAddress getlocalIP()
  523. {
  524. return IPAddress(mesh.getStationIP());
  525. }
  526.  
  527. // ------------------------------------------------------------------------------------------------------------ //
  528. // --- Aktualizacja Pogody z Serwera ------------------------------------------------------------------------- //
  529. // ------------------------------------------------------------------------------------------------------------ //
  530. //
  531. String httpGETRequest(const char* serverName)
  532. {
  533. HTTPClient http;
  534. http.begin(serverName);
  535. int httpResponseCode = http.GET();
  536. String bufor = "{}";
  537.  
  538. if ( httpResponseCode > 0 )
  539. {
  540. #if SERIAL
  541. //Serial.print("\nHTTP Response code: ");
  542. //Serial.print(httpResponseCode);
  543. #endif
  544.  
  545. bufor = http.getString();
  546. }
  547. else
  548. {
  549. #if SERIAL
  550. //Serial.print("Error code: ");
  551. //Serial.println(httpResponseCode);
  552. #endif
  553. }
  554. http.end();
  555. return bufor;
  556. }
  557. //
  558. // ------------------------------------------------------------------------------------------------------------ //
  559. // --- A K T U A L I Z A C J A P O G O D Y --- //
  560. // ------------------------------------------------------------------------------------------------------------ //
  561. //
  562. void PogodaAktualizuj()
  563. {
  564. PrintLine(60);
  565. PrintMSG("ESP32","MyTask", "Aktualizję pogodę z serwera : api.weatherapi.com");
  566.  
  567. String path = "http://api.weatherapi.com/v1/current.json?key=d27d7ab450e84466822133129211704&q=Mieroszow&aqi=no";
  568. String jsonBuffer = httpGETRequest(path.c_str());
  569.  
  570. JSON_Weather = JSON.parse(jsonBuffer);
  571.  
  572. if (JSON.typeof(JSON_Weather) == "undefined")
  573. {
  574. PrintLine(60);
  575. PrintMSG("DarkNet", "POGODA PARSER", "BŁĄD, BRAK DANYCH" );
  576. }
  577.  
  578. pogoda.miejscowosc = JSON_Weather["location"]["name"];
  579. pogoda.kraj = JSON_Weather["location"]["country"];
  580. pogoda.szerokosc_geograficzna = JSON_Weather["location"]["lat"];
  581. pogoda.dlugosc_geograficzna = JSON_Weather["location"]["lon"];
  582. pogoda.id = JSON_Weather["location"]["tz_id"];
  583. pogoda.czas_epoch = JSON_Weather["location"]["localtime_epoch"];
  584. pogoda.czas_lokalny = JSON_Weather["location"]["localtime"];
  585. pogoda.ostatnia_aktualizacja = JSON_Weather["current"]["last_updated"];
  586. pogoda.temperatura_C = JSON_Weather["current"]["temp_c"];
  587. pogoda.temperatura_C_odczuwalna = JSON_Weather["current"]["feelslike_c"];
  588. pogoda.kondycja = JSON_Weather["current"]["condition"]["text"];
  589. pogoda.predkosc_wiatru_kph = JSON_Weather["current"]["wind_kph"];
  590. pogoda.kierunek_wiatru_stopnie = JSON_Weather["current"]["wind_degree"];
  591. pogoda.kierunek_wiatru_kompas = JSON_Weather["current"]["wind_dir"];
  592. pogoda.podmuchy_wiatru = JSON_Weather["current"]["gust_kph"];
  593. pogoda.cisnienie = JSON_Weather["current"]["pressure_mb"];
  594. pogoda.opady = JSON_Weather["current"]["precip_mm"];
  595. pogoda.wilgotnosc = JSON_Weather["current"]["humidity"];
  596. pogoda.zachmurzenie = JSON_Weather["current"]["cloud"];
  597. pogoda.widzialnosc = JSON_Weather["current"]["vis_km"];
  598. pogoda.index_uv = JSON_Weather["current"]["uv"];
  599.  
  600. if(pogoda.miejscowosc == "Lubin")
  601. {
  602. PrintLine(60);
  603. Serial.printf("\n[DarkNet] [Pogoda] Miejscowość \t\t: ");
  604. Serial.print(pogoda.miejscowosc);
  605. Serial.printf("\n[DarkNet] [Pogoda] Kraj \t\t: ");
  606. Serial.print(pogoda.kraj);
  607. Serial.printf("\n[DarkNet] [Pogoda] Szer.Geograficzna \t: %2.2f",pogoda.szerokosc_geograficzna);
  608. Serial.printf("\n[DarkNet] [Pogoda] Dług.Geograficzna \t: %2.2f",pogoda.dlugosc_geograficzna);
  609. Serial.printf("\n[DarkNet] [Pogoda] Czas Epoch \t\t: %u",pogoda.czas_epoch );
  610. Serial.printf("\n[DarkNet] [Pogoda] Serwer ID \t\t: ");
  611. Serial.print( pogoda.id );
  612. Serial.printf("\n[DarkNet] [Pogoda] Czas Epoch \t\t: %u",pogoda.czas_epoch );
  613. Serial.printf("\n[DarkNet] [Pogoda] Czas Lokalny \t: ");
  614. Serial.print( pogoda.czas_lokalny );
  615. Serial.printf("\n[DarkNet] [Pogoda] Aktualizacja \t: ");
  616. Serial.print( pogoda.ostatnia_aktualizacja );
  617. Serial.printf("\n[DarkNet] [Pogoda] Temperatura \t\t: %2.2f",pogoda.temperatura_C);
  618. Serial.printf("\n[DarkNet] [Pogoda] Temp.Odczuwalna \t: %2.2f",pogoda.temperatura_C_odczuwalna);
  619. Serial.printf("\n[DarkNet] [Pogoda] Opis pogody \t\t: ");
  620. Serial.print(pogoda.kondycja);
  621. Serial.printf("\n[DarkNet] [Pogoda] Predkosc wiatru \t: %2.2f",pogoda.predkosc_wiatru_kph);
  622. Serial.printf("\n[DarkNet] [Pogoda] Podmuchy wiatru \t: %2.2f",pogoda.podmuchy_wiatru);
  623. Serial.printf("\n[DarkNet] [Pogoda] Kierunek wiatru \t: %2.2f",pogoda.kierunek_wiatru_stopnie);
  624. Serial.printf("\n[DarkNet] [Pogoda] Kierunek wiatru \t: ");
  625. Serial.print(pogoda.kierunek_wiatru_kompas);
  626. Serial.printf("\n[DarkNet] [Pogoda] Cisnienie \t\t: %d",pogoda.cisnienie);
  627. Serial.printf("\n[DarkNet] [Pogoda] Opady deszczu \t: %2.2f",pogoda.opady);
  628. Serial.printf("\n[DarkNet] [Pogoda] Wilgotnosc \t\t: %d",pogoda.wilgotnosc);
  629. Serial.printf("\n[DarkNet] [Pogoda] Zachmurzenie \t: %d",pogoda.zachmurzenie);
  630. Serial.printf("\n[DarkNet] [Pogoda] Widzialnosc \t\t: %d",pogoda.widzialnosc);
  631. Serial.printf("\n[DarkNet] [Pogoda] Index UV \t\t: %d",pogoda.index_uv);
  632.  
  633. PrintLine(60);
  634. PrintEND();
  635.  
  636. F_Pogoda = true; // dane OK, ustaw flagę na true
  637. }
  638. else F_Pogoda = false; // dane ZŁE, ustaw flagę na false
  639.  
  640. }
  641. //
  642. // ------------------------------------------------------------------------------------------------------------ //
  643. // --- A K T U A L I Z A C J A A S T R O N O M I I --- //
  644. // ------------------------------------------------------------------------------------------------------------ //
  645. //
  646. void AstronomiaAktualizuj()
  647. {
  648. PrintLine(60);
  649. PrintMSG("ESP32","MyTask", "Aktualizję astronomię z serwera : api.weatherapi.com");
  650.  
  651. // pobierz dane astronomiczne z serwera dla miasta LUBIN
  652.  
  653. String path = "http://api.weatherapi.com/v1/astronomy.json?key=d27d7ab450e84466822133129211704&q=Mieroszow&dt=2021-04-17";
  654. String jsonBuffer = httpGETRequest(path.c_str());
  655.  
  656. JSON_Astronomy = JSON.parse(jsonBuffer);
  657.  
  658. if (JSON.typeof(JSON_Astronomy) == "undefined")
  659. {
  660. PrintLine(60);
  661. PrintMSG("DarkNet", "ASTRONOMIA PARSER", "BŁĄD, BRAK DANYCH" );
  662. }
  663.  
  664. astronomia.miejscowosc = JSON_Astronomy["location"]["name"];
  665. astronomia.kraj = JSON_Astronomy["location"]["country"];
  666. astronomia.szerokosc_geograficzna = JSON_Astronomy["location"]["lat"];
  667. astronomia.dlugosc_geograficzna = JSON_Astronomy["location"]["lon"];
  668. astronomia.czas_epoch = JSON_Astronomy["location"]["localtime_epoch"];
  669. astronomia.czas_lokalny = JSON_Astronomy["location"]["localtime"];
  670. astronomia.wschod_slonca = JSON_Astronomy["astronomy"]["astro"]["sunrise"];
  671. astronomia.zachod_slonca = JSON_Astronomy["astronomy"]["astro"]["sunset"];
  672. astronomia.wschod_ksiezyca = JSON_Astronomy["astronomy"]["astro"]["moonrise"];
  673. astronomia.zachod_ksiezyca = JSON_Astronomy["astronomy"]["astro"]["moonset"];
  674. astronomia.faza_ksiezyca = JSON_Astronomy["astronomy"]["astro"]["moon_phase"];
  675. astronomia.oswietlenie_ksiezyca = JSON_Astronomy["astronomy"]["astro"]["moon_illumination"];
  676.  
  677. if(astronomia.miejscowosc == "Lubin")
  678. {
  679. PrintLine(60);
  680. Serial.printf("\n[DarkNet] [Astronomia] Miejscowość \t\t: ");
  681. Serial.print(astronomia.miejscowosc);
  682. Serial.printf("\n[DarkNet] [Astronomia] Kraj \t\t\t: ");
  683. Serial.print(astronomia.kraj);
  684. Serial.printf("\n[DarkNet] [Astronomia] Szer.Geograficzna \t: %2.2f",astronomia.szerokosc_geograficzna);
  685. Serial.printf("\n[DarkNet] [Astronomia] Dług.Geograficzna \t: %2.2f",astronomia.dlugosc_geograficzna);
  686. Serial.printf("\n[DarkNet] [Astronomia] Czas Epoch \t\t: %u",astronomia.czas_epoch );
  687. Serial.printf("\n[DarkNet] [Astronomia] Czas Lokalny \t\t: ");
  688. Serial.print( astronomia.czas_lokalny );
  689. Serial.printf("\n[DarkNet] [Astronomia] Wschód Słońca \t\t: ");
  690. Serial.print(astronomia.wschod_slonca );
  691. Serial.printf("\n[DarkNet] [Astronomia] Zachód Słońca \t\t: ");
  692. Serial.print(astronomia.zachod_slonca );
  693. Serial.printf("\n[DarkNet] [Astronomia] Wschód Księżyca \t\t: ");
  694. Serial.print(astronomia.wschod_ksiezyca );
  695. Serial.printf("\n[DarkNet] [Astronomia] Zachód Księżyca \t\t: ");
  696. Serial.print(astronomia.zachod_ksiezyca );
  697. Serial.printf("\n[DarkNet] [Astronomia] Faza Księżyca \t\t: ");
  698. Serial.print(astronomia.faza_ksiezyca);
  699. Serial.printf("\n[DarkNet] [Astronomia] Oświetlenie Księżyca \t: ");
  700. Serial.print(astronomia.oswietlenie_ksiezyca );
  701. PrintLine(60);
  702. PrintEND();
  703. F_Astronomia = true; // dane OK, ustaw flagę na true
  704. }
  705. else F_Astronomia = false; // dane ZŁE, ustaw flagę na false
  706. }
  707. //
  708. // ------------------------------------------------------------------------------------------------------------ //
  709. // --- A K T U A L I Z A C J A J A K O Ś C I P O W I E T R Z A --- //
  710. // ------------------------------------------------------------------------------------------------------------ //
  711. //
  712. void PowietrzeAktualizuj()
  713. {
  714. PrintLine(60);
  715. PrintMSG("ESP32","MyTask", "Aktualizję jakość powietrza z serwera : api.weatherapi.com");
  716.  
  717. // pobierz dane jakości powietrza z serwera dla miasta LUBIN
  718.  
  719. String path = "http://api.weatherapi.com/v1/current.json?key=d27d7ab450e84466822133129211704&q=Mieroszow&aqi=yes";
  720. String jsonBuffer = httpGETRequest(path.c_str());
  721.  
  722. JSON_Air = JSON.parse(jsonBuffer);
  723.  
  724. if (JSON.typeof(JSON_Air) == "undefined")
  725. {
  726. PrintLine(60);
  727. PrintMSG("DarkNet", "AIR PARSER", "BŁĄD, BRAK DANYCH" );
  728. }
  729.  
  730. powietrze.co = JSON_Air["current"]["air_quality"]["co"];
  731. powietrze.o3 = JSON_Air["current"]["air_quality"]["o3"];
  732. powietrze.no2 = JSON_Air["current"]["air_quality"]["no2"];
  733. powietrze.so2 = JSON_Air["current"]["air_quality"]["so2"];
  734. powietrze.pm25 = JSON_Air["current"]["air_quality"]["pm2_5"];
  735. powietrze.pm10 = JSON_Air["current"]["air_quality"]["pm10"];
  736. powietrze.Defra = JSON_Air["current"]["air_quality"]["gb-defra-index"];
  737.  
  738. if (powietrze.co != 0)
  739. {
  740. PrintLine(60);
  741. Serial.printf("\n[DarkNet] [Jakość Powietrza] Tlenek węgla \t\t: %2.8f [μg/ m3]", powietrze.co);
  742. Serial.printf("\n[DarkNet] [Jakość Powietrza] Dwutlenek azotu \t\t: %2.8f [μg/ m3]", powietrze.no2);
  743. Serial.printf("\n[DarkNet] [Jakość Powietrza] Ozon \t\t\t: %2.8f [μg/m3]", powietrze.o3);
  744. Serial.printf("\n[DarkNet] [Jakość Powietrza] Pyły i aerozole PM2.5 \t: %2.8f [μm]", powietrze.pm25);
  745. Serial.printf("\n[DarkNet] [Jakość Powietrza] Pyły i aerozole PM10 \t: %2.8f [μm]", powietrze.pm10);
  746. Serial.printf("\n[DarkNet] [Jakość Powietrza] Index jakości \t\t: %d IND", powietrze.Defra);
  747. PrintLine(60);
  748. PrintEND();
  749.  
  750. F_Powietrze = true;
  751. }
  752. else F_Powietrze = false;
  753. }
  754. //
  755. // ------------------------------------------------------------------------------------------------------------ //
  756. // --- A K T U A L I Z A C J A P R O G N O Z Ę --- //
  757. // ------------------------------------------------------------------------------------------------------------ //
  758. //
  759. void PrognozaAktualizuj()
  760. {
  761. PrintLine(60);
  762. PrintMSG("ESP32","MyTask", "Aktualizję prognozę z serwera : api.weatherapi.com");
  763.  
  764. // pobierz dane astronomiczne z serwera dla miasta LUBIN
  765.  
  766. String path = "http://api.weatherapi.com/v1/forecast.json?key=d27d7ab450e84466822133129211704&q=Mieroszow&days=1&aqi=no&alerts=no";
  767. String jsonBuffer = httpGETRequest(path.c_str());
  768.  
  769. JSON_Forecast = JSON.parse(jsonBuffer);
  770.  
  771. if (JSON.typeof(JSON_Forecast) == "undefined")
  772. {
  773. PrintLine(60);
  774. PrintMSG("DarkNet", "AIR PARSER", "BŁĄD, BRAK DANYCH" );
  775. }
  776. }
  777. //
  778. // ------------------------------------------------------------------------------------------------------------ //
  779. // --- MyTask ------------------------------------------------------------------------------------------------- //
  780. // ------------------------------------------------------------------------------------------------------------ //
  781. //
  782. void MyTask()
  783. {
  784. timeZERO = millis(); // zapisz czas 0
  785. task01m = timeZERO - timeout_task01m; // wyznacz nowy
  786. task05m = timeZERO - timeout_task05m; // wyznacz nowy
  787. task10m = timeZERO - timeout_task10m; // wyznacz nowy
  788. task15m = timeZERO - timeout_task15m; // wyznacz nowy
  789.  
  790. // --- ZADANIE co 1 minutę ------------------------------------------------------------------------------- //
  791.  
  792. if(task01m >= 60000UL) // wykonuj co 1 minutę
  793. {
  794. if (!F_Astronomia) AstronomiaAktualizuj(); // jeśli BRAK DANYCH wykonuj co minutę
  795. if (!F_Pogoda) PogodaAktualizuj(); // jeśli BRAK DANYCH wykonuj co minutę
  796. if (!F_Powietrze) PowietrzeAktualizuj(); // jeśli BRAK DANYCH wykonuj co minutę
  797. //if (!F_Prognoza) PrognozaAktualizuj(); // jeśli BRAK DANYCH wykonuj co minutę
  798.  
  799. timeout_task01m = timeZERO;
  800. }
  801.  
  802. // --- ZADANIE co 5 minut -------------------------------------------------------------------------------- //
  803.  
  804. if(task05m >= 300000UL) // wykonuj co 5 minut
  805. {
  806. timeout_task05m = timeZERO;
  807. }
  808.  
  809. // --- ZADANIE co 10 minut ------------------------------------------------------------------------------- //
  810.  
  811. if(task10m >= 600000UL) // wykonuj co 10 minut
  812. {
  813. timeout_task10m = timeZERO;
  814. }
  815.  
  816. // --- ZADANIE co 15 minut ------------------------------------------------------------------------------- //
  817.  
  818. if(task15m >= 900000UL) // wykonuj co 15 minut
  819. {
  820. if (F_Astronomia) AstronomiaAktualizuj(); // jeśli DANE OK co 15 minut
  821. if (F_Pogoda) PogodaAktualizuj(); // jeśli DANE OK co 15 minut
  822. if (F_Powietrze) PowietrzeAktualizuj(); // jeśli DANE OK co 15 minut
  823. //if (F_Prognoza) PrognozaAktualizuj(); // jeśli BRAK DANYCH wykonuj co minutę
  824.  
  825. timeout_task15m = timeZERO;
  826. }
  827.  
  828. }
  829. //
  830. // ------------------------------------------------------------------------------------------------------------ //
  831. // --- S E T U P ---------------------------------------------------------------------------------------------- //
  832. // ------------------------------------------------------------------------------------------------------------ //
  833. //
  834. void setup()
  835. {
  836. #if SERIAL
  837. Serial.begin(SPEED); // ustaw prędkość terminala SERIAL
  838. #endif
  839.  
  840. mesh.setDebugMsgTypes( ERROR | STARTUP | CONNECTION ); // ustaw przed init (), abyś mógł zobaczyć komunikaty startowe
  841.  
  842. mesh.init( MESH_PREFIX, MESH_PASSWORD, MESH_PORT, WIFI_AP_STA, 6 );
  843. mesh.onReceive(&receivedCallback);
  844. mesh.stationManual(STATION_SSID, STATION_PASSWORD);
  845. mesh.setHostname(HOSTNAME);
  846.  
  847. mesh.setRoot(true); // sieć MESH na tym urządzeniu jako ROOT
  848. mesh.setContainsRoot(true); // sieć MESH na tym urządzeniu jako ROOT
  849.  
  850. timeClient.begin(); // włącz klienta NTP (pobieranie czasu z internetu)
  851.  
  852. // --- CPU_Core_0 ----------------------------------------------------------------------------------
  853.  
  854. xTaskCreatePinnedToCore(Core0_Task1, "CPU_Core_0", 5000, NULL, 1, &CPU_Core_0, 0);
  855. vTaskDelay(500 / portTICK_PERIOD_MS);
  856.  
  857. xTaskCreatePinnedToCore(Core0_Task2, "CPU_Core_0", 5000, NULL, 1, &CPU_Core_0, 0);
  858. vTaskDelay(500 / portTICK_PERIOD_MS);
  859.  
  860. // --- CPU_Core_1 ----------------------------------------------------------------------------------
  861.  
  862. xTaskCreatePinnedToCore(Core1_Task1, "CPU_Core_1", 5000, NULL, 1, &CPU_Core_1, 1);
  863. vTaskDelay(500 / portTICK_PERIOD_MS);
  864.  
  865. xTaskCreatePinnedToCore(Core1_Task2, "CPU_Core_1", 5000, NULL, 1, &CPU_Core_1, 1);
  866. vTaskDelay(500 / portTICK_PERIOD_MS);
  867. }
  868.  
  869. // ------------------------------------------------------------------------------------------------------------ //
  870. // --- L O O P ------------------------------------------------------------------------------------------------ //
  871. // ------------------------------------------------------------------------------------------------------------ //
  872. //
  873. void loop()
  874. {
  875. mesh.update(); // aktulizuj MESH
  876. mqttClient.loop(); // pętla dla klienta mqtt
  877.  
  878. if(myIP != getlocalIP()) // jeśli moje IP różne od lokalnego IP
  879. {
  880. myIP = getlocalIP(); // zapisz lokalne IP
  881.  
  882. #if SERIAL
  883. Serial.println("Adres lokalny IP: " + myIP.toString());
  884. #endif
  885.  
  886. if (mqttClient.connect("painlessMeshClient")) // jeśli client
  887. {
  888. mqttClient.publish("painlessMesh/from/gateway","Gotowe!");
  889. mqttClient.subscribe("painlessMesh/to/#");
  890. }
  891. }
  892.  
  893. MyTask();
  894. }
  895. //
  896. // ------------------------------------------------------------------------------------------------------------ //
  897. // --- E N D ------------------------------------------------------------------------------------------------- //
  898. // ------------------------------------------------------------------------------------------------------------ //
  899.  
Advertisement
Add Comment
Please, Sign In to add comment