From 077ad517f56b65211370f87eb6e9f10f3e06faeb Mon Sep 17 00:00:00 2001
From: Jan Grewe <jan@faked.org>
Date: Sun, 4 Jun 2023 22:58:18 +0200
Subject: [PATCH] save/load via webinterface

---
 data_src/index.html | 12 +++++++++---
 data_src/main.js    | 13 +++++++++++--
 src/main.cpp        | 12 ++----------
 src/network.cpp     | 37 ++++++++++++++++++++++---------------
 src/network.h       |  1 +
 src/settings.cpp    | 20 ++++++++++++++++++++
 src/settings.h      | 14 ++++++++++++++
 7 files changed, 79 insertions(+), 30 deletions(-)
 create mode 100644 src/settings.cpp
 create mode 100644 src/settings.h

diff --git a/data_src/index.html b/data_src/index.html
index 9ce4494..edeed5b 100644
--- a/data_src/index.html
+++ b/data_src/index.html
@@ -34,19 +34,25 @@
             <input type="range" class="form-range rangeConfig" id="rangeSpeed" data-name="interval" min="1" max="100"
               steps="10" disabled>
           </div>
+          <div class="row mb-3 px-3 mt-5">
+            <button type="button" class="btn btn-primary btnAction" data-action="addGlider" disabled>Add
+              Glider</button>
+          </div>
 
         </div>
 
         <div class="card-footer text-body-secondary py-3">
           <div class="row">
             <div class="col-6">
-              <button type="button" class="btn btn-sm btn-primary btnAction" data-action="addGlider" disabled>Add
-                Glider</button>
+              <button type="button" class="btn btn-sm btn-success btnAction" data-action="load" disabled>Load</button>
+            </div>
+            <div class="col-6">
+              <button type="button" class="btn btn-sm btn-success btnAction" data-action="save" disabled>Save</button>
             </div>
             <div class="col-6 text-end">
               <button type="button" class="btn btn-sm btn-outline-secondary me-1" data-bs-toggle="collapse"
                 data-bs-target="#debug">Debug</button>
-              <button type="button" class="btn btn-sm btn-danger btnAction " data-action="reboot"
+              <button type="button" class="btn btn-sm btn-danger btnAction" data-action="reboot"
                 disabled>Reboot</button>
             </div>
           </div>
diff --git a/data_src/main.js b/data_src/main.js
index 368dbc0..28d07bf 100644
--- a/data_src/main.js
+++ b/data_src/main.js
@@ -1,4 +1,4 @@
-var wsUrl = 'ws://' + document.location.host + '/ws'
+var wsUrl = 'ws://' + document.location.host + '/ws';
 
 var config = {
     brightness: 0,
@@ -81,6 +81,8 @@ function startSocket() {
         onOpen: function (e) {
             console.log("WS: connected");
             addMessage("✅ connected");
+            getConfig();
+            uiEnabled(true);
         },
         onClose: function (e) {
             uiEnabled(false);
@@ -95,16 +97,23 @@ function startSocket() {
     });
 
     ws.listen(function (data) {
+        console.log(data);
         var json = JSON.stringify(data);
         var msg = "⬅️ " + json;
         addMessage(msg);
         if (data.config) {
             loadConfig(data.config);
-            uiEnabled(true);
         }
     });
 }
 
+function getConfig() {
+    var payload = {
+        'action': 'load'
+    };
+    wsSend(payload);
+}
+
 function loadConfig(data) {
     config.brightness = data.brightness;
     config.interval = data.interval;
diff --git a/src/main.cpp b/src/main.cpp
index 2ed21b6..6ed2e41 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,11 +1,9 @@
 #include <Arduino.h>
-#include <Preferences.h>
 #include "utils.h"
 #include "network.h"
 #include "display.h"
 #include "gameoflife.h"
-
-Preferences preferences;
+#include "settings.h"
 
 int defaultBrightness;
 int gameInterval;
@@ -19,18 +17,12 @@ void showTitle() {
   showMessage(msg);
 }
 
-void setupSettings() {
-  preferences.begin("settings", true); // true = readonly
-  defaultBrightness = preferences.getUInt("brightness", 50);
-  gameInterval = preferences.getUInt("interval", 100);
-  preferences.end();
-}
 
 void setup()
 {
   Serial.begin(115200);
   logLine("", true);
-  setupSettings();
+  loadSettings();
   setupDisplay();
   showTitle();
   setupNetwork();
diff --git a/src/network.cpp b/src/network.cpp
index 272ad92..77abde2 100644
--- a/src/network.cpp
+++ b/src/network.cpp
@@ -5,6 +5,7 @@
 #include "network.h"
 #include "display.h"
 #include "gameoflife.h"
+#include "settings.h"
 
 MDNSResponder mdns;
 AsyncWebServer server(80);
@@ -57,15 +58,14 @@ void setupOTA()
                      {
                       runGame = false;
                       ws.enable(false);
-                      ws.textAll("OTA Update Started");
                       ws.closeAll();
-                      logLine("Update Start");
+                      logLine("OTA Update Start");
                       clearDisplay(); });
   ArduinoOTA.onEnd([]()
                    {
                     otaProgress = 0;
                     runGame = true; 
-                    logLine("Update End");
+                    logLine("OTA Update End");
                     clearDisplay(); });
   ArduinoOTA.onProgress([](unsigned int progress, unsigned int total)
                         {
@@ -198,13 +198,6 @@ void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType
     logLine("WS<< connect");
     logLine("WS>> ping");
     client->ping();
-    DynamicJsonDocument doc = getConfigJson();
-    size_t strsize = measureJson(doc) + 1;
-    char json[strsize];
-    serializeJson(doc, json, strsize);
-    logLine("WS>> ", false);
-    logLine(json);
-    ws.text(client->id(), json);
   }
   else if (type == WS_EVT_DISCONNECT)
   {
@@ -250,7 +243,16 @@ void handleJson(uint8_t *data)
 
   if (doc.containsKey("action"))
   {
-    if (doc["action"] == "addGlider")
+    if (doc["action"] == "load")
+    {
+      loadSettings();
+      sendConfig();
+    }
+    else if (doc["action"] == "save")
+    {
+      saveSettings();
+    }
+    else if (doc["action"] == "addGlider")
     {
       addGlider();
     }
@@ -266,8 +268,13 @@ void updateConfig(StaticJsonDocument<200U> doc)
   gameInterval = doc["config"]["interval"];
   defaultBrightness = doc["config"]["brightness"];
   displayBrightness(defaultBrightness);
-  preferences.begin("settings", false);
-  preferences.putUInt("brightness", defaultBrightness);
-  preferences.putUInt("interval", gameInterval);
-  preferences.end();
+}
+
+void sendConfig()
+{
+  DynamicJsonDocument doc = getConfigJson();
+  size_t strsize = measureJson(doc) + 1;
+  char json[strsize];
+  serializeJson(doc, json, strsize);
+  ws.textAll(json);
 }
diff --git a/src/network.h b/src/network.h
index c22f54a..d9d85db 100644
--- a/src/network.h
+++ b/src/network.h
@@ -32,5 +32,6 @@ void onTelnetInput(String str);
 void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len);
 void handleJson(uint8_t* data);
 void updateConfig(StaticJsonDocument<200U> doc);
+void sendConfig();
 
 #endif
diff --git a/src/settings.cpp b/src/settings.cpp
new file mode 100644
index 0000000..c9fc9d3
--- /dev/null
+++ b/src/settings.cpp
@@ -0,0 +1,20 @@
+#include <Arduino.h>
+#include "settings.h"
+#include "display.h"
+
+Preferences preferences;
+
+void loadSettings() {
+  preferences.begin("settings", true); // true = readonly
+  defaultBrightness = preferences.getUInt("brightness", 50);
+  gameInterval = preferences.getUInt("interval", 100);
+  preferences.end();
+  displayBrightness(defaultBrightness);
+}
+
+void saveSettings() {
+  preferences.begin("settings", false);
+  preferences.putUInt("brightness", defaultBrightness);
+  preferences.putUInt("interval", gameInterval);
+  preferences.end();  
+}
diff --git a/src/settings.h b/src/settings.h
new file mode 100644
index 0000000..189c02e
--- /dev/null
+++ b/src/settings.h
@@ -0,0 +1,14 @@
+
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include <Arduino.h>
+#include <Preferences.h>
+
+extern int defaultBrightness;
+extern int gameInterval;
+
+void loadSettings();
+void saveSettings();
+
+#endif
-- 
GitLab