feat: set labels in NodeContext/Info

This commit is contained in:
2025-08-29 20:21:11 +02:00
parent d3a9802ec9
commit fe045804cb
7 changed files with 61 additions and 42 deletions

View File

@@ -9,23 +9,21 @@
using namespace std; using namespace std;
NodeContext ctx; NodeContext ctx({
{"app", "base"},
{"role", "demo"}
});
NetworkManager network(ctx); NetworkManager network(ctx);
TaskManager taskManager(ctx); TaskManager taskManager(ctx);
ClusterManager cluster(ctx, taskManager); ClusterManager cluster(ctx, taskManager);
ApiServer apiServer(ctx, taskManager, ctx.config.api_server_port); ApiServer apiServer(ctx, taskManager, ctx.config.api_server_port);
void setup() { void setup() {
Serial.begin(115200);
// Setup WiFi first // Setup WiFi first
network.setupWiFi(); network.setupWiFi();
// Add example labels for this node
auto it = ctx.memberList->find(ctx.hostname);
if (it != ctx.memberList->end()) {
it->second.labels["app"] = "base";
it->second.labels["role"] = "demo";
}
// Initialize and start all tasks // Initialize and start all tasks
taskManager.initialize(); taskManager.initialize();

View File

@@ -339,7 +339,12 @@ private:
uint8_t brightness; uint8_t brightness;
}; };
NodeContext ctx; NodeContext ctx({
{"app", "neopixel"},
{"device", "light"},
{"pixels", String(NEOPIXEL_COUNT)},
{"pin", String(NEOPIXEL_PIN)}
});
NetworkManager network(ctx); NetworkManager network(ctx);
TaskManager taskManager(ctx); TaskManager taskManager(ctx);
ClusterManager cluster(ctx, taskManager); ClusterManager cluster(ctx, taskManager);
@@ -347,16 +352,9 @@ ApiServer apiServer(ctx, taskManager, ctx.config.api_server_port);
NeoPixelService neoService(ctx, taskManager, NEOPIXEL_COUNT, NEOPIXEL_PIN, NEOPIXEL_TYPE); NeoPixelService neoService(ctx, taskManager, NEOPIXEL_COUNT, NEOPIXEL_PIN, NEOPIXEL_TYPE);
void setup() { void setup() {
network.setupWiFi(); Serial.begin(115200);
// Add example labels for this node network.setupWiFi();
auto it = ctx.memberList->find(ctx.hostname);
if (it != ctx.memberList->end()) {
it->second.labels["app"] = "neopixel";
it->second.labels["device"] = "light";
it->second.labels["pixels"] = String(NEOPIXEL_COUNT);
it->second.labels["pin"] = String(NEOPIXEL_PIN);
}
taskManager.initialize(); taskManager.initialize();

View File

@@ -96,7 +96,11 @@ private:
bool relayOn; bool relayOn;
}; };
NodeContext ctx; NodeContext ctx({
{"app", "relay"},
{"device", "actuator"},
{"pin", String(RELAY_PIN)}
});
NetworkManager network(ctx); NetworkManager network(ctx);
TaskManager taskManager(ctx); TaskManager taskManager(ctx);
ClusterManager cluster(ctx, taskManager); ClusterManager cluster(ctx, taskManager);
@@ -104,17 +108,11 @@ ApiServer apiServer(ctx, taskManager, ctx.config.api_server_port);
RelayService relayService(ctx, taskManager, RELAY_PIN); RelayService relayService(ctx, taskManager, RELAY_PIN);
void setup() { void setup() {
Serial.begin(115200);
// Setup WiFi first // Setup WiFi first
network.setupWiFi(); network.setupWiFi();
// Add example labels for this node
auto it = ctx.memberList->find(ctx.hostname);
if (it != ctx.memberList->end()) {
it->second.labels["app"] = "relay";
it->second.labels["device"] = "actuator";
it->second.labels["pin"] = String(RELAY_PIN);
}
// Initialize and start all tasks // Initialize and start all tasks
taskManager.initialize(); taskManager.initialize();

View File

@@ -5,15 +5,18 @@
#include "NodeInfo.h" #include "NodeInfo.h"
#include <functional> #include <functional>
#include <string> #include <string>
#include <initializer_list>
#include "Config.h" #include "Config.h"
class NodeContext { class NodeContext {
public: public:
NodeContext(); NodeContext();
NodeContext(std::initializer_list<std::pair<String, String>> initialLabels);
~NodeContext(); ~NodeContext();
WiFiUDP* udp; WiFiUDP* udp;
String hostname; String hostname;
IPAddress localIP; IPAddress localIP;
NodeInfo self;
std::map<String, NodeInfo>* memberList; std::map<String, NodeInfo>* memberList;
Config config; Config config;

View File

@@ -103,6 +103,11 @@ void ApiServer::onSystemStatusRequest(AsyncWebServerRequest *request) {
for (const auto& kv : it->second.labels) { for (const auto& kv : it->second.labels) {
labelsObj[kv.first.c_str()] = kv.second; labelsObj[kv.first.c_str()] = kv.second;
} }
} else if (!ctx.self.labels.empty()) {
JsonObject labelsObj = doc["labels"].to<JsonObject>();
for (const auto& kv : ctx.self.labels) {
labelsObj[kv.first.c_str()] = kv.second;
}
} }
} }
String json; String json;

View File

@@ -14,7 +14,6 @@ void NetworkManager::setHostnameFromMac() {
} }
void NetworkManager::setupWiFi() { void NetworkManager::setupWiFi() {
Serial.begin(115200);
WiFi.mode(WIFI_STA); WiFi.mode(WIFI_STA);
WiFi.begin(ctx.config.wifi_ssid.c_str(), ctx.config.wifi_password.c_str()); WiFi.begin(ctx.config.wifi_ssid.c_str(), ctx.config.wifi_password.c_str());
Serial.println("[WiFi] Connecting to AP..."); Serial.println("[WiFi] Connecting to AP...");
@@ -43,18 +42,26 @@ void NetworkManager::setupWiFi() {
Serial.println(ctx.hostname); Serial.println(ctx.hostname);
Serial.printf("[WiFi] UDP listening on port %d\n", ctx.config.udp_port); Serial.printf("[WiFi] UDP listening on port %d\n", ctx.config.udp_port);
// Register this node in the memberlist via event system // Populate self NodeInfo
NodeInfo self; ctx.self.hostname = ctx.hostname;
self.hostname = ctx.hostname; if (WiFi.isConnected()) {
if(WiFi.isConnected()) { ctx.self.ip = WiFi.localIP();
self.ip = WiFi.localIP();
} else { } else {
// Fallback to AP IP if not connected ctx.self.ip = WiFi.softAPIP();
self.ip = WiFi.softAPIP();
} }
self.lastSeen = millis(); ctx.self.lastSeen = millis();
self.status = NodeInfo::ACTIVE; ctx.self.status = NodeInfo::ACTIVE;
// Initialize a default label for demonstration; users can modify at runtime ctx.self.labels["hostname"] = ctx.hostname;
self.labels["hostname"] = ctx.hostname;
ctx.fire("node_discovered", &self); // Ensure member list has an entry for this node
auto &memberList = *ctx.memberList;
auto existing = memberList.find(ctx.hostname);
if (existing == memberList.end()) {
memberList[ctx.hostname] = ctx.self;
} else {
existing->second = ctx.self;
}
// Notify listeners that the node is (re)discovered
ctx.fire("node_discovered", &ctx.self);
} }

View File

@@ -4,6 +4,16 @@ NodeContext::NodeContext() {
udp = new WiFiUDP(); udp = new WiFiUDP();
memberList = new std::map<String, NodeInfo>(); memberList = new std::map<String, NodeInfo>();
hostname = ""; hostname = "";
self.hostname = "";
self.ip = IPAddress();
self.lastSeen = 0;
self.status = NodeInfo::INACTIVE;
}
NodeContext::NodeContext(std::initializer_list<std::pair<String, String>> initialLabels) : NodeContext() {
for (const auto& kv : initialLabels) {
self.labels[kv.first] = kv.second;
}
} }
NodeContext::~NodeContext() { NodeContext::~NodeContext() {