Arduino Ethernet Control - Reading instructions from a table

Hi!

Apologies for being a novice and I welcome any alternatives based on what I'm trying to do:

I have an Ethernet connected Arduino with two connected relays, using the Arduino as a web server, with some buttons I am able to control the relays by pushing the buttons - basically using this method:

I need the relays to switch by following a predetermined schedule. The schedule is a truth table with a new row every five minutes with 1's to close the relay and 0's to open the relay. I'll also need to upload a new schedule every now and again so can't hardcode into the sketch. I need the sketch to read the truth table and then tell the relays what to do.

Can I paste the truth table to the webserver (webpage) and have the Arduino read each line every five minutes? If so how? or is there another way? Also I'm not great with HTML so any examples would be much appreciated.

Many Thanks

MastersInWhat?

You'll have to do a couple of things:

  • Connect to a NTP server to get the current time
  • Host a webpage for setting the table
  • Host a JSON file containing the current table
  • Receive a JSON file containing the new table (using POST request from the first webpage)
  • Parse the JSON
  • Check the time every now and then, look up the setting in the parsed JSON, and turn the relay on or off accordingly

I was bored, so I wrote a piece of HTML+JavaScript that you could use for the webpage:

<HTML>
    <body>
        <div style="width:160px;margin:12 auto;padding:48px;text-align:center">
            <table id="timetable">
                <tr>
                    <th>Time</th>
                    <th>Relay 1</th>
                    <th>Relay 2</th>
                </tr>                
            </table>
            <button onclick="send();">Send</button>
        </div>    
    </body>
    <script type="text/javascript">
        const starthour = 7;
        const startminute = 30;
        const timeinterval = 5; // in minutes
        const stophour = 10;
        const stopminute = 25;
        
        let xhrGet = new XMLHttpRequest();
        xhrGet.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) { // successfully fetched JSON
                let hours = starthour;
                let minutes = startminute;

                let timetable = document.getElementById("timetable"); // the table element to which we'll add rows

                let jsonArr = JSON.parse(this.resoponseText);
                console.log(jsonArr);
                let jsonCounter = 0;
                
                while((hours < stophour || minutes <= stopminute) && jsonArr[jsonCounter] !== undefined) { // add table rows to the page
                    let minuteStr = minutes < 10 ? "0"+minutes : minutes.toString(); // add leading zero when necessary

                    let tr = document.createElement("tr");                              // time
                    let tdTime = document.createElement("td");
                    tdTime.appendChild(document.createTextNode(hours+":"+minuteStr));
                    tr.appendChild(tdTime);

                    let tdR1 = document.createElement("td");                            // cell with checkbox for relay 1
                    let cbR1 = document.createElement("input");
                    cbR1.setAttribute("type","checkbox");
                    cbR1.checked = jsonArr[jsonCounter][0] == 1;
                    tdR1.appendChild(cbR1);
                    tr.appendChild(tdR1);

                    let tdR2 = document.createElement("td");                            // cell with checkbox for relay 1
                    let cbR2 = document.createElement("input");
                    cbR2.setAttribute("type","checkbox");            
                    cbR2.checked = jsonArr[jsonCounter][1] == 1;
                    tdR2.appendChild(cbR2);
                    tr.appendChild(tdR2);

                    timetable.appendChild(tr);

                    minutes += timeinterval;                                            // next time interval
                    hours += Math.floor(minutes/60);
                    minutes %= 60;

                    jsonCounter++;
                }
            } if (this.readyState == 4 && this.status != 200) {
                alert("Could not fetch JSON from Arduino ...");
            }
        };
        xhrGet.open("GET","table.json",true);
        xhrGet.send();
        
        function send() {
            let values = [];
            for (let i = 2, trElement; trElement = timetable.childNodes[i]; i++){
                let newRow = [trElement.childNodes[1].firstChild.checked ? 1:0, trElement.childNodes[2].firstChild.checked ? 1:0];
                values.push(newRow);
            }
            let jsonStr = JSON.stringify(values);
            console.log(jsonStr);
            
            let jsonBlob = new Blob([jsonStr], {type: 'application/json'});
            
            let xhrPost = new XMLHttpRequest();
            xhrPost.onreadystatechange = function() {
                if (this.readyState == 4 && this.status == 200) { // successfully sent JSON
                    alert("Success!");
                } else if (this.readyState == 4 && this.status != 200) {
                    alert("Sending JSON to Arduino failed.");
                }
            };
            xhrPost.open("POST","table.json",true);
            xhrPost.send(jsonBlob);      
        }
    </script>
</HTML>

JSrelays.png

If you don't understand what's happening, just ask.
Basically:
The HTML is simple, doesn't contain much when first loaded. Then JavaScript requests the JSON file from the Arduino. Based on that JSON file, and the time constants given on lines 15-19, JS creates an HTML table with times and checkboxes.
When you click 'Send', JS reads all values from the checkboxes into an array, converts it to a JSON string, and sends it to the Arduino using an HTTP POST request.

Pieter

Apologies for the little hi-jack. Using JSON to send post requests seems very interesting too me, as currently I use GET requests targeted at hidden iframes. Reading/understanding the code above it a bit beyond me at my current level, but is there anything you could recommend reading so I can learn more?