Skip to content

Commit 014564c

Browse files
committed
Add CRUD(S), addControl update definition, reorder layouts
Front end ======== - Multirow: add crud(s) to display add, delete and sort/drag Back end ======= - Devices, IO, Tasks, Live scripts, Info: add crud - Nodes: addControl: always update definition - Virtual driver: remove (will be part of Physical driver -> rename...) - Utilities: EXT_LOGx: conditional (saves flash) - Physical layer: layoutPre: set nrOfAssignedPins = 0 - Channels: check if channels defined - Infrared: no logging if symbol is 1
1 parent 4d44b48 commit 014564c

File tree

17 files changed

+11704
-11759
lines changed

17 files changed

+11704
-11759
lines changed

docs/develop/nodes.md

Lines changed: 41 additions & 72 deletions
Large diffs are not rendered by default.

docs/moonbase/devices.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
<img width="320" src="https://github.com/user-attachments/assets/dacd1527-b771-4d57-8528-5d42d89e3cac" />
44

5-
Sends and receives UDP messages over the network to see which other devices are there (WLED compatible).
5+
Shows which other MoonLight devices are connected to your local network.
66

7-
* Device name: name of this device
7+
* Device name: name of this device (set the name in the [WiFi station module](https://moonmodules.org/MoonLight/network/sta/))
88
* Devices: Devices found on the network
9-
* Click on IP to jump to the device
10-
* Statusbar and HTML title display the device name
9+
* Click on IP to jump to the device

interface/src/lib/components/moonbase/MultiRow.svelte

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,13 @@
9898
const query = (isNegated ? filterValue.slice(1) : filterValue).toLowerCase();
9999
100100
// No filter or empty query → return items directly
101-
if (!query) return data[property.name].map((item:any) => ({ item }));
101+
if (!query) return data[property.name].map((item: any) => ({ item }));
102102
103103
// Filtered items
104104
return data[property.name]
105-
.map((item:any) => ({ item }))
105+
.map((item: any) => ({ item }))
106106
.filter(({ item }: { item: any }) => {
107-
const matchFound = property.n.slice(0, 3).some((propertyN:any) => {
107+
const matchFound = property.n.slice(0, 3).some((propertyN: any) => {
108108
let valueStr;
109109
110110
if (
@@ -143,21 +143,23 @@
143143
<div class="h-16 flex w-full items-center justify-between space-x-3 p-0 text-xl font-medium">
144144
{initCap(property.name)}
145145
</div>
146-
<div class="relative w-full overflow-visible">
147-
<!-- <div class="mx-4 mb-4 flex flex-wrap justify-end gap-2"> -->
148-
<button
149-
class="btn btn-primary text-primary-content btn-md absolute -top-14 right-0"
150-
onclick={() => {
151-
addItem(property.name);
152-
153-
//add the new item to the data
154-
data[property.name].push(dataEditable);
155-
onChange();
156-
}}
157-
>
158-
<Add class="h-6 w-6" /></button
159-
>
160-
</div>
146+
{#if findItemInDefinition.crud == null || findItemInDefinition.crud.includes('c')}
147+
<div class="relative w-full overflow-visible">
148+
<!-- <div class="mx-4 mb-4 flex flex-wrap justify-end gap-2"> -->
149+
<button
150+
class="btn btn-primary text-primary-content btn-md absolute -top-14 right-0"
151+
onclick={() => {
152+
addItem(property.name);
153+
154+
//add the new item to the data
155+
data[property.name].push(dataEditable);
156+
onChange();
157+
}}
158+
>
159+
<Add class="h-6 w-6" /></button
160+
>
161+
</div>
162+
{/if}
161163

162164
<!-- Search Filter -->
163165
{#if findItemInDefinition.filter != null}
@@ -178,11 +180,18 @@
178180
{/if}
179181

180182
<div class="overflow-x-auto space-y-1" transition:slide|local={{ duration: 300, easing: cubicOut }}>
181-
<DraggableList items={filteredItems} onReorder={handleReorder} class="space-y-2">
183+
<DraggableList
184+
items={filteredItems}
185+
onReorder={handleReorder}
186+
class="space-y-2"
187+
dragDisabled={!(findItemInDefinition.crud == null || findItemInDefinition.crud.includes('s'))}
188+
>
182189
{#snippet children({ item: itemWrapper }: { item: any })}
183190
<!-- svelte-ignore a11y_click_events_have_key_events -->
184191
<div class="rounded-box bg-base-100 flex items-center space-x-3 px-4 py-2">
185-
<Grip class="h-6 w-6 text-base-content/30 cursor-grab flex-shrink-0" />
192+
{#if findItemInDefinition.crud == null || findItemInDefinition.crud.includes('s')}
193+
<Grip class="h-6 w-6 text-base-content/30 cursor-grab flex-shrink-0" />
194+
{/if}
186195
<!-- Show the first 3 fields -->
187196
{#each property.n.slice(0, 3) as propertyN}
188197
{#if propertyN.type != 'array' && propertyN.type != 'controls' && propertyN.type != 'password'}
@@ -217,14 +226,16 @@
217226
>
218227
<SearchIcon class="h-6 w-6" /></button
219228
>
220-
<button
221-
class="btn btn-ghost btn-sm"
222-
onclick={() => {
223-
deleteItem(property.name, itemWrapper.item);
224-
}}
225-
>
226-
<Delete class="text-error h-6 w-6" />
227-
</button>
229+
{#if findItemInDefinition.crud == null || findItemInDefinition.crud.includes('d')}
230+
<button
231+
class="btn btn-ghost btn-sm"
232+
onclick={() => {
233+
deleteItem(property.name, itemWrapper.item);
234+
}}
235+
>
236+
<Delete class="text-error h-6 w-6" />
237+
</button>
238+
{/if}
228239
</div>
229240
{/if}
230241
</div>

lib/framework/WWWData.h

Lines changed: 11529 additions & 11523 deletions
Large diffs are not rendered by default.

src/MoonBase/Modules/ModuleDevices.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class ModuleDevices : public Module {
3737

3838
control = addControl(controls, "devices", "rows");
3939
control["filter"] = "";
40+
control["crud"] = "r";
4041
rows = control["n"].to<JsonArray>();
4142
{
4243
addControl(rows, "name", "mdnsName", 0, 32, true);

src/MoonBase/Modules/ModuleIO.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ class ModuleIO : public Module {
139139

140140
control = addControl(controls, "pins", "rows");
141141
control["filter"] = "!Unused";
142+
control["crud"] = "ru";
143+
142144
rows = control["n"].to<JsonArray>();
143145
{
144146
control = addControl(rows, "GPIO", "number", 0, SOC_GPIO_PIN_COUNT - 1, true); // ro

src/MoonBase/Modules/ModuleTasks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class ModuleTasks : public Module {
3232

3333
control = addControl(controls, "tasks", "rows");
3434
control["filter"] = "";
35+
control["crud"] = "r";
3536
rows = control["n"].to<JsonArray>();
3637
{
3738
addControl(rows, "name", "text", 0, 32, true);

src/MoonBase/Nodes.h

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -74,39 +74,47 @@ class Node {
7474

7575
template <class ControlType>
7676
JsonObject addControl(const ControlType& variable, const char* name, const char* type, int min = 0, int max = UINT8_MAX, bool ro = false, const char* desc = nullptr) {
77-
uint32_t pointer = (uint32_t)&variable;
78-
7977
bool newControl = false; // flag to check if control is new or already exists
8078
// if control already exists only update it's pointer
8179
JsonObject control = JsonObject();
8280
for (JsonObject control1 : controls) {
8381
if (control1["name"] == name) {
8482
// EXT_LOGD(ML_TAG, "%s t:%s p:%p ps:%d", name, type, pointer, sizeof(ControlType));
85-
control1["p"] = pointer;
8683
control = control1; // set control to the found one
8784
break;
8885
}
8986
}
9087

91-
if (control.isNull()) { // if control not found, create a new one
88+
// if control not found, create a new one
89+
if (control.isNull()) {
9290
control = controls.add<JsonObject>();
9391
control["name"] = name;
94-
control["type"] = type;
95-
control["default"] = variable;
96-
97-
control["p"] = pointer;
98-
99-
if (ro) control["ro"] = true; // else if (!control["ro"].isNull()) control.remove("ro");
100-
if (min != 0) control["min"] = min; // else if (!control["min"].isNull()) control.remove("min");
101-
if (max != UINT8_MAX) control["max"] = max; // else if (!control["max"].isNull()) control.remove("max");
102-
if (desc) control["desc"] = desc;
103-
104-
newControl = true; // set flag to true, as control is new
92+
control["value"] = variable; // set default
93+
newControl = true; // set flag to true, as control is new
10594
}
10695

107-
control["valid"] = true; // invalid controls will be deleted
108-
109-
if (newControl) control["value"] = variable; // set default
96+
// update the control definition (see also setupDefinition...)
97+
control["type"] = type;
98+
control["default"] = variable;
99+
control["p"] = (uint32_t)&variable; // pointer to variable
100+
control["valid"] = true; // invalid controls will be deleted
101+
// optional properties
102+
if (ro)
103+
control["ro"] = true;
104+
else if (!control["ro"].isNull())
105+
control.remove("ro");
106+
if (min != 0)
107+
control["min"] = min;
108+
else if (!control["min"].isNull())
109+
control.remove("min");
110+
if (max != UINT8_MAX)
111+
control["max"] = max;
112+
else if (!control["max"].isNull())
113+
control.remove("max");
114+
if (desc)
115+
control["desc"] = desc;
116+
else if (!control["desc"].isNull())
117+
control.remove("desc");
110118

111119
// setValue
112120
if (control["type"] == "slider" || control["type"] == "select" || control["type"] == "pin" || control["type"] == "number") {
@@ -328,7 +336,6 @@ static struct SharedData {
328336
#include "MoonLight/Nodes/Drivers/D_Hub75.h"
329337
#include "MoonLight/Nodes/Drivers/D_Infrared.h"
330338
#include "MoonLight/Nodes/Drivers/D_PhysicalDriver.h"
331-
#include "MoonLight/Nodes/Drivers/D_VirtualDriver.h"
332339
#include "MoonLight/Nodes/Drivers/D__Sandbox.h"
333340
#include "MoonLight/Nodes/Effects/E_FastLED.h"
334341
#include "MoonLight/Nodes/Effects/E_MoonLight.h"

src/MoonBase/Utilities.h

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,66 @@
1414
#include <Arduino.h>
1515
#include <ESPFS.h>
1616

17-
#include "Char.h"
18-
1917
#include "ArduinoJson.h"
18+
#include "Char.h"
2019

2120
#define STRINGIFY(x) #x
2221
#define TOSTRING(x) STRINGIFY(x) // e.g. for pio.ini settings (see ML_CHIPSET)
2322

2423
// add task and stacksize to logging
2524
// if USE_ESP_IDF_LOG: USE_ESP_IDF_LOG is not showing __FILE__), __LINE__, __FUNCTION__ so add that
2625
#ifdef USE_ESP_IDF_LOG
27-
#define EXT_LOGE(tag, fmt, ...) ESP_LOGE(tag, "%s (%d) [%s:%d] %s: " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), pathToFileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
28-
#define EXT_LOGW(tag, fmt, ...) ESP_LOGW(tag, "%s (%d) [%s:%d] %s: " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), pathToFileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
29-
#define EXT_LOGI(tag, fmt, ...) ESP_LOGI(tag, "%s (%d) [%s:%d] %s: " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), pathToFileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
30-
#define EXT_LOGD(tag, fmt, ...) ESP_LOGD(tag, "%s (%d) [%s:%d] %s: " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), pathToFileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
31-
#define EXT_LOGV(tag, fmt, ...) ESP_LOGV(tag, "%s (%d) [%s:%d] %s: " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), pathToFileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
26+
#if CORE_DEBUG_LEVEL >= 1
27+
#define EXT_LOGE(tag, fmt, ...) ESP_LOGE(tag, "%s (%d) [%s:%d] %s: " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), pathToFileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
28+
#else
29+
#define EXT_LOGE(tag, fmt, ...)
30+
#endif
31+
#if CORE_DEBUG_LEVEL >= 2
32+
#define EXT_LOGW(tag, fmt, ...) ESP_LOGW(tag, "%s (%d) [%s:%d] %s: " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), pathToFileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
33+
#else
34+
#define EXT_LOGW(tag, fmt, ...)
35+
#endif
36+
#if CORE_DEBUG_LEVEL >= 3
37+
#define EXT_LOGI(tag, fmt, ...) ESP_LOGI(tag, "%s (%d) [%s:%d] %s: " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), pathToFileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
38+
#else
39+
#define EXT_LOGI(tag, fmt, ...)
40+
#endif
41+
#if CORE_DEBUG_LEVEL >= 4
42+
#define EXT_LOGD(tag, fmt, ...) ESP_LOGD(tag, "%s (%d) [%s:%d] %s: " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), pathToFileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
43+
#else
44+
#define EXT_LOGD(tag, fmt, ...)
45+
#endif
46+
#if CORE_DEBUG_LEVEL >= 5
47+
#define EXT_LOGV(tag, fmt, ...) ESP_LOGV(tag, "%s (%d) [%s:%d] %s: " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), pathToFileName(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__)
48+
#else
49+
#define EXT_LOGV(tag, fmt, ...)
50+
#endif
3251
#else
33-
#define EXT_LOGE(tag, fmt, ...) ESP_LOGE(tag, "%s (%d) " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), ##__VA_ARGS__)
34-
#define EXT_LOGW(tag, fmt, ...) ESP_LOGW(tag, "%s (%d) " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), ##__VA_ARGS__)
35-
#define EXT_LOGI(tag, fmt, ...) ESP_LOGI(tag, "%s (%d) " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), ##__VA_ARGS__)
36-
#define EXT_LOGD(tag, fmt, ...) ESP_LOGD(tag, "%s (%d) " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), ##__VA_ARGS__)
37-
#define EXT_LOGV(tag, fmt, ...) ESP_LOGV(tag, "%s (%d) " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), ##__VA_ARGS__)
52+
#if CORE_DEBUG_LEVEL >= 1
53+
#define EXT_LOGE(tag, fmt, ...) ESP_LOGE(tag, "%s (%d) " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), ##__VA_ARGS__)
54+
#else
55+
#define EXT_LOGE(tag, fmt, ...)
56+
#endif
57+
#if CORE_DEBUG_LEVEL >= 2
58+
#define EXT_LOGW(tag, fmt, ...) ESP_LOGW(tag, "%s (%d) " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), ##__VA_ARGS__)
59+
#else
60+
#define EXT_LOGW(tag, fmt, ...)
61+
#endif
62+
#if CORE_DEBUG_LEVEL >= 3
63+
#define EXT_LOGI(tag, fmt, ...) ESP_LOGI(tag, "%s (%d) " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), ##__VA_ARGS__)
64+
#else
65+
#define EXT_LOGI(tag, fmt, ...)
66+
#endif
67+
#if CORE_DEBUG_LEVEL >= 4
68+
#define EXT_LOGD(tag, fmt, ...) ESP_LOGD(tag, "%s (%d) " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), ##__VA_ARGS__)
69+
#else
70+
#define EXT_LOGD(tag, fmt, ...)
71+
#endif
72+
#if CORE_DEBUG_LEVEL >= 5
73+
#define EXT_LOGV(tag, fmt, ...) ESP_LOGV(tag, "%s (%d) " fmt, pcTaskGetName(xTaskGetCurrentTaskHandle()), uxTaskGetStackHighWaterMark(xTaskGetCurrentTaskHandle()), ##__VA_ARGS__)
74+
#else
75+
#define EXT_LOGV(tag, fmt, ...)
76+
#endif
3877
#endif
3978

4079
#define MB_TAG "🌙"
@@ -227,6 +266,6 @@ extern unsigned char moonmanpng[];
227266
extern unsigned int moonmanpng_len;
228267
#endif
229268

230-
static inline uint32_t fastDiv255(uint32_t x) { //3–4 cycles
231-
return (x * 0x8081u) >> 23;
269+
static inline uint32_t fastDiv255(uint32_t x) { // 3–4 cycles
270+
return (x * 0x8081u) >> 23;
232271
}

src/MoonLight/Layers/PhysicalLayer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ void PhysicalLayer::onLayoutPre() {
136136
memset(ledsPerPin, 0xFF, sizeof(ledsPerPin)); // UINT16_MAX is 2 * 0xFF
137137
memset(ledPinsAssigned, 0, sizeof(ledPinsAssigned));
138138
}
139+
nrOfAssignedPins = 0;
139140
} else if (pass == 2) {
140141
indexP = 0;
141142
for (VirtualLayer* layer : layers) {

0 commit comments

Comments
 (0)