feat: add labels to NodeInfo
This commit is contained in:
@@ -19,6 +19,13 @@ void setup() {
|
|||||||
// 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();
|
||||||
|
|
||||||
|
|||||||
@@ -349,6 +349,15 @@ NeoPixelService neoService(ctx, taskManager, NEOPIXEL_COUNT, NEOPIXEL_PIN, NEOPI
|
|||||||
void setup() {
|
void setup() {
|
||||||
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"] = "neopixel";
|
||||||
|
it->second.labels["device"] = "light";
|
||||||
|
it->second.labels["pixels"] = String(NEOPIXEL_COUNT);
|
||||||
|
it->second.labels["pin"] = String(NEOPIXEL_PIN);
|
||||||
|
}
|
||||||
|
|
||||||
taskManager.initialize();
|
taskManager.initialize();
|
||||||
|
|
||||||
apiServer.begin();
|
apiServer.begin();
|
||||||
|
|||||||
@@ -107,6 +107,14 @@ void setup() {
|
|||||||
// 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();
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <IPAddress.h>
|
#include <IPAddress.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
struct NodeInfo {
|
struct NodeInfo {
|
||||||
String hostname;
|
String hostname;
|
||||||
@@ -18,6 +19,7 @@ struct NodeInfo {
|
|||||||
} resources;
|
} resources;
|
||||||
unsigned long latency = 0; // ms since lastSeen
|
unsigned long latency = 0; // ms since lastSeen
|
||||||
std::vector<std::tuple<String, int>> apiEndpoints; // List of registered endpoints
|
std::vector<std::tuple<String, int>> apiEndpoints; // List of registered endpoints
|
||||||
|
std::map<String, String> labels; // Arbitrary node labels (key -> value)
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* statusToStr(NodeInfo::Status status);
|
const char* statusToStr(NodeInfo::Status status);
|
||||||
|
|||||||
@@ -95,6 +95,16 @@ void ApiServer::onSystemStatusRequest(AsyncWebServerRequest *request) {
|
|||||||
apiObj["uri"] = std::get<0>(entry);
|
apiObj["uri"] = std::get<0>(entry);
|
||||||
apiObj["method"] = std::get<1>(entry);
|
apiObj["method"] = std::get<1>(entry);
|
||||||
}
|
}
|
||||||
|
// Include local node labels if present
|
||||||
|
if (ctx.memberList) {
|
||||||
|
auto it = ctx.memberList->find(ctx.hostname);
|
||||||
|
if (it != ctx.memberList->end()) {
|
||||||
|
JsonObject labelsObj = doc["labels"].to<JsonObject>();
|
||||||
|
for (const auto& kv : it->second.labels) {
|
||||||
|
labelsObj[kv.first.c_str()] = kv.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
String json;
|
String json;
|
||||||
serializeJson(doc, json);
|
serializeJson(doc, json);
|
||||||
request->send(200, "application/json", json);
|
request->send(200, "application/json", json);
|
||||||
@@ -122,6 +132,13 @@ void ApiServer::onClusterMembersRequest(AsyncWebServerRequest *request) {
|
|||||||
apiObj["uri"] = std::get<0>(endpoint);
|
apiObj["uri"] = std::get<0>(endpoint);
|
||||||
methodToStr(endpoint, apiObj);
|
methodToStr(endpoint, apiObj);
|
||||||
}
|
}
|
||||||
|
// Add labels if present
|
||||||
|
if (!node.labels.empty()) {
|
||||||
|
JsonObject labelsObj = obj["labels"].to<JsonObject>();
|
||||||
|
for (const auto& kv : node.labels) {
|
||||||
|
labelsObj[kv.first.c_str()] = kv.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
String json;
|
String json;
|
||||||
serializeJson(doc, json);
|
serializeJson(doc, json);
|
||||||
|
|||||||
@@ -118,6 +118,16 @@ void ClusterManager::fetchNodeInfo(const IPAddress& ip) {
|
|||||||
node.apiEndpoints.push_back(std::make_tuple(uri, method));
|
node.apiEndpoints.push_back(std::make_tuple(uri, method));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Parse labels if present
|
||||||
|
node.labels.clear();
|
||||||
|
if (doc["labels"].is<JsonObject>()) {
|
||||||
|
JsonObject labelsObj = doc["labels"].as<JsonObject>();
|
||||||
|
for (JsonPair kvp : labelsObj) {
|
||||||
|
String k = String(kvp.key().c_str());
|
||||||
|
String v = String(labelsObj[kvp.key()]);
|
||||||
|
node.labels[k] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
Serial.printf("[Cluster] Fetched info for node: %s @ %s\n", node.hostname.c_str(), ip.toString().c_str());
|
Serial.printf("[Cluster] Fetched info for node: %s @ %s\n", node.hostname.c_str(), ip.toString().c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,5 +54,7 @@ void NetworkManager::setupWiFi() {
|
|||||||
}
|
}
|
||||||
self.lastSeen = millis();
|
self.lastSeen = millis();
|
||||||
self.status = NodeInfo::ACTIVE;
|
self.status = NodeInfo::ACTIVE;
|
||||||
|
// Initialize a default label for demonstration; users can modify at runtime
|
||||||
|
self.labels["hostname"] = ctx.hostname;
|
||||||
ctx.fire("node_discovered", &self);
|
ctx.fire("node_discovered", &self);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user