stspringer

Better Garage Door Opener Using fetchAPI/JavaScript

Aug 20th, 2023 (edited)
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.16 KB | None | 0 0
  1. /*
  2. I have a LiftMaster Elite garage door opener which has a wall mount control. I decided to hookup a ESP8266 NodeMCU Web Server, to open or close my garage door using either my PC or my mobile phone.
  3.  
  4. So I realized after I got this working, let's say my garage door is closed, and my web page control button, on my phone, reports that the garage door is closed "as it should", what happens if someone opens the garage door with the garage wall mount button, while I am away from home, and my mobile phone still registers that my garage door is closed?
  5.  
  6. To solve this we need two reed switches, one for the door open position and one for the door closed position. The circuit I use has a 5v relay, with a signal pin, so after hooking up the relay "Common" and "NC" to the LiftMaster door control terminals, via the connectors on the side of the unit, I saw that when the garage door was either closing or opening, which takes approximately 12 seconds, the display on the wall mount switch, "which shows the time and temperature by default", would go out "time and temperature display would dissapear", during the 12 seconds ot the garage door motion, either closing or opening.
  7.  
  8. I realized this was happening because the relay is acting as a "jumper wire" on the garage door terminals, and electricity takes the path of least resistance and bypasses the wall mount during the 12 second wire jump.
  9.  
  10.  
  11. THE CONFUSING PART OF THE RELAY! "SIGNAL WIRE LOW", Relay ON, "NORMALL OPEN" terminal is "ON", the green LED indicator is "ON", THE LOAD IS OFF, IF CONNECTED TO THE "NC" TERMINAL,
  12.  
  13. "SIGNAL WIRE HIGH", Relay OFF, "NORMALLY CLOSED" terminal is "ON", THE LOAD IS ON, IF CONNECTED TO THE "NC" TERMINAL, green LED indicator is "OFF"
  14.  
  15.  
  16. Think about it. You have a 1 channel 5v relay control side, connected to an arduino, with 3.3v to the vcc of the relay control side, and the ground from the arduino connected to ground of the control side of the relay, and a signal wire as input from the arduino to the relay control side, "IN" pin.
  17.  
  18. On the load side of the relay you have let's say 12v in the common terminal of the relay "which will power the load", and the "NC" terminal on the relay is connected to the loads positive terminal, the ground side of the load is connected to the power source ground.
  19.  
  20. So let's say with a "LOW" "zero volts" signal wire the relay is actually on, the "NO" terminal has 12v, and the green LED indicator on the relay will be "ON". but that means the armature in the relay is being pulled to the Normally Open terminal in the relay "NO" but your load, is connected to the Normally Closed Terminal of the relay, so the load is off, not working. When the signal wire is "HIGH" the relay is actually "OFF", and the green LED turns "OFF", and the armature in the relay goes back to the "NC" terminal, in the relay, and the load turns "ON" and works.
  21.  
  22. To test this with a dvom, you will see when the signal wire is "LOW", zero v,you will read 12v when you place the positive lead of the dvom on the "NO" terminal of the relay, and the negative lead of the dvom on the Negative power source, it reads 12v, If you now put the positive lead of the dvom on the "NC" terminal, you will read zero volts. When the signal wire goes to "HIGH" the reading from the negative power source to the "NC" terminal reads 12v and the load is "ON"
  23.  
  24. Of course you could make the relay turn "ON" with a "HIGH" signal or "OFF" with a "LOW" signal, but here we are talking about the relay being "ON" with a "LOW" signal, where the relay is actually on, but the "NC" terminal is "OFF", has no connection to 12 volts.
  25.  
  26. The confusing part of the relay with either a "LOW ZERO VOLT" or "HIGH 3.3 VOLT" signal wire. Remember when a relay signal wire is "HIGH" the relay is "OFF" and the armature is pulled to the normally closed terminal, and the green LED indicator is off.
  27.  
  28. The 5v relay explained: When the relay signal pin is "LOW" the relay is "ON", and the green LED on the relay, is "ON" and the pole, or armature, in the relay, is pulled to the "normally open" "NO" terminal.
  29.  
  30. When the signal wire is "HIGH" the relay is "OFF" and the pole, or armature, in the relay, is now back to the Normally Closed terminal "NC" and the green LED is "OFF", and the 12v power is now sent to the load, if your load is connected to the "NC" terminal.
  31.  
  32. I noticed that the relay would sometimes stay "HIGH" or "OFF", after the garage door was either opened or closed, which means the pole or armature falls back to the "NC" terminal, and the green LED would be "OFF", and my wall mount button display would be out,this is not what we want. To solve this I had to turn the relay "ON", "LOW", in code, after the 12 seconds was up, and the pole or armature would fall back, to the "NO" terminal, and the green led would be "ON".
  33.  
  34. digitalWrite (output5, LOW);//this insures we turn the relay off after an opening or closing of the garage door, output5 is the relay signal wire GPIO5, D1
  35.  
  36. Also if you short the reed switch OPEN signal wires when the web button caption says CLOSED it will change the web button to OPEN and visa versa, on the reed switch CLOSE signal wires. This is to keep the states correct if someone presses the wall mount button when your phone state said CLOSED, and now the door is actually OPEN, the reed switches will update the state on your phone.
  37. */
  38.  
  39.  
  40.  
  41. /*********
  42. Door opener
  43. https://forum.arduino.cc/t/garage-door-opener-with-esp8266-web-server/1154364/18
  44. *********/
  45.  
  46. //DECLARATIONS
  47. //REMEMBER!, if the signal wire is "LOW", zero v, the relay is "ON", and the 'NO" terminal is "CLOSED" and has power, If the //signal wire is "HIGH", 3.3v the relay is "OFF", and the "NC" terminal has power.
  48. ///We are using the "NC" terminal on the relay in this script to power the load
  49. //THE CONFUSING PART OF THE 5V RELAY! "SIGNAL WIRE LOW", the Relay is "ON", "NORMALL OPEN" terminal is "ON", CLOSED, the //green LED indicator is "ON"
  50. //"SIGNAL WIRE HIGH", the is Relay OFF, "NORMALLY CLOSED" terminal is "ON", CLOSED, green LED indicator is "OFF"
  51.  
  52.  
  53. //The 5v relay explained: When the relay signal pin is "LOW" the relay is "ON", and the green LED on the relay, is "ON" and the pole, or armature in the relay, is pulled to the "normally open" "NO" terminal
  54. //when the signal wire is "HIGH" the relay is "OFF" and the pole or armature is back to the normally closed terminal "NC" and the green LED is "OFF", and power is sent to the load, if your load is connected
  55. //to the "NC" terminal.
  56.  
  57. //CONST INT
  58. const int positionSwitchTop = 14; // Pin connected to Top reed switch
  59. const int positionSwitchBottom = 4; // Pin connected to Bottom reed switch
  60. const int LED_Reed_Switch_Indicator = 16; // Built in LED pin turns on when door is in motion, else it is off
  61.  
  62. //INT
  63. int Bottom_Reed_Switch_Proximity = digitalRead(positionSwitchBottom); // Read the state of the bottom reed switch
  64. int Top_Reed_Switch_Proximity = digitalRead(positionSwitchTop); // Read the state of the top reed switch
  65.  
  66.  
  67. //BOOL
  68. bool The_Garage_Door_Is_Open = false;
  69. bool The_Garage_Door_Is_Closed = false;
  70.  
  71. //LIBRARY
  72. // Load Wi-Fi library
  73. #include <ESP8266WiFi.h>
  74. #include <ESP8266WebServer.h>
  75.  
  76. // Assign output variables to GPIO pins
  77. const uint8_t output5 = 5; // a output pin for door5
  78.  
  79. //UNSIGNED LONG
  80. unsigned long lastTimeDoorWasActivated = 0; // times for millis()
  81. const unsigned long doorDelay = 12000; // 12 seconds approximate time for garage door to fully open or close
  82.  
  83.  
  84. //ENUM FSM
  85. // how long does it take to open/close the door - set to 18 seconds
  86. enum class State { OPENED,
  87. CLOSING,
  88. CLOSED,
  89. OPENING }; // due to naming conflicts you will need a scoped enumeration (enum class)
  90. // 0 1 2 3 // the compiler will assign numbers to the enumeration items
  91.  
  92.  
  93. State state5 = State::CLOSED; // state5 a variable to store the current state for output5 running State Closed first
  94.  
  95. #if true // true for stspringer
  96. // Replace with your network credentials
  97. const char* ssid = "SECURE_10";
  98. const char* password = "DED4DD82CD";
  99. //My Add/ DEFINE STATIC IP 10.0.69.22 WORKING! https://www.youtube.com/watch?v=B9jJI7p2Gw4
  100.  
  101. //STATIC IP ADDRESS
  102.  
  103. //IPAddress local_IP(10, 0, 69, 22);//22 is the actual wireless ESP8266 in the garagedigitalWrite(relayPin, relayOnState);
  104. IPAddress local_IP(10, 0, 69, 19); // 19 for testing
  105. IPAddress gateway(10, 0, 69, 1);
  106. IPAddress subnet(255, 255, 255, 0);
  107. IPAddress primaryDNS(208, 67, 222, 222);
  108. IPAddress secondaryDNS(208, 67, 220, 220);
  109. #endif
  110.  
  111.  
  112. // Set web server port number to 80
  113. ESP8266WebServer server(80);
  114.  
  115. // open door
  116. void doorOpen() {
  117. lastTimeDoorWasActivated = millis();
  118. digitalWrite(output5, HIGH); //the relay signal wire is HIGH, 3.3v,the relay is actually "OFF", the "NC" terminal is CLOSED, "ON", sending power to the load, the "NO" terminal is now "OPEN", the green LED indicator is "OFF"
  119. state5 = State::OPENING;
  120. Serial.println(F("state5 OPENING"));
  121. }
  122.  
  123. // forced close
  124. void doorClose() {
  125. lastTimeDoorWasActivated = millis();
  126. digitalWrite(output5, HIGH); //the relay signal wire is HIGH, 3.3v,the relay is actually "OFF", the "NC" terminal is CLOSED, "ON", sending power to the load, the "NO" terminal is now "OPEN", the green LED indicator is "OFF"
  127. state5 = State::CLOSING; //running State Closed first
  128. Serial.println(F("state5 CLOSING"));
  129. }
  130.  
  131. void runFSM() {
  132. //Check state5 here
  133. //if (digitalRead(positionSwitchBottom) == LOW && state5 != State::CLOSED) state5 = State::CLOSED;//My Edit if the door is CLOSED but state5 is OPENED set stae5 to CLOSED
  134. //if (digitalRead(positionSwitchTop) == LOW && state5 != State::OPENED) state5 = State::OPENED;//My Edit if the door is OPENED but state5 is CLOSED set stae5 to OPENED
  135.  
  136. //My Add/EDIT check BOTTOM Reed Switch here
  137. if (digitalRead(positionSwitchBottom) == LOW && state5 != State::CLOSED) //bottom reed switch closing the circuit "ON", "LOW", initally when the BOTTOM reed switch is closed if the state on the web page is NOT CLOSED then make it CLOSED
  138. {
  139. state5 = State::CLOSED; //My Edit if the door is CLOSED but state5 is OPENED set state5 to CLOSED
  140.  
  141. if (The_Garage_Door_Is_Closed) //YES THE GARAGE DOOR IS CLOSED
  142. {
  143. state5 = State::OPENING; //the garage door is CLOSED so OPEN it, call OPENING
  144. } else //THE GARAGE DOOR IS OPENED
  145. {
  146. state5 = State::CLOSED; //the garage door is OPENED so close it, call CLOSED
  147. }
  148. } else if (digitalRead(positionSwitchBottom) == LOW && state5 == State::OPENED) // the garage door is in the physical CLOSED position, but state5 is showing OPENED on the web page, so set state5 to CLOSED
  149. {
  150. state5 = State::CLOSED;
  151. }
  152.  
  153.  
  154. //check TOP Reed Switch here
  155. if (digitalRead(positionSwitchTop) == LOW && state5 != State::OPENED) //TOP reed switch closing the circuit "ON", "LOW", initally when the TOP reed switch is CLOSED if the state on the web page is NOT OPENED then make it OPENED
  156. {
  157. state5 = State::OPENED; //My Edit if the door is OPENED but state5 is CLOSED, set state5 to OPENED
  158.  
  159. if (The_Garage_Door_Is_Open) //YES THE GARAGE DOOR IS OPENE
  160. {
  161. state5 = State::CLOSING; //the garage door is OPENED so CLOSE IT, call CLOSING
  162. } else //THE GARAGE DOOR IS CLOSED
  163. {
  164. state5 = State::OPENED; //the garage door CLOSED so OPEN it, CALL OPENED
  165. }
  166. } else if (digitalRead(positionSwitchTop) == LOW && state5 == State::CLOSED) // the garage door is in the physical OPENED position, but state5 is showing CLOSED on the web page, so set state5 to OPENED
  167. {
  168. state5 = State::OPENED;
  169. }
  170.  
  171. switch (state5) { // state5 a variable to store the current state for output5
  172. case State::OPENED:
  173. // here you could read a hardware button
  174. The_Garage_Door_Is_Open = true;
  175. The_Garage_Door_Is_Closed = false;
  176.  
  177. break;
  178. case State::CLOSING:
  179. if (millis() - lastTimeDoorWasActivated > doorDelay) //wait 12 seconds
  180. {
  181. //This triggers the 5v relay to turn ON and connect the load to the "NC" pin. The
  182. //LED will light up to indicate that the relay is ON. digitalWrite (output5, LOW);
  183. digitalWrite(output5, LOW);
  184. Serial.println(F("state5 CLOSED"));
  185. state5 = State::CLOSED; // state5 a variable to store the current state for output5
  186. }
  187. break;
  188. case State::CLOSED:
  189. // here you could read a hardware button
  190. The_Garage_Door_Is_Open = false;
  191. The_Garage_Door_Is_Closed = true;
  192.  
  193. break;
  194. case State::OPENING:
  195. if (millis() - lastTimeDoorWasActivated > doorDelay) //wait 12 seconds
  196. {
  197. //This triggers the 5v relay to turn ON and connect the load to the "NC" pin. The
  198. //LED will light up to indicate that the relay is ON. digitalWrite (output5, LOW);
  199. digitalWrite(output5, LOW);
  200. Serial.println(F("state5 OPENED"));
  201. state5 = State::OPENED; // state5 a variable to store the current state for output5
  202. }
  203. break;
  204. } //switch state
  205.  
  206. } //runFSM
  207.  
  208.  
  209. //SETUP
  210. void setup() {
  211. Serial.begin(115200);
  212. // Initialize the output variables as outputs
  213.  
  214. //OUTPUT
  215. pinMode(output5, OUTPUT);
  216. pinMode(LED_Reed_Switch_Indicator, OUTPUT);
  217.  
  218. //INPUT
  219. pinMode(positionSwitchTop, INPUT_PULLUP);
  220. pinMode(positionSwitchBottom, INPUT_PULLUP);
  221.  
  222. digitalWrite(LED_Reed_Switch_Indicator, HIGH); //initially turn "OFF", HIGH, the LED_Reed_Switch_Indicator
  223.  
  224. // Connect to Wi-Fi network with SSID and password
  225. Serial.print(F("Connecting to "));
  226. Serial.println(ssid);
  227.  
  228. //My Add/ Define Static IP Setings working!
  229. if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
  230. Serial.println(F("STA Failed to configure"));
  231. }
  232.  
  233. WiFi.begin(ssid, password);
  234. while (WiFi.status() != WL_CONNECTED) {
  235. delay(500);
  236. Serial.print(".");
  237. }
  238. Serial.println("");
  239. Serial.println(F("WiFi connected."));
  240. // Print local IP address and start web server
  241. Serial.println(F("IP address: "));
  242. Serial.println(WiFi.localIP());
  243.  
  244. serverSetup(); //in TAB 2 server
  245. }
  246.  
  247. void reedSwitchStatus() {
  248.  
  249. ////////////////////////////////////////////////////////////////////////////////////////
  250. //BEGIN Bottom_Reed_Switch_Proximity
  251. ///////////////////////////////////////////////////////////////////////////////////////
  252.  
  253. // If the pin reads low, the switch is closed.
  254. if (Bottom_Reed_Switch_Proximity = LOW) //Bottom_Reed_Switch_Proximity "reed Switch" is Closed IMPORTANT WATCH OUT FOR == ERROR HERE SHOULD BE =
  255. {
  256. Serial.println("Bottom Switch closed");
  257.  
  258. } else //Bottom_Reed_Switch_Proximity "reed Switch" is Open, turn on the blue built in LED 16 when the garage door is in motion
  259. {
  260. if (state5 == State::OPENING) {
  261. digitalWrite(LED_Reed_Switch_Indicator, LOW); //tune "ON" the LED_Reed_Switch_Indicator
  262. } else if (state5 == State::OPENED) {
  263. digitalWrite(output5, LOW); //this insures we turn the relay "off" after an opening or closing of the garage door
  264. digitalWrite(positionSwitchBottom, HIGH);
  265. digitalWrite(LED_Reed_Switch_Indicator, HIGH); //tune "OFF" the LED_Reed_Switch_Indicator
  266. Serial.println("Bottom_Reed_Switch_Proximity opened");
  267. }
  268.  
  269. } //if Bottom
  270.  
  271. ////////////////////////////////////////////////////////////////////////////////////////
  272. //BEGIN Top_Reed_Switch_Proximity
  273. ///////////////////////////////////////////////////////////////////////////////////////
  274.  
  275. // If the pin reads low, the switch is closed.
  276. if (Top_Reed_Switch_Proximity = LOW) //Top_Reed_Switch_Proximity "reed Switch" is Closed IMPORTANT WATCH OUT FOR == ERROR HERE SHOULD BE =
  277. {
  278. Serial.println("Top Switch closed");
  279.  
  280. } else // Top_Reed_Switch_Proximity "reed Switch" is Open, turn on the blue built in LED 16 when the garage door is in motion
  281. {
  282. if (state5 == State::CLOSING) {
  283. digitalWrite(LED_Reed_Switch_Indicator, LOW); //tune "ON" the LED_Reed_Switch_Indicator
  284. } else if (state5 == State::CLOSED) {
  285. digitalWrite(output5, LOW); //this insures we turn the relay off after an opening or closing of the garage door
  286. digitalWrite(positionSwitchTop, HIGH);
  287. digitalWrite(LED_Reed_Switch_Indicator, HIGH); //tune "OFF" the LED_Reed_Switch_Indicator
  288. Serial.println("Top_Reed_Switch_Proximity opened");
  289. }
  290.  
  291. } //if Top
  292.  
  293. } //reedSwitch
  294.  
  295. void loop() {
  296. server.handleClient(); // call the webserver
  297. reedSwitchStatus();
  298. runFSM();
  299. }
  300.  
  301.  
  302.  
  303.  
  304.  
  305. /////////////////////////////////////////////////////////////////////////////////////////////////
  306. //BEGIN SERVER TAB 2 UPDATE using "fetchAPI/JavaScript" 08_18_2023
  307. ////////////////////////////////////////////////////////////////////////////////////////////////
  308.  
  309. /*
  310. Webserver Parts
  311. Update page with FetchAPI & JavaScript
  312. button sends request to a dedicated resource to process commands
  313. */
  314.  
  315. // we need the button text in the page and in the JSON, hence a global structure to avoid duplicated code.
  316. struct Stateinfo {
  317. const char caption[42]; // text/caption for the button
  318. const char style[10]; // the CSS class (button, button2)
  319. };
  320.  
  321. // the order must fit to the order of the states in the enumeration
  322. Stateinfo stateinfo[4] {
  323. {"The Garage Door is Open", "button2"}, // green - button2
  324. {"Please wait... The Garage Door is Closing", "button"}, // red - button
  325. {"The Garage Door is Closed", "button"}, // red - button
  326. {"Please wait... The Garage Door is opening", "button2"} // green - button2
  327. };
  328.  
  329. // call this function in setup()
  330. void serverSetup() {
  331. server.on("/", handlePage); // the home page
  332. server.on("/j.js", handleJs); // javscript based on fetch API to update the page
  333. server.on("/json", handleJson); // send data in JSON format
  334. server.on("/cmd", handleCmd); // process commands
  335. server.begin();
  336. }
  337.  
  338. // the main handle for the page
  339. void handlePage() {
  340. //Serial.println(F(" D8 handle page"));
  341. String message;
  342. message.reserve(1000);
  343.  
  344. // Display the HTML web page
  345. message += F("<!DOCTYPE html>\n"
  346. "<html lang=\"en\">\n" // define the language of the content
  347. "<head>\n"
  348. "<title>John's Garage Door Opener</title>\n" // mostly displayed on the title bar of the browser tab
  349. "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n" // set the viewport for mobile devices
  350. "<link rel=\"icon\" href=\"data:,\">\n" // avoid loading of favicon.ico
  351. "<script src='j.js'></script>\n" // include the JavaScript
  352. "<style>\n" // inline style (or include a CSS)
  353. "html {font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n"
  354. "button, input[type=submit], .button {border: none; color: white; padding: 16px 40px; text-decoration: none; font-size: 20px; margin: 2px; cursor: pointer;}\n"
  355. ".button {background-color: #FF0000;}\n"
  356. ".button2 {background-color: #195B6A;}\n"
  357. "</style>\n"
  358. "</head>\n"
  359. "<body>\n"
  360. "<h1>John's Garage Door Opener</h1>\n");
  361.  
  362. // Display current state of output5
  363. message += F("<p>GPIO 5 - State<span id=\"output5\">");
  364. message += digitalRead(output5);
  365. message += F("</span></p>\n");
  366. // Display a form with one command button (=submit)
  367. Serial.println(stateinfo[(int)state5].caption);
  368. message += F("<form action=\"/cmd\" method=\"POST\"><button id=\"button5\" name=\"button5\" class=\"");
  369. message += stateinfo[(int)state5].style; // access the index based on the integer value of state5
  370. message += F("\">");
  371. message += stateinfo[(int)state5].caption;
  372. message += F("</button></form>\n");
  373.  
  374. // just for debugging - you will see 0, 1, 2, 3 as numeric representation of state5
  375. message += F("<p>global state5=<span id=\"state5\">"); message += (int)state5; message += F("</span></p>\n");
  376. message += F("<p>FetchAPI</p>\n");
  377. message += F("</body>\n");
  378. message += F("</html>");
  379.  
  380. server.send(200, "text/html", message);
  381. //Serial.print(F("handle page message length=")); Serial.println(message.length());
  382. }
  383.  
  384. // process incomming commands LOGIC HERE button5 pressed if state5 == State :: OPENED doorClose()
  385. void handleCmd() {
  386. if (server.hasArg("button5")) {
  387. if (state5 == State::OPENED) doorClose();
  388. else if (state5 == State::CLOSED) doorOpen();
  389. else Serial.println(F("D81 pressed cmd button in a state where no action is defined"));
  390. }
  391. handlePage(); // as HTML output we return the start page to the browser
  392. }
  393.  
  394. // Output: send data to browser as JSON
  395. // after amodification always check if JSON is still valid. Just call the JSON (json) in your webbrowser and check.
  396. void handleJson() {
  397. String message = "";
  398. message.reserve(1000);
  399. message = F(" {\"ss\":"); // Start of JSON and the first object "ss": with the actual runtime in seconds
  400. message += millis() / 1000;
  401.  
  402. message += F(",\"output5\":"); message += digitalRead(output5);
  403.  
  404. message += F(",\"state5\":"); message += (int)state5;
  405.  
  406. message += F(",\"style5\":\""); message += stateinfo[(int)state5].style; message += F("\""); // access the index based on the integer value of state5. Its text therefore the content must be enclosed in "
  407.  
  408. message += F(",\"caption5\":\""); message += stateinfo[(int)state5].caption; message += F("\"");
  409.  
  410. message += (F("}")); // End of JSON
  411. server.send(200, "application/json", message); // set MIME type https://www.ietf.org/rfc/rfc4627.txt
  412. //Serial.print(F("handleJson message length=")); Serial.println(message.length());
  413. }
  414.  
  415. // Output: a fetch API / JavaScript
  416. // a function in the JavaScript uses the fetchAPI to request a JSON file from the webserver.
  417. // The JavaScript process the JSON file and updates the values on the page
  418. void handleJs() {
  419. String message;
  420. message.reserve(1000);
  421. message += F("const url ='json';\n"
  422. "function renew(){\n"
  423. " document.getElementById('state5').style.color = 'blue';\n" // if the timer starts the request, this field gets blue
  424. " fetch(url)\n" // Call the fetch function passing the url of the API as a parameter
  425. " .then(response => {return response.json();})\n"
  426. " .then(jo => {\n"
  427. " for (var i in jo)\n"
  428. " {\n"
  429. " if (document.getElementById(i)) document.getElementById(i).innerHTML = jo[i];\n" // as long as the JSON name fits to the HTML id, the value will be replaced
  430. " }\n"
  431. // add other fields here (e.g. the delivered JSON name doesn't fit to the html id
  432. " document.getElementById('button5').innerHTML = jo['caption5'];\n"
  433. " document.getElementById('button5').className = jo['style5'];\n"
  434. " document.getElementById('state5').style.color = '';\n" // if everything was ok, the field will get the default color again
  435. " })\n"
  436. " .catch(function() {\n" // this is where you run code if the server returns any errors
  437. " document.getElementById('state5').style.color = 'red';\n" // indicator that something went wrong
  438. " });\n"
  439. "}\n"
  440. "document.addEventListener('DOMContentLoaded', renew, setInterval(renew, 1000));\n"); // call JSON every n milliseconds
  441.  
  442. server.send(200, "text/javascript", message);
  443. //Serial.print(F("handleJs message length=")); Serial.println(message.length());
  444. }
  445.  
  446. /////////////////////////////////////////////////////////////////////////////////////////////////
  447. //END SERVER TAB 2 UPDATE 08_18_2023
  448. ////////////////////////////////////////////////////////////////////////////////////////////////
  449.  
Advertisement
Add Comment
Please, Sign In to add comment