Skip to content

Commit

Permalink
Refactor Instances module, DDP/Artnet uses instance ip
Browse files Browse the repository at this point in the history
index.js
- processUpdate, check if not model.json

Module
- connectedChanged and enabledChanged call onOffChanged

SysModUI
- remove okay check before

UserModArtNet, DDP
- add UI to select ip

UserModE131
- use onOffChanged trigger

UserModInstances
- rename from UserModWLEDDIscovery
- nodes vector of NodeInfo instead of dictionary
- add UI to display nodes
- use onOffChanged trigger
- check once per second
- read node name from packet contents
- use timestamp to remove node if no update in 32 seconds (WLED sends each 30 seconds)
  • Loading branch information
ewowi committed Aug 13, 2023
1 parent a443e64 commit 7813c0b
Show file tree
Hide file tree
Showing 15 changed files with 638 additions and 524 deletions.
11 changes: 5 additions & 6 deletions data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ function makeWS() {
console.log("Error: no valid model", json);
}
else { //update
// console.log("WS receive update", json);
processUpdate(json);
if (!Array.isArray(json)) //only the model is an array
// console.log("WS receive update", json);
processUpdate(json);
}
}
}
Expand Down Expand Up @@ -345,7 +346,7 @@ function flushUIFunCommands() {
if (uiFunCommands.length > 0) { //if something to flush
var command = {};
command["uiFun"] = uiFunCommands; //ask to run uiFun for vars (to add the options)
console.log("uiFunCommands", command);
// console.log("flushUIFunCommands", command);
requestJson(command);
uiFunCommands = [];
}
Expand Down Expand Up @@ -451,14 +452,12 @@ function processVarNode(node, key, json) {
}
}
if (json.hasOwnProperty("table")) {
console.log("processUpdate table", key, json.table);
//remove table rows
let tbodyNode = cE('tbody');


//find model info
let variable = findVar(key);
console.log("processUpdate table model", variable);
console.log("processUpdate table", key, variable, json.table);

//add each row
let rowNr = 0;
Expand Down
1 change: 0 additions & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ lib_deps =
https://github.com/me-no-dev/ESPAsyncWebServer.git
; https://github.com/lost-hope/ESPAsyncWebServer.git#master
https://github.com/bblanchon/ArduinoJson.git
https://github.com/netmindz/Dictionary.git#first

[appmod_leds]
build_flags =
Expand Down
7 changes: 3 additions & 4 deletions src/App/AppModLeds.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class AppModLeds:public Module {
print->print("Set Brightness to %d -> %d\n", var["value"].as<int>(), bri);
});

ui->initSelect(parentVar, "fx", 6, false, [](JsonObject var) { //uiFun. 6: Juggles is default
ui->initSelect(parentVar, "fx", 0, false, [](JsonObject var) { //uiFun
web->addResponse(var["id"], "label", "Effect");
web->addResponse(var["id"], "comment", "Effect to show");
JsonArray select = web->addResponseA(var["id"], "select");
Expand Down Expand Up @@ -95,7 +95,7 @@ class AppModLeds:public Module {
} // fx < size
});

ui->initSelect(parentVar, "projection", -1, false, [](JsonObject var) { //uiFun. 1: is default
ui->initSelect(parentVar, "projection", 0, false, [](JsonObject var) { //uiFun.
// web->addResponse(var["id"], "label", "Effect");
web->addResponse(var["id"], "comment", "How to project fx to fixture");
JsonArray select = web->addResponseA(var["id"], "select");
Expand Down Expand Up @@ -128,7 +128,7 @@ class AppModLeds:public Module {
buffer[3] = max(LedsV::nrOfLedsP * SysModWeb::ws->count()/200, 16U); //interval in ms * 10, not too fast
});

ui->initSelect(parentVar, "ledFix", -1, false, [](JsonObject var) { //uiFun
ui->initSelect(parentVar, "ledFix", 0, false, [](JsonObject var) { //uiFun
web->addResponse(var["id"], "label", "LedFix");
web->addResponse(var["id"], "comment", "Fixture to display effect on");
JsonArray select = web->addResponseA(var["id"], "select");
Expand Down Expand Up @@ -162,7 +162,6 @@ class AppModLeds:public Module {
char details[32] = "";
print->fFormat(details, sizeof(details), "P:%dx%dx%d V:%dx%dx%d", LedsV::widthP, LedsV::heightP, LedsV::depthP, LedsV::widthV, LedsV::heightV, LedsV::depthV);
web->addResponse(var["id"], "value", details);
}, [](JsonObject var) { //chFun
});

ui->initText(parentVar, "nrOfLeds", nullptr, true, [](JsonObject var) { //uiFun
Expand Down
5 changes: 3 additions & 2 deletions src/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ class Module {

virtual void loop() {}

virtual void connectedChanged() {}
virtual void enabledChanged() {}
virtual void connectedChanged() {onOffChanged();}
virtual void enabledChanged() {onOffChanged();}
virtual void onOffChanged() {}

virtual void testManager() {}
virtual void performanceManager() {}
Expand Down
2 changes: 1 addition & 1 deletion src/Sys/SysModFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void SysModFiles::loop(){

mdl->setValueV("drsize", "%d / %d B", usedBytes(), totalBytes());

// if something changed in clist
// if something changed in fileTbl
if (filesChanged) {
filesChanged = false;

Expand Down
14 changes: 3 additions & 11 deletions src/Sys/SysModUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,6 @@ void SysModUI::loop() {

SysModWeb::ws->cleanupClients();
if (SysModWeb::ws->count()) {
//check if there are valid clients before!!!
bool okay = false;
for (auto client:SysModWeb::ws->getClients()) {
if (client->status() == WS_CONNECTED && !client->queueIsFull())
okay = true;
}

if (okay) {

SysModWeb::wsSendBytesCounter++;

//send var to notify client data coming is for var (client then knows it is canvas and expects data for it)
Expand Down Expand Up @@ -124,7 +115,6 @@ void SysModUI::loop() {
SysModWeb::ws->cleanupClients(0); //disconnect all clients to release memory
SysModWeb::ws->_cleanBuffers();
}
} // if okay
}

varLoop->counter++;
Expand Down Expand Up @@ -270,10 +260,12 @@ const char * SysModUI::processJson(JsonVariant &json) {
//call ui function...
if (!var["uiFun"].isNull()) {//isnull needed here!
size_t funNr = var["uiFun"];
if (funNr < ucFunctions.size())
if (funNr < ucFunctions.size())
ucFunctions[funNr](var);
else
print->print("processJson function nr %s outside bounds %d >= %d\n", var["id"].as<const char *>(), funNr, ucFunctions.size());

//if select var, send value back
if (var["type"] == "select")
web->addResponseI(var["id"], "value", var["value"]); //temp assume int only

Expand Down
43 changes: 19 additions & 24 deletions src/Sys/SysModWeb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ AsyncWebSocket * SysModWeb::ws = nullptr;

const char * (*SysModWeb::processWSFunc)(JsonVariant &) = nullptr;

DynamicJsonDocument * SysModWeb::responseDoc0 = nullptr;
DynamicJsonDocument * SysModWeb::responseDoc1 = nullptr;
DynamicJsonDocument * SysModWeb::responseDocLoopTask = nullptr;
DynamicJsonDocument * SysModWeb::responseDocAsyncTCP = nullptr;
bool SysModWeb::clientsChanged = false;

unsigned long SysModWeb::wsSendBytesCounter = 0;
Expand All @@ -38,8 +38,8 @@ unsigned long SysModWeb::wsSendJsonCounter = 0;
SysModWeb::SysModWeb() :Module("Web") {
ws = new AsyncWebSocket("/ws");
server = new AsyncWebServer(80);
responseDoc0 = new DynamicJsonDocument(2048);
responseDoc1 = new DynamicJsonDocument(2048);
responseDocLoopTask = new DynamicJsonDocument(2048);
responseDocAsyncTCP = new DynamicJsonDocument(3072);
};

void SysModWeb::setup() {
Expand All @@ -48,13 +48,13 @@ void SysModWeb::setup() {

parentVar = ui->initModule(parentVar, name);

JsonObject tableVar = ui->initTable(parentVar, "clist", nullptr, false, [](JsonObject var) { //uiFun
JsonObject tableVar = ui->initTable(parentVar, "clTbl", nullptr, false, [](JsonObject var) { //uiFun
web->addResponse(var["id"], "label", "Clients");
web->addResponse(var["id"], "comment", "List of clients");
JsonArray rows = web->addResponseA(var["id"], "table");
web->clientsToJson(rows);
});
ui->initText(tableVar, "clNr", nullptr, true, [](JsonObject var) { //uiFun
ui->initNumber(tableVar, "clNr", -1, true, [](JsonObject var) { //uiFun
web->addResponse(var["id"], "label", "Nr");
});
ui->initText(tableVar, "clIp", nullptr, true, [](JsonObject var) { //uiFun
Expand All @@ -76,6 +76,9 @@ void SysModWeb::setup() {

ui->initText(parentVar, "wsSendBytes");
ui->initText(parentVar, "wsSendJson");
ui->initNumber(parentVar, "queueLength", WS_MAX_QUEUED_MESSAGES, true, [](JsonObject var) { //uiFun
web->addResponse(var["id"], "comment", "32 not enough, investigate...");
});

print->print("%s %s %s\n", __PRETTY_FUNCTION__, name, success?"success":"failed");
}
Expand All @@ -92,11 +95,11 @@ void SysModWeb::loop() {
if (millis() - secondMillis >= 1000) {
secondMillis = millis();

// if something changed in clist
// if something changed in clTbl
if (clientsChanged) {
clientsChanged = false;

ui->processUiFun("clist");
ui->processUiFun("clTbl");
}

uint8_t rowNr = 0;
Expand Down Expand Up @@ -344,7 +347,8 @@ void SysModWeb::wsEvent2(AsyncWebSocket * server, AsyncWebSocketClient * client,


void SysModWeb::printClient(const char * text, AsyncWebSocketClient * client) {
print->print("%s client: %d %s q:%d s:%d (w:%d)\n", text, client?client->id():-1, client?client->remoteIP().toString().c_str():"No", client->queueIsFull(), client->status(), ws->count());
print->print("%s client: %d %s q:%d s:%d (#:%d)\n", text, client?client->id():-1, client?client->remoteIP().toString().c_str():"No", client->queueIsFull(), client->status(), ws->count());
//status: { WS_DISCONNECTED, WS_CONNECTED, WS_DISCONNECTING }
}

void SysModWeb::sendDataWs(AsyncWebSocketClient * client, JsonVariant json) {
Expand All @@ -354,37 +358,29 @@ void SysModWeb::sendDataWs(AsyncWebSocketClient * client, JsonVariant json) {
}
// return;
wsSendJsonCounter++;
// ws->cleanupClients();
ws->cleanupClients();

if (ws->count()) {
bool okay = false;
for (auto client:SysModWeb::ws->getClients()) {
if (client->status() == WS_CONNECTED && !client->queueIsFull())
okay = true;
}

if (okay) {

size_t len = measureJson(json);
AsyncWebSocketMessageBuffer *wsBuf = ws->makeBuffer(len);

if (wsBuf) {
wsBuf->lock();
serializeJson(json, (char *)wsBuf->get(), len);
if (client) {
if (client->status() == WS_CONNECTED && !client->queueIsFull())
if (client->status() == WS_CONNECTED && !client->queueIsFull())
client->text(wsBuf);
else
printClient("sendDataWs client full or not connected", client);

// DEBUG_PRINTLN(F("to a single client."));
} else {
for (auto client:ws->getClients()) {
if (client->status() == WS_CONNECTED && !client->queueIsFull())
if (client->status() == WS_CONNECTED && !client->queueIsFull())
client->text(wsBuf);
else
// printClient("sendDataWs client full or not connected", client); //crash??
print->print("sendDataWs client full or not connected\n");
printClient("sendDataWs client(s) full or not connected", client); //crash??
// print->print("sendDataWs client full or not connected\n");
}
// DEBUG_PRINTLN(F("to multiple clients."));
}
Expand All @@ -397,7 +393,6 @@ void SysModWeb::sendDataWs(AsyncWebSocketClient * client, JsonVariant json) {
ws->cleanupClients(); //disconnect all clients to release memory
ws->_cleanBuffers();
}
} //if okay
}
}

Expand Down Expand Up @@ -595,5 +590,5 @@ void SysModWeb::clientsToJson(JsonArray array, bool nameOnly, const char * filte
JsonDocument * SysModWeb::getResponseDoc() {
// print->print("response wsevent core %d %s\n", xPortGetCoreID(), pcTaskGetTaskName(NULL));

return strncmp(pcTaskGetTaskName(NULL), "loopTask", 8) != 0?web->responseDoc0:web->responseDoc1;
return strncmp(pcTaskGetTaskName(NULL), "loopTask", 8) == 0?web->responseDocLoopTask:web->responseDocAsyncTCP;
}
4 changes: 2 additions & 2 deletions src/Sys/SysModWeb.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ class SysModWeb:public Module {
static AsyncWebServer *server;
static const char * (*processWSFunc)(JsonVariant &);

static DynamicJsonDocument *responseDoc0;
static DynamicJsonDocument *responseDoc1;
static DynamicJsonDocument *responseDocLoopTask;
static DynamicJsonDocument *responseDocAsyncTCP;

};

Expand Down
39 changes: 29 additions & 10 deletions src/User/UserModArtNet.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,33 @@ class UserModArtNet:public Module {

public:

IPAddress targetIp;
static IPAddress targetIp; //tbd: targetip also configurable from fixtures and artnet instead of pin output

UserModArtNet() :Module("ArtNet") {
print->print("%s %s\n", __PRETTY_FUNCTION__, name);

isEnabled = false;
isEnabled = false; //default off

parentVar = ui->initModule(parentVar, name);

ui->initSelect(parentVar, "artInst", -1, false, [](JsonObject var) { //uiFun
web->addResponse(var["id"], "label", "Instance");
web->addResponse(var["id"], "comment", "Instance to send data");
JsonArray select = web->addResponseA(var["id"], "select");
for (NodeInfo node: UserModInstances::nodes) {
char option[32] = { 0 };
strcpy(option, node.ip.toString().c_str());
strcat(option, " ");
strcat(option, node.details);
select.add(option);
}
}, [](JsonObject var) { //chFun
size_t ddpInst = var["value"];
if (ddpInst >=0 && ddpInst < UserModInstances::nodes.size()) {
targetIp = UserModInstances::nodes[ddpInst].ip;
print->print("Start ArtNet to %s\n", targetIp.toString().c_str());
}
}); //ddpInst

print->print("%s %s %s\n", __PRETTY_FUNCTION__, name, success?"success":"failed");
};
Expand All @@ -31,21 +52,17 @@ class UserModArtNet:public Module {
void setup() {
Module::setup();
print->print("%s %s\n", __PRETTY_FUNCTION__, name);
targetIp = IPAddress(0,0,0,0); // TODO allow setting at runtime

print->print("%s %s %s\n", __PRETTY_FUNCTION__, name, success?"success":"failed");
}

// void connectedChanged() {
// if (SysModModules::isConnected) {
// print->print("%s %s - Connected\n", __PRETTY_FUNCTION__, name);
// }
// }

void loop(){
// Module::loop();

if(!SysModModules::isConnected) return;

if(!targetIp) return;

if(!lds->newFrame) return;

// calculate the number of UDP packets we need to send
Expand Down Expand Up @@ -114,4 +131,6 @@ class UserModArtNet:public Module {

};

static UserModArtNet *artnetmod;
static UserModArtNet *artnetmod;

IPAddress UserModArtNet::targetIp;
Loading

0 comments on commit 7813c0b

Please sign in to comment.