Skip to content

Commit 04619e2

Browse files
committed
Module: call onUpdate directly from compareRecursive (no change vector)
Docs ==== - modules: update loop1s UI == - Module: handleState: updateRecursive as well Server ===== pio.ini: httpd stack size 8192 to 16384 (to call onUpdate directly from compareRecursive - Module: remove updatedItems, add onUpdate function var, compareRecursive: refactor keys, call onUpdate, return changed - ModuleAnimations: add gLiveAnimation, compileAndRun JsonVariant argument add external funs, add clients leds, loop1s: check clients - ModuleDemo: add millis - ModuleInstances: loop1s check clients
1 parent 3e725af commit 04619e2

File tree

10 files changed

+12809
-12718
lines changed

10 files changed

+12809
-12718
lines changed

docs/moonbase/modules.md

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ Each module has each own documentation which can be accessed by pressing the ? a
2020

2121
To create a new module:
2222

23-
* Create a class which inherits from Module
24-
* Call the Module constructor with the name of the module.
23+
* Create a **class** which inherits from Module
24+
* Call the Module **constructor** with the name of the module.
2525
* This name will be used to set up http rest api and webserver sockets
2626
* See [ModuleDemo.h](https://github.com/ewowi/MoonBase/blob/main/src/custom/ModuleDemo.h)
2727

@@ -39,7 +39,7 @@ ModuleDemo(PsychicHttpServer *server
3939
}
4040
```
4141
42-
* Implement function setupDefinition to create a json document with the datastructure
42+
* Implement function **setupDefinition** to create a json document with the datastructure
4343
* Store data on the file system
4444
* Generate the UI
4545
* Initialy create the module data
@@ -66,12 +66,12 @@ void setupDefinition(JsonArray root) override{
6666
6767
```
6868

69-
* Implement function onUpdate to define what happens if data changes
69+
* Implement function **onUpdate** to define what happens if data changes
7070
* struct UpdatedItem defines the update (parent property (including index in case of multiple records), name of property and value)
7171
* This runs in the httpd / webserver task. To run it in the main (application task use runInLoopTask - see [ModuleAnimations](https://github.com/ewowi/MoonBase/blob/main/src/custom/ModuleAnimations.h)) - as httpd stack has been increased runInLoopTask is less needed
7272

7373
```cpp
74-
void onUpdate(UpdatedItem updatedItem) override
74+
void onUpdate(UpdatedItem &updatedItem) override
7575
{
7676
if (equal(updatedItem.name, "lightsOn") || equal(updatedItem.name, "brightness")) {
7777
ESP_LOGD(TAG, "handle %s = %s -> %s", updatedItem.name, updatedItem.oldValue.c_str(), updatedItem.value.as<String>().c_str());
@@ -81,12 +81,38 @@ void setupDefinition(JsonArray root) override{
8181
if (updatedItem.oldValue.length())
8282
ESP_LOGD(TAG, "delete %s ...", updatedItem.oldValue.c_str());
8383
if (updatedItem.value.as<String>().length())
84-
compileAndRun(updatedItem.value.as<String>().c_str());
84+
compileAndRun(updatedItem.value);
8585
} else
8686
ESP_LOGD(TAG, "no handle for %s = %s -> %s", updatedItem.name, updatedItem.oldValue.c_str(), updatedItem.value.as<String>().c_str());
8787
}
8888
```
8989
90+
* Implement function **loop1s** to send [readonly data](#Readonly_data) from the server to the UI
91+
* Optionally, only when a module has readonly data
92+
93+
```cpp
94+
void loop1s() {
95+
JsonDocument newData; //to only send updatedData
96+
97+
JsonArray scripts = newData["scripts"].to<JsonArray>(); //to: remove old array
98+
99+
for (Executable &exec: scriptRuntime._scExecutables) {
100+
JsonObject object = scripts.add<JsonObject>();
101+
object["name"] = exec.name;
102+
object["isRunning"] = exec.isRunning();
103+
object["isHalted"] = exec.isHalted;
104+
object["exeExist"] = exec.exeExist;
105+
object["kill"] = 0;
106+
}
107+
108+
if (_state.data["scripts"] != newData["scripts"]) {
109+
_state.data["scripts"] = newData["scripts"]; //update without compareRecursive -> without handles - WIP
110+
JsonObject newDataObject = newData.as<JsonObject>();
111+
_socket->emitEvent("animationsRO", newDataObject); //RO is WIP, maybe use "animations" also for readonly
112+
}
113+
}
114+
```
115+
90116
* Add the module in [main.cpp](https://github.com/ewowi/MoonBase/blob/main/src/main.cpp)
91117

92118
```cpp
@@ -95,6 +121,8 @@ ModuleDemo moduleDemo = ModuleDemo(&server, &esp32sveltekit, &filesService);
95121
moduleDemo.begin();
96122
...
97123
moduleDemo.loop();
124+
...
125+
moduleDemo.loop1s();
98126
```
99127

100128
* Add the module in [menu.svelte](https://github.com/ewowi/MoonBase/blob/main/interface/src/routes/menu.svelte) (this will be automated in the future)
@@ -112,9 +140,17 @@ submenu: [
112140

113141
* This is all to create a fully functioning new module
114142

115-
Moonbase-Modules is implemented in:
143+
### Readonly data
144+
145+
A module can consist of data which is edited by the user (e.g. selecting an animation to run) and data which is send from the server to the UI (e.g. a list of running processes). Currently both type of valuas are stored in state data and definition. Distinguished by property["ro"] = true in setupDefinition. So the client uses state data and definition to build a screen with both types visually mixed together (what is desirable). Currently there are 2 websocket events: one for the entire state (including readonly) and one only for readonly which only contains the changed values. Module.svelte handles readonly differently by the function handleRO which calls updateRecursive which only update the parts of the data which has changed.
146+
147+
It might be arguable that readonly variables are not stored in state data.
148+
149+
### Server
116150

117151
* [Module.h](https://github.com/ewowi/MoonBase/blob/main/src/custom/Module.h) and [Module.cpp](https://github.com/ewowi/MoonBase/blob/main/src/custom/Module.cpp) will generate all the required server code
152+
153+
### UI
118154
* [Module.svelte](https://github.com/ewowi/MoonBase/blob/main/interface/src/routes/custom/module/Module.svelte) will deal with the UI
119155
* [MultiInput.svelte](https://github.com/ewowi/MoonBase/blob/main/interface/src/lib/components/custom/MultiInput.svelte) is used by Module.svelte to display the right UI widget based on what is defined in the definition json
120156
* Modifications done in [menu.svelte](https://github.com/ewowi/MoonBase/blob/main/interface/src/routes/menu.svelte) do identify a module by href and not by title alone

interface/src/routes/moonbase/module/Module.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@
147147
148148
const handleState = (state: any) => {
149149
// console.log("handleState", state);
150-
data = state;
150+
updateRecursive(data, state);
151+
// data = state;
151152
};
152153
153154
const handleRO = (state: any) => {

0 commit comments

Comments
 (0)