feat: services (#2)
This commit is contained in:
@@ -10,52 +10,33 @@
|
||||
#include "NodeContext.h"
|
||||
#include "NodeInfo.h"
|
||||
#include "TaskManager.h"
|
||||
#include "ApiTypes.h"
|
||||
|
||||
class Service; // Forward declaration
|
||||
|
||||
class ApiServer {
|
||||
public:
|
||||
ApiServer(NodeContext& ctx, TaskManager& taskMgr, uint16_t port = 80);
|
||||
void begin();
|
||||
void addService(Service& service);
|
||||
void addEndpoint(const String& uri, int method, std::function<void(AsyncWebServerRequest*)> requestHandler);
|
||||
void addEndpoint(const String& uri, int method, std::function<void(AsyncWebServerRequest*)> requestHandler,
|
||||
std::function<void(AsyncWebServerRequest*, const String&, size_t, uint8_t*, size_t, bool)> uploadHandler);
|
||||
|
||||
// Minimal capability spec types and registration overloads
|
||||
struct ParamSpec {
|
||||
String name;
|
||||
bool required;
|
||||
String location; // "query" | "body" | "path" | "header"
|
||||
String type; // e.g. "string", "number", "boolean"
|
||||
std::vector<String> values; // optional allowed values
|
||||
};
|
||||
struct EndpointCapability {
|
||||
String uri;
|
||||
int method;
|
||||
std::vector<ParamSpec> params;
|
||||
};
|
||||
void addEndpoint(const String& uri, int method, std::function<void(AsyncWebServerRequest*)> requestHandler,
|
||||
const std::vector<ParamSpec>& params);
|
||||
void addEndpoint(const String& uri, int method, std::function<void(AsyncWebServerRequest*)> requestHandler,
|
||||
std::function<void(AsyncWebServerRequest*, const String&, size_t, uint8_t*, size_t, bool)> uploadHandler,
|
||||
const std::vector<ParamSpec>& params);
|
||||
|
||||
static const char* methodToStr(int method);
|
||||
|
||||
private:
|
||||
AsyncWebServer server;
|
||||
NodeContext& ctx;
|
||||
TaskManager& taskManager;
|
||||
std::vector<std::reference_wrapper<Service>> services;
|
||||
std::vector<std::tuple<String, int>> serviceRegistry;
|
||||
std::vector<EndpointCapability> capabilityRegistry;
|
||||
void onClusterMembersRequest(AsyncWebServerRequest *request);
|
||||
void methodToStr(const std::tuple<String, int> &endpoint, JsonObject &apiObj);
|
||||
void onSystemStatusRequest(AsyncWebServerRequest *request);
|
||||
void onFirmwareUpdateRequest(AsyncWebServerRequest *request);
|
||||
void onFirmwareUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final);
|
||||
void onRestartRequest(AsyncWebServerRequest *request);
|
||||
|
||||
// Task management endpoints
|
||||
void onTaskStatusRequest(AsyncWebServerRequest *request);
|
||||
void onTaskControlRequest(AsyncWebServerRequest *request);
|
||||
|
||||
// Capabilities endpoint
|
||||
void onCapabilitiesRequest(AsyncWebServerRequest *request);
|
||||
|
||||
// Internal helpers
|
||||
void registerServiceForLocalNode(const String& uri, int method);
|
||||
|
||||
18
include/ApiTypes.h
Normal file
18
include/ApiTypes.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include <vector>
|
||||
|
||||
struct ParamSpec {
|
||||
String name;
|
||||
bool required;
|
||||
String location; // "query" | "body" | "path" | "header"
|
||||
String type; // e.g. "string", "number", "boolean"
|
||||
std::vector<String> values; // optional allowed values
|
||||
String defaultValue; // optional default value (stringified)
|
||||
};
|
||||
|
||||
struct EndpointCapability {
|
||||
String uri;
|
||||
int method;
|
||||
std::vector<ParamSpec> params;
|
||||
};
|
||||
@@ -1,12 +1,49 @@
|
||||
#pragma once
|
||||
#include "NodeContext.h"
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <vector>
|
||||
|
||||
struct AccessPoint {
|
||||
String ssid;
|
||||
int32_t rssi;
|
||||
uint8_t encryptionType;
|
||||
uint8_t* bssid;
|
||||
int32_t channel;
|
||||
bool isHidden;
|
||||
};
|
||||
|
||||
class NetworkManager {
|
||||
public:
|
||||
NetworkManager(NodeContext& ctx);
|
||||
void setupWiFi();
|
||||
void setHostnameFromMac();
|
||||
|
||||
// WiFi scanning methods
|
||||
void scanWifi();
|
||||
void processAccessPoints();
|
||||
std::vector<AccessPoint> getAccessPoints() const;
|
||||
|
||||
// WiFi configuration methods
|
||||
void setWiFiConfig(const String& ssid, const String& password,
|
||||
uint32_t connect_timeout_ms = 10000,
|
||||
uint32_t retry_delay_ms = 500);
|
||||
|
||||
// Network status methods
|
||||
bool isConnected() const { return WiFi.isConnected(); }
|
||||
String getSSID() const { return WiFi.SSID(); }
|
||||
IPAddress getLocalIP() const { return WiFi.localIP(); }
|
||||
String getMacAddress() const { return WiFi.macAddress(); }
|
||||
String getHostname() const { return WiFi.hostname(); }
|
||||
int32_t getRSSI() const { return WiFi.RSSI(); }
|
||||
WiFiMode_t getMode() const { return WiFi.getMode(); }
|
||||
|
||||
// AP mode specific methods
|
||||
IPAddress getAPIP() const { return WiFi.softAPIP(); }
|
||||
String getAPMacAddress() const { return WiFi.softAPmacAddress(); }
|
||||
uint8_t getConnectedStations() const { return WiFi.softAPgetStationNum(); }
|
||||
|
||||
private:
|
||||
NodeContext& ctx;
|
||||
std::vector<AccessPoint> accessPoints;
|
||||
bool isScanning = false;
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <string>
|
||||
#include <initializer_list>
|
||||
#include "Config.h"
|
||||
#include "ApiTypes.h"
|
||||
|
||||
class NodeContext {
|
||||
public:
|
||||
@@ -19,6 +20,7 @@ public:
|
||||
NodeInfo self;
|
||||
std::map<String, NodeInfo>* memberList;
|
||||
Config config;
|
||||
std::vector<EndpointCapability> capabilities;
|
||||
|
||||
using EventCallback = std::function<void(void*)>;
|
||||
std::map<std::string, std::vector<EventCallback>> eventRegistry;
|
||||
|
||||
16
include/services/ClusterService.h
Normal file
16
include/services/ClusterService.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include "services/Service.h"
|
||||
#include "NodeContext.h"
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
class ClusterService : public Service {
|
||||
public:
|
||||
ClusterService(NodeContext& ctx);
|
||||
void registerEndpoints(ApiServer& api) override;
|
||||
const char* getName() const override { return "Cluster"; }
|
||||
|
||||
private:
|
||||
NodeContext& ctx;
|
||||
|
||||
void handleMembersRequest(AsyncWebServerRequest* request);
|
||||
};
|
||||
22
include/services/NetworkService.h
Normal file
22
include/services/NetworkService.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "services/Service.h"
|
||||
#include "NetworkManager.h"
|
||||
#include "NodeContext.h"
|
||||
|
||||
class NetworkService : public Service {
|
||||
public:
|
||||
NetworkService(NetworkManager& networkManager);
|
||||
void registerEndpoints(ApiServer& api) override;
|
||||
const char* getName() const override { return "Network"; }
|
||||
|
||||
private:
|
||||
NetworkManager& networkManager;
|
||||
|
||||
// WiFi scanning endpoints
|
||||
void handleWifiScanRequest(AsyncWebServerRequest* request);
|
||||
void handleGetWifiNetworks(AsyncWebServerRequest* request);
|
||||
|
||||
// Network status endpoints
|
||||
void handleNetworkStatus(AsyncWebServerRequest* request);
|
||||
void handleSetWifiConfig(AsyncWebServerRequest* request);
|
||||
};
|
||||
21
include/services/NodeService.h
Normal file
21
include/services/NodeService.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "services/Service.h"
|
||||
#include "NodeContext.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include <Updater.h>
|
||||
|
||||
class NodeService : public Service {
|
||||
public:
|
||||
NodeService(NodeContext& ctx);
|
||||
void registerEndpoints(ApiServer& api) override;
|
||||
const char* getName() const override { return "Node"; }
|
||||
|
||||
private:
|
||||
NodeContext& ctx;
|
||||
|
||||
void handleStatusRequest(AsyncWebServerRequest* request);
|
||||
void handleUpdateRequest(AsyncWebServerRequest* request);
|
||||
void handleUpdateUpload(AsyncWebServerRequest* request, const String& filename, size_t index, uint8_t* data, size_t len, bool final);
|
||||
void handleRestartRequest(AsyncWebServerRequest* request);
|
||||
void handleCapabilitiesRequest(AsyncWebServerRequest* request);
|
||||
};
|
||||
9
include/services/Service.h
Normal file
9
include/services/Service.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "ApiServer.h"
|
||||
|
||||
class Service {
|
||||
public:
|
||||
virtual ~Service() = default;
|
||||
virtual void registerEndpoints(ApiServer& api) = 0;
|
||||
virtual const char* getName() const = 0;
|
||||
};
|
||||
17
include/services/TaskService.h
Normal file
17
include/services/TaskService.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "services/Service.h"
|
||||
#include "TaskManager.h"
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
class TaskService : public Service {
|
||||
public:
|
||||
TaskService(TaskManager& taskManager);
|
||||
void registerEndpoints(ApiServer& api) override;
|
||||
const char* getName() const override { return "Task"; }
|
||||
|
||||
private:
|
||||
TaskManager& taskManager;
|
||||
|
||||
void handleStatusRequest(AsyncWebServerRequest* request);
|
||||
void handleControlRequest(AsyncWebServerRequest* request);
|
||||
};
|
||||
Reference in New Issue
Block a user