esp8266-remote-timer

ESP8266 based timer w/ remote control and NTP sync
Index Commits Files Refs README LICENSE
commit 54c61e656f3fc09bc4ed0a88e6b1d7cf75b93664
parent 69dcae0dc2e9972b38e3c84fbf1939d7bf039c6f
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date:   Fri, 28 Mar 2025 21:13:17 -0300

add timer logic (not fully implemented yet)

Diffstat:
Mdata/index.html | 90+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mdata/main.js | 53++++++++++++++++++++++++++++++++++++++++++++---------
Msrc/main.cpp | 33+++++++++++++++------------------
3 files changed, 113 insertions(+), 63 deletions(-)
diff --git a/data/index.html b/data/index.html
@@ -23,42 +23,52 @@
                         </tr>
                     </table>
                 </div>
-                <div id="timer-div">
-                    <table>
-                        <tr id="timer-div2"  onclick="handle_click('timer-toggle)">
-                            <td id="label-box" style="padding: 0 0 .65em 0;">
-                                Timer enabled
-                            </td>
-                            <td style="text-align: right; padding: 0 0 .65em 0;">
-                                <input type="checkbox" id="timer-checkbox"/>
-                            </td>
-                        </tr>
-                        <tr>
-                            <td style="padding: 0.85em 0 .25em 0;">
-                                From
-                            </td>
-                            <td style="padding: 0.85em 0 .25em 0;">
-                                <input id="from-time" type="time" value="18:00"/>
-                            </td>
-                        </tr>
-                        <tr>
-                            <td>
-                                Until
-                            </td>
-                            <td>
-                                <input id="to-time" type="time" value="00:00"/>
-                            </td>
-                        </tr>
-                        <!-- <tr> -->
-                        <!--     <td> -->
-                        <!--     </td> -->
-                        <!--     <td> -->
-                        <!--         <div id="save-timer-button"> -->
-                        <!--             save -->
-                        <!--         </div> -->
-                        <!--     </td> -->
-                        <!-- </tr> -->
-                    </table>
+                <div id="timer">
+                    <div id="timer-enable" onclick="handle_click('timer-toggle')">
+                        <table>
+                            <tr>
+                                <td id="label-box">
+                                    Timer enabled
+                                </td>
+                                <td>
+                                    <input type="checkbox" id="timer-checkbox"/>
+                                </td>
+                            </tr>
+                        </table>
+                    </div>
+                    <div id="timer-sep"></div>
+                    <div id="timer-picker">
+                        <table>
+                            <tr>
+                                <td>
+                                    From
+                                </td>
+                                <td>
+                                    <input id="from-time" type="time" value="18:00"/>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td>
+                                    Until
+                                </td>
+                                <td>
+                                    <input id="to-time" type="time" value="00:00"/>
+                                </td>
+                            </tr>
+                            <!-- <tr> -->
+                            <!--     <td> -->
+                            <!--     </td> -->
+                            <!--     <td> -->
+                            <!--         <div id="save-timer-button"> -->
+                            <!--             save -->
+                            <!--         </div> -->
+                            <!--     </td> -->
+                            <!-- </tr> -->
+                        </table>
+                    </div>
+                    <div id="timer-save-div">
+                        <input type="button" value="Save" id="timer-save">
+                    </div>
                 </div>
             </div>
 
@@ -98,6 +108,14 @@
                     </tr>
                     <tr>
                         <td style="text-align: left;">
+                            Last NTP sync
+                        </td>
+                        <td style="text-align: right;">
+                            <div id="last-ntp-sync" style="font-family: monospace;"></div>
+                        </td>
+                    </tr>
+                    <tr>
+                        <td style="text-align: left;">
                             System time
                         </td>
                         <td style="text-align: right;">
diff --git a/data/main.js b/data/main.js
@@ -1,6 +1,8 @@
 var received_data;
-var time_div, main_output_checkbox, system_local_domain, system_ip_addr, system_time, wifi_ssid, wifi_rssi;
-var system_time_since_epoch;
+var time_div, main_output_checkbox, system_local_domain, system_ip_addr, wifi_ssid, wifi_rssi;
+var system_time, system_time_elem, last_ntp_sync, last_ntp_sync_elem;
+
+var to_time, from_time, timer_save_button;
 
 // Convert to GMT-3 using Intl.DateTimeFormat
 const time_formatter = new Intl.DateTimeFormat('en-GB', {
@@ -38,10 +40,15 @@ function socket_onmessage_handler(event) {
     system_ip_addr.href = received_data["system-ip-addr"];
     system_ip_addr.innerHTML = received_data["system-ip-addr"];
 
-    system_time_since_epoch = received_data["system-time"];
-    const tmp_system_time = new Date(system_time_since_epoch*1000);
-    const formatted_date = time_formatter.format(tmp_system_time);
-    system_time.innerHTML = formatted_date + " GMT-3";
+    system_time = received_data["system-time"];
+    system_time_elem.innerHTML = time_formatter.format(new Date(system_time*1000))
+        .replaceAll("/", "-")
+        .replaceAll(",", "") + " GMT-3";
+
+    last_ntp_sync = received_data["last-ntp-sync"];
+    last_ntp_sync_elem.innerHTML = time_formatter.format(new Date(last_ntp_sync*1000))
+        .replaceAll("/", "-")
+        .replaceAll(",", "") + " GMT-3";
 
     wifi_ssid.innerHTML = received_data["wifi-ssid"];
     const rssi = received_data["wifi-rssi"];
@@ -56,8 +63,10 @@ function socket_onopen_handler(event) {
 function handle_click(cb) {
     if(cb == 'main-toggle') {
         socket.send("main-output-toggle");
+    } else if(cb == 'timer-toggle') {
+        socket.send("timer-toggle");
     } else {
-        console.log("not implemented");
+        console.log("handle_click: wrong target");
     }
 }
 
@@ -68,12 +77,38 @@ function update_system_time() {
 function query_data() {
     main_output_checkbox = document.getElementById("main-output-checkbox");
     system_local_domain = document.getElementById("system-local-domain");
+    last_ntp_sync_elem = document.getElementById("last-ntp-sync");
+    system_time_elem = document.getElementById("system-time");
     system_ip_addr = document.getElementById("system-ip-addr");
-    system_time = document.getElementById("system-time");
     wifi_ssid = document.getElementById("wifi-ssid");
     wifi_rssi = document.getElementById("wifi-rssi");
 
-    setInterval(update_system_time, 30*1000); // update time every 30 secs
+    from_time = document.getElementById("from-time");
+    to_time = document.getElementById("to-time");
+    timer_save_button = document.getElementById("timer-save");
+
+    timer_save_button.addEventListener(
+        "click",
+        () => {
+            socket.send("timer-set-values");
+            socket.send(from_time.value)
+            socket.send(to_time.value)
+            console.log(from_time.value, to_time.value);
+        },
+        false,
+    );
+
+    /*
+    to_time.addEventListener(
+        "input",
+        () => {
+            console.log(to_time.value);
+        },
+        false,
+    );
+    */
+
+    // setInterval(update_system_time, 30*1000); // update time every 30 secs
 }
 
 const socket = new WebSocket("ws:/" + "/" + location.host + ":81");
diff --git a/src/main.cpp b/src/main.cpp
@@ -4,13 +4,6 @@
 #include <ESP8266mDNS.h>
 #include <LittleFS.h>
 #include <Arduino_JSON.h>
-
-uint8_t remote_devices = 0, main_output_enabled = 0;
-uint32_t t = 0, dt = 0, main_output_dt = 0;
-
-ESP8266WebServer server(80);
-WebSocketsServer web_socket = WebSocketsServer(81);
-JSONVar data, system_time_data;
 #include <time.h>
 #include <coredecls.h> // settimeofday_cb() callback
 
@@ -28,8 +21,14 @@ JSONVar data, system_time_data;
 
 #define MAIN_SWITCH_REPEAT_TIME 200
 
+ESP8266WebServer server(80);
+WebSocketsServer web_socket = WebSocketsServer(81);
+JSONVar data, system_time_data;
+
 time_t system_time, last_ntp_sync;
 tm tm;
+uint8_t remote_devices = 0, timer_enabled = 0, main_output_enabled = 0;
+
 void webp_socket_event(uint8_t, WStype_t, uint8_t *, size_t);
 void webp_handler();
 
@@ -84,7 +83,7 @@ void setup() {
     delay(1000);
 
     Serial.printf("[SETUP] Booting");
-    for(uint8_t t = 20; t > 0; t--) {
+    for(uint8_t t = 10; t > 0; t--) {
         Serial.print(".");
         Serial.flush();
         delay(150);
@@ -102,12 +101,13 @@ void setup() {
     digitalWrite(SETUP_COMPLETE_OUTPUT_PIN, HIGH);
 }
 
+uint32_t t = 0, clock_dt = 0, main_output_dt = 0;
 void loop() {
     t = millis();
 
-    if(digitalRead(MAIN_SWITCH_INPUT_PIN)) {
-        if((t - dt) > MAIN_SWITCH_REPEAT_TIME) {
-            dt = millis();
+    if((t - main_output_dt) > MAIN_SWITCH_REPEAT_TIME) {
+        if(digitalRead(MAIN_SWITCH_INPUT_PIN)) {
+            main_output_dt = millis();
             main_output_toggle();
             update_all_socket_clients();
         }
@@ -139,7 +139,7 @@ void setup_wifi() {
 
     Serial.printf("[SETUP] Connecting to WiFi");
     while(WiFi.status() != WL_CONNECTED) {
-        delay(200);
+        delay(100);
         Serial.print(".");
     }
     Serial.printf("\n[SETUP] Connected to '%s' IP address ", WIFI_SSID);
@@ -167,8 +167,8 @@ void main_output_toggle() {
     main_output_enabled = !main_output_enabled;
 }
 
-void query_system_time() {
-    system_time_data["system-time"] = system_time.getEpochTime();
+void timer_toggle() {
+    timer_enabled = !timer_enabled;
 }
 
 void update_data() {
@@ -274,10 +274,7 @@ void webserver_file_handler() {
     String path = server.uri();
     String requested_page;
     int response_code;
-    response_code = 200;
-    if(webserver_get_file(path, requested_page)) {
-        response_code = 404;
-    }
+    response_code = webserver_get_file(path, requested_page) ? 404 : 200;
     server.send(response_code, webserver_file_content_type(path), requested_page);
 }