FlipperHTTP.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. // FlipperHTTP.h for flipper-http.ino
  2. #include <WiFi.h>
  3. #include <HTTPClient.h>
  4. #include <WiFiClientSecure.h>
  5. #include "SPIFFS.h"
  6. #include <ArduinoJson.h>
  7. #include <Arduino.h>
  8. #include <ArduinoHttpClient.h>
  9. #define B_PIN 4 // Blue
  10. #define G_PIN 5 // Green
  11. #define R_PIN 6 // Red
  12. #define ON LOW
  13. #define OFF HIGH
  14. class FlipperHTTP
  15. {
  16. public:
  17. // Constructor
  18. FlipperHTTP()
  19. {
  20. }
  21. // Main methods for flipper-http.ino
  22. void setup();
  23. void loop();
  24. // HTTP Methods
  25. String get(String url);
  26. String get(String url, const char *headerKeys[], const char *headerValues[], int headerSize);
  27. String post(String url, String payload);
  28. String post(String url, String payload, const char *headerKeys[], const char *headerValues[], int headerSize);
  29. String put(String url, String payload);
  30. String put(String url, String payload, const char *headerKeys[], const char *headerValues[], int headerSize);
  31. String delete_request(String url, String payload);
  32. String delete_request(String url, String payload, const char *headerKeys[], const char *headerValues[], int headerSize);
  33. // Save and Load settings to and from SPIFFS
  34. bool saveWifiSettings(String data);
  35. bool loadWifiSettings();
  36. // Connect to Wifi using the loaded SSID and Password
  37. bool connectToWifi();
  38. // Check if the Dev Board is connected to Wifi
  39. bool isConnectedToWifi() { return WiFi.status() == WL_CONNECTED; }
  40. // Read serial data until newline character
  41. String readSerialLine();
  42. // Clear serial buffer to avoid any residual data
  43. void clearSerialBuffer()
  44. {
  45. while (Serial.available() > 0)
  46. {
  47. Serial.read();
  48. }
  49. }
  50. // Turn on and off the LED
  51. void ledAction(int pin = G_PIN, int timeout = 250)
  52. {
  53. digitalWrite(pin, ON);
  54. delay(timeout);
  55. digitalWrite(pin, OFF);
  56. delay(timeout);
  57. }
  58. // Display LED sequence when Wifi Board is first connected to the Flipper
  59. void ledStart()
  60. {
  61. pinMode(B_PIN, OUTPUT); // Set Blue Pin mode as output
  62. pinMode(G_PIN, OUTPUT); // Set Green Pin mode as output
  63. pinMode(R_PIN, OUTPUT); // Set Red Pin mode as output
  64. digitalWrite(B_PIN, OFF);
  65. digitalWrite(R_PIN, OFF);
  66. ledAction();
  67. ledAction();
  68. ledAction();
  69. }
  70. // Starting LED (Green only)
  71. void ledStatus()
  72. {
  73. digitalWrite(B_PIN, OFF);
  74. digitalWrite(R_PIN, OFF);
  75. digitalWrite(G_PIN, ON);
  76. }
  77. // Turn off all LEDs
  78. void ledOff()
  79. {
  80. digitalWrite(B_PIN, OFF);
  81. digitalWrite(G_PIN, OFF);
  82. digitalWrite(R_PIN, OFF);
  83. }
  84. private:
  85. const char *settingsFilePath = "/flipper-http.json"; // Path to the settings file in the SPIFFS file system
  86. char loadedSSID[64] = {0}; // Variable to store SSID
  87. char loadedPassword[64] = {0}; // Variable to store password
  88. bool readSerialSettings(String receivedData, bool connectAfterSave);
  89. };
  90. // Connect to Wifi using the loaded SSID and Password
  91. bool FlipperHTTP::connectToWifi()
  92. {
  93. if (String(loadedSSID) == "" || String(loadedPassword) == "")
  94. {
  95. Serial.println("[ERROR] WiFi SSID or Password is empty.");
  96. return false;
  97. }
  98. WiFi.disconnect(true); // Ensure WiFi is disconnected before reconnecting
  99. WiFi.begin(loadedSSID, loadedPassword);
  100. int i = 0;
  101. while (!this->isConnectedToWifi() && i < 20)
  102. {
  103. delay(500);
  104. i++;
  105. Serial.print(".");
  106. }
  107. Serial.println(); // Move to next line after dots
  108. if (this->isConnectedToWifi())
  109. {
  110. Serial.println("[SUCCESS] Successfully connected to Wifi.");
  111. return true;
  112. }
  113. else
  114. {
  115. Serial.println("[ERROR] Failed to connect to Wifi.");
  116. return false;
  117. }
  118. }
  119. // Save Wifi settings to SPIFFS
  120. bool FlipperHTTP::saveWifiSettings(String jsonData)
  121. {
  122. File file = SPIFFS.open(settingsFilePath, FILE_WRITE);
  123. if (!file)
  124. {
  125. Serial.println("[ERROR] Failed to open file for writing.");
  126. return false;
  127. }
  128. file.print(jsonData);
  129. file.close();
  130. Serial.println("[SUCCESS] Settings saved to SPIFFS.");
  131. return true;
  132. }
  133. // Load Wifi settings from SPIFFS
  134. bool FlipperHTTP::loadWifiSettings()
  135. {
  136. File file = SPIFFS.open(settingsFilePath, FILE_READ);
  137. if (!file)
  138. {
  139. Serial.println("[ERROR] Failed to open file for reading.");
  140. return "";
  141. }
  142. // Read the entire file content
  143. String fileContent = file.readString();
  144. file.close();
  145. return fileContent;
  146. }
  147. String FlipperHTTP::readSerialLine()
  148. {
  149. String receivedData = "";
  150. while (Serial.available() > 0)
  151. {
  152. char incomingChar = Serial.read();
  153. if (incomingChar == '\n')
  154. {
  155. break;
  156. }
  157. receivedData += incomingChar;
  158. delay(1); // Minimal delay to allow buffer to fill
  159. }
  160. receivedData.trim(); // Remove any leading/trailing whitespace
  161. return receivedData;
  162. }
  163. bool FlipperHTTP::readSerialSettings(String receivedData, bool connectAfterSave)
  164. {
  165. DynamicJsonDocument doc(1024);
  166. DeserializationError error = deserializeJson(doc, receivedData);
  167. if (error)
  168. {
  169. Serial.print("[ERROR] Failed to parse JSON: ");
  170. Serial.println(error.c_str());
  171. return false;
  172. }
  173. // Extract values from JSON
  174. if (doc.containsKey("ssid") && doc.containsKey("password"))
  175. {
  176. strlcpy(loadedSSID, doc["ssid"], sizeof(loadedSSID));
  177. strlcpy(loadedPassword, doc["password"], sizeof(loadedPassword));
  178. }
  179. else
  180. {
  181. Serial.println("[ERROR] JSON does not contain ssid and password.");
  182. return false;
  183. }
  184. // Save to SPIFFS
  185. if (!this->saveWifiSettings(receivedData))
  186. {
  187. Serial.println("[ERROR] Failed to save settings to file.");
  188. return false;
  189. }
  190. // Attempt to reconnect with new settings
  191. if (connectAfterSave && this->connectToWifi())
  192. {
  193. Serial.println("[SUCCESS] Connected to the new Wifi network.");
  194. }
  195. else
  196. {
  197. Serial.println("[WARNING] Saved settings but failed to connect.");
  198. }
  199. return true;
  200. }
  201. String FlipperHTTP::get(String url)
  202. {
  203. WiFiClientSecure client;
  204. client.setInsecure(); // Bypass certificate validation
  205. HTTPClient http;
  206. String payload = "";
  207. if (http.begin(client, url))
  208. {
  209. int httpCode = http.GET();
  210. if (httpCode > 0)
  211. {
  212. payload = http.getString();
  213. http.end();
  214. return payload;
  215. }
  216. else
  217. {
  218. Serial.print("[ERROR] GET Request Failed, error: ");
  219. Serial.println(http.errorToString(httpCode).c_str());
  220. }
  221. http.end();
  222. }
  223. else
  224. {
  225. Serial.println("[ERROR] Unable to connect to the server.");
  226. }
  227. // Clear serial buffer to avoid any residual data
  228. this->clearSerialBuffer();
  229. return payload;
  230. }
  231. String FlipperHTTP::get(String url, const char *headerKeys[], const char *headerValues[], int headerSize)
  232. {
  233. WiFiClientSecure client;
  234. client.setInsecure(); // Bypass certificate
  235. HTTPClient http;
  236. String payload = "";
  237. http.collectHeaders(headerKeys, headerSize);
  238. if (http.begin(client, url))
  239. {
  240. for (int i = 0; i < headerSize; i++)
  241. {
  242. http.addHeader(headerKeys[i], headerValues[i]);
  243. }
  244. int httpCode = http.GET();
  245. if (httpCode > 0)
  246. {
  247. payload = http.getString();
  248. http.end();
  249. return payload;
  250. }
  251. else
  252. {
  253. Serial.print("[ERROR] GET Request Failed, error: ");
  254. Serial.println(http.errorToString(httpCode).c_str());
  255. }
  256. http.end();
  257. }
  258. else
  259. {
  260. Serial.println("[ERROR] Unable to connect to the server.");
  261. }
  262. // Clear serial buffer to avoid any residual data
  263. this->clearSerialBuffer();
  264. return payload;
  265. }
  266. String FlipperHTTP::delete_request(String url, String payload)
  267. {
  268. WiFiClientSecure client;
  269. client.setInsecure(); // Bypass certificate
  270. HTTPClient http;
  271. String response = "";
  272. if (http.begin(client, url))
  273. {
  274. int httpCode = http.sendRequest("DELETE", payload);
  275. if (httpCode > 0)
  276. {
  277. response = http.getString();
  278. http.end();
  279. return response;
  280. }
  281. else
  282. {
  283. Serial.print("[ERROR] DELETE Request Failed, error: ");
  284. Serial.println(http.errorToString(httpCode).c_str());
  285. }
  286. http.end();
  287. }
  288. else
  289. {
  290. Serial.println("[ERROR] Unable to connect to the server.");
  291. }
  292. // Clear serial buffer to avoid any residual data
  293. this->clearSerialBuffer();
  294. return response;
  295. }
  296. String FlipperHTTP::delete_request(String url, String payload, const char *headerKeys[], const char *headerValues[], int headerSize)
  297. {
  298. WiFiClientSecure client;
  299. client.setInsecure(); // Bypass certificate
  300. HTTPClient http;
  301. String response = "";
  302. http.collectHeaders(headerKeys, headerSize);
  303. if (http.begin(client, url))
  304. {
  305. for (int i = 0; i < headerSize; i++)
  306. {
  307. http.addHeader(headerKeys[i], headerValues[i]);
  308. }
  309. int httpCode = http.sendRequest("DELETE", payload);
  310. if (httpCode > 0)
  311. {
  312. response = http.getString();
  313. http.end();
  314. return response;
  315. }
  316. else
  317. {
  318. Serial.print("[ERROR] DELETE Request Failed, error: ");
  319. Serial.println(http.errorToString(httpCode).c_str());
  320. }
  321. http.end();
  322. }
  323. else
  324. {
  325. Serial.println("[ERROR] Unable to connect to the server.");
  326. }
  327. // Clear serial buffer to avoid any residual data
  328. this->clearSerialBuffer();
  329. return response;
  330. }
  331. String FlipperHTTP::post(String url, String payload, const char *headerKeys[], const char *headerValues[], int headerSize)
  332. {
  333. WiFiClientSecure client;
  334. client.setInsecure(); // Bypass certificate
  335. HTTPClient http;
  336. String response = "";
  337. http.collectHeaders(headerKeys, headerSize);
  338. if (http.begin(client, url))
  339. {
  340. for (int i = 0; i < headerSize; i++)
  341. {
  342. http.addHeader(headerKeys[i], headerValues[i]);
  343. }
  344. int httpCode = http.POST(payload);
  345. if (httpCode > 0)
  346. {
  347. response = http.getString();
  348. http.end();
  349. return response;
  350. }
  351. else
  352. {
  353. Serial.print("[ERROR] POST Request Failed, error: ");
  354. Serial.println(http.errorToString(httpCode).c_str());
  355. }
  356. http.end();
  357. }
  358. else
  359. {
  360. Serial.println("[ERROR] Unable to connect to the server.");
  361. }
  362. // Clear serial buffer to avoid any residual data
  363. this->clearSerialBuffer();
  364. return response;
  365. }
  366. String FlipperHTTP::post(String url, String payload)
  367. {
  368. WiFiClientSecure client;
  369. client.setInsecure(); // Bypass certificate
  370. HTTPClient http;
  371. String response = "";
  372. if (http.begin(client, url))
  373. {
  374. int httpCode = http.POST(payload);
  375. if (httpCode > 0)
  376. {
  377. response = http.getString();
  378. http.end();
  379. return response;
  380. }
  381. else
  382. {
  383. Serial.print("[ERROR] POST Request Failed, error: ");
  384. Serial.println(http.errorToString(httpCode).c_str());
  385. }
  386. http.end();
  387. }
  388. else
  389. {
  390. Serial.println("[ERROR] Unable to connect to the server.");
  391. }
  392. // Clear serial buffer to avoid any residual data
  393. this->clearSerialBuffer();
  394. return response;
  395. }
  396. String FlipperHTTP::put(String url, String payload, const char *headerKeys[], const char *headerValues[], int headerSize)
  397. {
  398. WiFiClientSecure client;
  399. client.setInsecure(); // Bypass certificate
  400. HTTPClient http;
  401. String response = "";
  402. http.collectHeaders(headerKeys, headerSize);
  403. if (http.begin(client, url))
  404. {
  405. for (int i = 0; i < headerSize; i++)
  406. {
  407. http.addHeader(headerKeys[i], headerValues[i]);
  408. }
  409. int httpCode = http.PUT(payload);
  410. if (httpCode > 0)
  411. {
  412. response = http.getString();
  413. http.end();
  414. return response;
  415. }
  416. else
  417. {
  418. Serial.print("[ERROR] PUT Request Failed, error: ");
  419. Serial.println(http.errorToString(httpCode).c_str());
  420. }
  421. http.end();
  422. }
  423. else
  424. {
  425. Serial.println("[ERROR] Unable to connect to the server.");
  426. }
  427. // Clear serial buffer to avoid any residual data
  428. this->clearSerialBuffer();
  429. return response;
  430. }
  431. String FlipperHTTP::put(String url, String payload)
  432. {
  433. WiFiClientSecure client;
  434. client.setInsecure(); // Bypass certificate
  435. HTTPClient http;
  436. String response = "";
  437. if (http.begin(client, url))
  438. {
  439. int httpCode = http.PUT(payload);
  440. if (httpCode > 0)
  441. {
  442. response = http.getString();
  443. http.end();
  444. return response;
  445. }
  446. else
  447. {
  448. Serial.print("[ERROR] PUT Request Failed, error: ");
  449. Serial.println(http.errorToString(httpCode).c_str());
  450. }
  451. http.end();
  452. }
  453. else
  454. {
  455. Serial.println("[ERROR] Unable to connect to the server.");
  456. }
  457. // Clear serial buffer to avoid any residual data
  458. this->clearSerialBuffer();
  459. return response;
  460. }
  461. void FlipperHTTP::setup()
  462. {
  463. Serial.begin(115200);
  464. // Initialize SPIFFS
  465. if (!SPIFFS.begin(true))
  466. {
  467. Serial.println("[ERROR] SPIFFS initialization failed.");
  468. ESP.restart();
  469. }
  470. this->ledStart();
  471. Serial.flush();
  472. }
  473. void FlipperHTTP::loop()
  474. {
  475. // Check if there's incoming serial data
  476. if (Serial.available() > 0)
  477. {
  478. // Read the incoming serial data until newline
  479. String _data = this->readSerialLine();
  480. if (_data.length() == 0)
  481. {
  482. // No complete command received
  483. return;
  484. }
  485. this->ledStatus();
  486. // Ping/Pong to see if board/flipper is connected
  487. if (_data.startsWith("[PING]"))
  488. {
  489. Serial.println("[PONG]");
  490. }
  491. // Handle [WIFI/SAVE] command
  492. else if (_data.startsWith("[WIFI/SAVE]"))
  493. {
  494. // Extract JSON data by removing the command part
  495. String jsonData = _data.substring(strlen("[WIFI/SAVE]"));
  496. jsonData.trim(); // Remove any leading/trailing whitespace
  497. // Parse and save the settings
  498. if (this->readSerialSettings(jsonData, true))
  499. {
  500. Serial.println("[SUCCESS] Wifi settings saved.");
  501. }
  502. else
  503. {
  504. Serial.println("[ERROR] Failed to save Wifi settings.");
  505. }
  506. }
  507. // Handle [WIFI/CONNECT] command
  508. else if (_data == "[WIFI/CONNECT]")
  509. {
  510. // Check if WiFi is already connected
  511. if (!this->isConnectedToWifi())
  512. {
  513. // Attempt to connect to Wifi
  514. if (this->connectToWifi())
  515. {
  516. Serial.println("[SUCCESS] Connected to Wifi.");
  517. }
  518. else
  519. {
  520. Serial.println("[ERROR] Failed to connect to Wifi.");
  521. }
  522. }
  523. else
  524. {
  525. Serial.println("[INFO] Already connected to Wifi.");
  526. }
  527. }
  528. // Handle [WIFI/DISCONNECT] command
  529. else if (_data == "[WIFI/DISCONNECT]")
  530. {
  531. WiFi.disconnect(true);
  532. Serial.println("[DISCONNECTED] Wifi has been disconnected.");
  533. }
  534. // Handle [GET] command
  535. else if (_data.startsWith("[GET]"))
  536. {
  537. if (!this->isConnectedToWifi() && !this->connectToWifi())
  538. {
  539. Serial.println("[ERROR] Not connected to Wifi. Failed to reconnect.");
  540. this->ledOff();
  541. return;
  542. }
  543. // Extract URL by removing the command part
  544. String url = _data.substring(strlen("[GET]"));
  545. url.trim();
  546. // GET request
  547. String getData = this->get(url);
  548. if (getData != "")
  549. {
  550. Serial.println("[GET/SUCCESS] GET request successful.");
  551. Serial.println(getData);
  552. Serial.flush();
  553. Serial.println();
  554. Serial.println("[GET/END]");
  555. }
  556. else
  557. {
  558. Serial.println("[ERROR] GET request failed or returned empty data.");
  559. }
  560. }
  561. // Handle [GET/HTTP] command
  562. else if (_data.startsWith("[GET/HTTP]"))
  563. {
  564. if (!this->isConnectedToWifi() && !this->connectToWifi())
  565. {
  566. Serial.println("[ERROR] Not connected to Wifi. Failed to reconnect.");
  567. this->ledOff();
  568. return;
  569. }
  570. // Extract the JSON by removing the command part
  571. String jsonData = _data.substring(strlen("[GET/HTTP]"));
  572. jsonData.trim();
  573. DynamicJsonDocument doc(1024);
  574. DeserializationError error = deserializeJson(doc, jsonData);
  575. if (error)
  576. {
  577. Serial.print("[ERROR] Failed to parse JSON.");
  578. this->ledOff();
  579. return;
  580. }
  581. // Extract values from JSON
  582. if (!doc.containsKey("url"))
  583. {
  584. Serial.println("[ERROR] JSON does not contain url.");
  585. this->ledOff();
  586. return;
  587. }
  588. String url = doc["url"];
  589. // Extract headers if available
  590. const char *headerKeys[10];
  591. const char *headerValues[10];
  592. int headerSize = 0;
  593. if (doc.containsKey("headers"))
  594. {
  595. JsonObject headers = doc["headers"];
  596. for (JsonPair header : headers)
  597. {
  598. headerKeys[headerSize] = header.key().c_str();
  599. headerValues[headerSize] = header.value();
  600. headerSize++;
  601. }
  602. }
  603. // GET request
  604. String getData = this->get(url, headerKeys, headerValues, headerSize);
  605. if (getData != "")
  606. {
  607. Serial.println("[GET/SUCCESS] GET request successful.");
  608. Serial.println(getData);
  609. Serial.flush();
  610. Serial.println();
  611. Serial.println("[GET/END]");
  612. }
  613. else
  614. {
  615. Serial.println("[ERROR] GET request failed or returned empty data.");
  616. }
  617. }
  618. // Handle [POST/HTTP] command
  619. else if (_data.startsWith("[POST/HTTP]"))
  620. {
  621. if (!this->isConnectedToWifi() && !this->connectToWifi())
  622. {
  623. Serial.println("[ERROR] Not connected to Wifi. Failed to reconnect.");
  624. this->ledOff();
  625. return;
  626. }
  627. // Extract the JSON by removing the command part
  628. String jsonData = _data.substring(strlen("[POST/HTTP]"));
  629. jsonData.trim();
  630. DynamicJsonDocument doc(1024);
  631. DeserializationError error = deserializeJson(doc, jsonData);
  632. if (error)
  633. {
  634. Serial.print("[ERROR] Failed to parse JSON.");
  635. this->ledOff();
  636. return;
  637. }
  638. // Extract values from JSON
  639. if (!doc.containsKey("url") || !doc.containsKey("payload"))
  640. {
  641. Serial.println("[ERROR] JSON does not contain url or payload.");
  642. this->ledOff();
  643. return;
  644. }
  645. String url = doc["url"];
  646. String payload = doc["payload"];
  647. // Extract headers if available
  648. const char *headerKeys[10];
  649. const char *headerValues[10];
  650. int headerSize = 0;
  651. if (doc.containsKey("headers"))
  652. {
  653. JsonObject headers = doc["headers"];
  654. for (JsonPair header : headers)
  655. {
  656. headerKeys[headerSize] = header.key().c_str();
  657. headerValues[headerSize] = header.value();
  658. headerSize++;
  659. }
  660. }
  661. // POST request
  662. String postData = this->post(url, payload, headerKeys, headerValues, headerSize);
  663. if (postData != "")
  664. {
  665. Serial.println("[POST/SUCCESS] POST request successful.");
  666. Serial.println(postData);
  667. Serial.flush();
  668. Serial.println();
  669. Serial.println("[POST/END]");
  670. }
  671. else
  672. {
  673. Serial.println("[ERROR] POST request failed or returned empty data.");
  674. }
  675. }
  676. // Handle [PUT/HTTP] command
  677. else if (_data.startsWith("[PUT/HTTP]"))
  678. {
  679. if (!this->isConnectedToWifi() && !this->connectToWifi())
  680. {
  681. Serial.println("[ERROR] Not connected to Wifi. Failed to reconnect.");
  682. this->ledOff();
  683. return;
  684. }
  685. // Extract the JSON by removing the command part
  686. String jsonData = _data.substring(strlen("[PUT/HTTP]"));
  687. jsonData.trim();
  688. DynamicJsonDocument doc(1024);
  689. DeserializationError error = deserializeJson(doc, jsonData);
  690. if (error)
  691. {
  692. Serial.print("[ERROR] Failed to parse JSON.");
  693. this->ledOff();
  694. return;
  695. }
  696. // Extract values from JSON
  697. if (!doc.containsKey("url") || !doc.containsKey("payload"))
  698. {
  699. Serial.println("[ERROR] JSON does not contain url or payload.");
  700. this->ledOff();
  701. return;
  702. }
  703. String url = doc["url"];
  704. String payload = doc["payload"];
  705. // Extract headers if available
  706. const char *headerKeys[10];
  707. const char *headerValues[10];
  708. int headerSize = 0;
  709. if (doc.containsKey("headers"))
  710. {
  711. JsonObject headers = doc["headers"];
  712. for (JsonPair header : headers)
  713. {
  714. headerKeys[headerSize] = header.key().c_str();
  715. headerValues[headerSize] = header.value();
  716. headerSize++;
  717. }
  718. }
  719. // PUT request
  720. String putData = this->put(url, payload, headerKeys, headerValues, headerSize);
  721. if (putData != "")
  722. {
  723. Serial.println("[PUT/SUCCESS] PUT request successful.");
  724. Serial.println(putData);
  725. Serial.flush();
  726. Serial.println();
  727. Serial.println("[PUT/END]");
  728. }
  729. else
  730. {
  731. Serial.println("[ERROR] PUT request failed or returned empty data.");
  732. }
  733. }
  734. // Handle [DELETE/HTTP] command
  735. else if (_data.startsWith("[DELETE/HTTP]"))
  736. {
  737. if (!this->isConnectedToWifi() && !this->connectToWifi())
  738. {
  739. Serial.println("[ERROR] Not connected to Wifi. Failed to reconnect.");
  740. this->ledOff();
  741. return;
  742. }
  743. // Extract the JSON by removing the command part
  744. String jsonData = _data.substring(strlen("[DELETE/HTTP]"));
  745. jsonData.trim();
  746. DynamicJsonDocument doc(1024);
  747. DeserializationError error = deserializeJson(doc, jsonData);
  748. if (error)
  749. {
  750. Serial.print("[ERROR] Failed to parse JSON.");
  751. this->ledOff();
  752. return;
  753. }
  754. // Extract values from JSON
  755. if (!doc.containsKey("url") || !doc.containsKey("payload"))
  756. {
  757. Serial.println("[ERROR] JSON does not contain url or payload.");
  758. this->ledOff();
  759. return;
  760. }
  761. String url = doc["url"];
  762. String payload = doc["payload"];
  763. // Extract headers if available
  764. const char *headerKeys[10];
  765. const char *headerValues[10];
  766. int headerSize = 0;
  767. if (doc.containsKey("headers"))
  768. {
  769. JsonObject headers = doc["headers"];
  770. for (JsonPair header : headers)
  771. {
  772. headerKeys[headerSize] = header.key().c_str();
  773. headerValues[headerSize] = header.value();
  774. headerSize++;
  775. }
  776. }
  777. // DELETE request
  778. String deleteData = this->delete_request(url, payload, headerKeys, headerValues, headerSize);
  779. if (deleteData != "")
  780. {
  781. Serial.println("[DELETE/SUCCESS] DELETE request successful.");
  782. Serial.println(deleteData);
  783. Serial.flush();
  784. Serial.println();
  785. Serial.println("[DELETE/END]");
  786. }
  787. else
  788. {
  789. Serial.println("[ERROR] DELETE request failed or returned empty data.");
  790. }
  791. }
  792. this->ledOff();
  793. }
  794. }