⚡ Removes PsychicHttp dependency
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include <template/stateful_service.h>
|
#include <template/stateful_service.h>
|
||||||
#include <template/stateful_endpoint.h>
|
#include <template/stateful_endpoint.h>
|
||||||
#include <template/stateful_persistence.h>
|
#include <template/stateful_persistence.h>
|
||||||
@@ -16,14 +18,13 @@ class APService : public StatefulService<APSettings> {
|
|||||||
void loop();
|
void loop();
|
||||||
void recoveryMode();
|
void recoveryMode();
|
||||||
|
|
||||||
esp_err_t getStatus(PsychicRequest *request);
|
esp_err_t getStatus(httpd_req_t *request);
|
||||||
void status(JsonObject &root);
|
void status(JsonObject &root);
|
||||||
APNetworkStatus getAPNetworkStatus();
|
APNetworkStatus getAPNetworkStatus();
|
||||||
|
|
||||||
StatefulHttpEndpoint<APSettings> endpoint;
|
StatefulHttpEndpoint<APSettings> endpoint;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PsychicHttpServer *_server;
|
|
||||||
FSPersistence<APSettings> _persistence;
|
FSPersistence<APSettings> _persistence;
|
||||||
|
|
||||||
DNSServer *_dnsServer;
|
DNSServer *_dnsServer;
|
||||||
@@ -37,4 +38,4 @@ class APService : public StatefulService<APSettings> {
|
|||||||
void startAP();
|
void startAP();
|
||||||
void stopAP();
|
void stopAP();
|
||||||
void handleDNS();
|
void handleDNS();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <PsychicHttp.h>
|
|
||||||
#include <template/stateful_service.h>
|
|
||||||
#include <list>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <communication/comm_base.hpp>
|
|
||||||
|
|
||||||
class Websocket : public CommAdapterBase {
|
|
||||||
public:
|
|
||||||
Websocket(PsychicHttpServer &server, const char *route = "/api/ws");
|
|
||||||
|
|
||||||
void begin() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
PsychicWebSocketHandler socket_;
|
|
||||||
PsychicHttpServer &server_;
|
|
||||||
const char *route_;
|
|
||||||
|
|
||||||
void onWSOpen(PsychicWebSocketClient *client);
|
|
||||||
void onWSClose(PsychicWebSocketClient *client);
|
|
||||||
esp_err_t onFrame(PsychicWebSocketRequest *request, httpd_ws_frame *frame);
|
|
||||||
|
|
||||||
void send(const uint8_t *data, size_t len, int cid = -1) override;
|
|
||||||
};
|
|
||||||
@@ -2,52 +2,43 @@
|
|||||||
|
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <PsychicHttp.h>
|
#include <esp_http_server.h>
|
||||||
#include "platform_shared/message.pb.h"
|
#include "platform_shared/message.pb.h"
|
||||||
|
|
||||||
#define FT_ENABLED(feature) feature
|
#define FT_ENABLED(feature) feature
|
||||||
|
|
||||||
// ESP32 camera off by default
|
|
||||||
#ifndef USE_CAMERA
|
#ifndef USE_CAMERA
|
||||||
#define USE_CAMERA 0
|
#define USE_CAMERA 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ESP32 IMU on by default
|
|
||||||
#ifndef USE_MPU6050
|
#ifndef USE_MPU6050
|
||||||
#define USE_MPU6050 0
|
#define USE_MPU6050 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ESP32 IMU on by default
|
|
||||||
#ifndef USE_BNO055
|
#ifndef USE_BNO055
|
||||||
#define USE_BNO055 1
|
#define USE_BNO055 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ESP32 magnetometer on by default
|
|
||||||
#ifndef USE_HMC5883
|
#ifndef USE_HMC5883
|
||||||
#define USE_HMC5883 0
|
#define USE_HMC5883 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ESP32 barometer off by default
|
|
||||||
#ifndef USE_BMP180
|
#ifndef USE_BMP180
|
||||||
#define USE_BMP180 0
|
#define USE_BMP180 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ESP32 SONAR off by default
|
|
||||||
#ifndef USE_USS
|
#ifndef USE_USS
|
||||||
#define USE_USS 0
|
#define USE_USS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// PCA9685 Servo controller on by default
|
|
||||||
#ifndef USE_PCA9685
|
#ifndef USE_PCA9685
|
||||||
#define USE_PCA9685 1
|
#define USE_PCA9685 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// WS2812 LED strip off by default
|
|
||||||
#ifndef USE_WS2812
|
#ifndef USE_WS2812
|
||||||
#define USE_WS2812 0
|
#define USE_WS2812 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ESP32 MDNS on by default
|
|
||||||
#ifndef USE_MDNS
|
#ifndef USE_MDNS
|
||||||
#define USE_MDNS 1
|
#define USE_MDNS 1
|
||||||
#endif
|
#endif
|
||||||
@@ -78,6 +69,6 @@ void features(JsonObject& root);
|
|||||||
|
|
||||||
void features_request(const socket_message_FeaturesDataRequest& fd_req, socket_message_FeaturesDataResponse& fd_res);
|
void features_request(const socket_message_FeaturesDataRequest& fd_req, socket_message_FeaturesDataResponse& fd_res);
|
||||||
|
|
||||||
esp_err_t getFeatures(PsychicRequest* request);
|
esp_err_t getFeatures(httpd_req_t* request);
|
||||||
|
|
||||||
} // namespace feature_service
|
} // namespace feature_service
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <PsychicHttp.h>
|
#include <esp_http_server.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -16,18 +16,15 @@
|
|||||||
#define MDNS_SETTINGS_FILE "/config/mdnsSettings.json"
|
#define MDNS_SETTINGS_FILE "/config/mdnsSettings.json"
|
||||||
|
|
||||||
namespace FileSystem {
|
namespace FileSystem {
|
||||||
extern PsychicUploadHandler *uploadHandler;
|
|
||||||
|
|
||||||
std::string listFiles(const std::string &directory, bool isRoot = true);
|
std::string listFiles(const std::string &directory, bool isRoot = true);
|
||||||
bool deleteFile(const char *filename);
|
bool deleteFile(const char *filename);
|
||||||
bool editFile(const char *filename, const char *content);
|
bool editFile(const char *filename, const char *content);
|
||||||
esp_err_t uploadFile(PsychicRequest *request, const std::string &filename, uint64_t index, uint8_t *data, size_t len,
|
|
||||||
bool last);
|
|
||||||
|
|
||||||
esp_err_t getFiles(PsychicRequest *request);
|
esp_err_t getFiles(httpd_req_t *request);
|
||||||
esp_err_t getConfigFile(PsychicRequest *request);
|
esp_err_t getConfigFile(httpd_req_t *request);
|
||||||
esp_err_t handleDelete(PsychicRequest *request, JsonVariant &json);
|
esp_err_t handleDelete(httpd_req_t *request, JsonVariant &json);
|
||||||
esp_err_t handleEdit(PsychicRequest *request, JsonVariant &json);
|
esp_err_t handleEdit(httpd_req_t *request, JsonVariant &json);
|
||||||
|
esp_err_t mkdir(httpd_req_t *request, JsonVariant &json);
|
||||||
|
|
||||||
esp_err_t mkdir(PsychicRequest *request, JsonVariant &json);
|
} // namespace FileSystem
|
||||||
} // namespace FileSystem
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <PsychicHttp.h>
|
#include <esp_http_server.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
#include <template/stateful_service.h>
|
#include <template/stateful_service.h>
|
||||||
#include <template/stateful_endpoint.h>
|
#include <template/stateful_endpoint.h>
|
||||||
@@ -25,10 +26,10 @@ class MDNSService : public StatefulService<MDNSSettings> {
|
|||||||
|
|
||||||
void begin();
|
void begin();
|
||||||
|
|
||||||
esp_err_t getStatus(PsychicRequest *request);
|
esp_err_t getStatus(httpd_req_t *request);
|
||||||
void getStatus(JsonVariant &root);
|
void getStatus(JsonVariant &root);
|
||||||
|
|
||||||
static esp_err_t queryServices(PsychicRequest *request, JsonVariant &json);
|
static esp_err_t queryServices(httpd_req_t *request, JsonVariant &json);
|
||||||
|
|
||||||
StatefulHttpEndpoint<MDNSSettings> endpoint;
|
StatefulHttpEndpoint<MDNSSettings> endpoint;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <PsychicHttp.h>
|
#include <esp_http_server.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <async_worker.h>
|
|
||||||
|
|
||||||
#include <features.h>
|
#include <features.h>
|
||||||
#include <template/stateful_persistence.h>
|
#include <template/stateful_persistence.h>
|
||||||
@@ -31,8 +30,8 @@ class CameraService : public StatefulService<CameraSettings> {
|
|||||||
|
|
||||||
esp_err_t begin();
|
esp_err_t begin();
|
||||||
|
|
||||||
esp_err_t cameraStill(PsychicRequest *request);
|
esp_err_t cameraStill(httpd_req_t *request);
|
||||||
esp_err_t cameraStream(PsychicRequest *request);
|
esp_err_t cameraStream(httpd_req_t *request);
|
||||||
|
|
||||||
StatefulHttpEndpoint<CameraSettings> endpoint;
|
StatefulHttpEndpoint<CameraSettings> endpoint;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
#define ServoController_h
|
#define ServoController_h
|
||||||
|
|
||||||
#include <Adafruit_PWMServoDriver.h>
|
#include <Adafruit_PWMServoDriver.h>
|
||||||
#include <communication/websocket_adapter.h>
|
|
||||||
#include <template/stateful_persistence.h>
|
#include <template/stateful_persistence.h>
|
||||||
#include <template/stateful_service.h>
|
#include <template/stateful_service.h>
|
||||||
#include <template/stateful_endpoint.h>
|
#include <template/stateful_endpoint.h>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
#include <PsychicHttp.h>
|
#include <esp_http_server.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <filesystem.h>
|
#include <filesystem.h>
|
||||||
#include <global.h>
|
#include <global.h>
|
||||||
@@ -13,9 +13,9 @@
|
|||||||
#include "platform_shared/message.pb.h"
|
#include "platform_shared/message.pb.h"
|
||||||
|
|
||||||
namespace system_service {
|
namespace system_service {
|
||||||
esp_err_t handleReset(PsychicRequest *request);
|
esp_err_t handleReset(httpd_req_t *request);
|
||||||
esp_err_t handleRestart(PsychicRequest *request);
|
esp_err_t handleRestart(httpd_req_t *request);
|
||||||
esp_err_t handleSleep(PsychicRequest *request);
|
esp_err_t handleSleep(httpd_req_t *request);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
void restart();
|
void restart();
|
||||||
@@ -25,4 +25,4 @@ void getAnalytics(socket_message_AnalyticsData &analytics);
|
|||||||
void getStaticSystemInformation(socket_message_StaticSystemInformation &info);
|
void getStaticSystemInformation(socket_message_StaticSystemInformation &info);
|
||||||
|
|
||||||
const char *resetReason(esp_reset_reason_t reason);
|
const char *resetReason(esp_reset_reason_t reason);
|
||||||
} // namespace system_service
|
} // namespace system_service
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <PsychicHttp.h>
|
#include <esp_http_server.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
#include <template/stateful_service.h>
|
#include <template/stateful_service.h>
|
||||||
|
#include <communication/native_server.h>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
@@ -20,29 +22,26 @@ class StatefulHttpEndpoint {
|
|||||||
StatefulService<T> *statefulService)
|
StatefulService<T> *statefulService)
|
||||||
: _stateReader(stateReader), _stateUpdater(stateUpdater), _statefulService(statefulService) {}
|
: _stateReader(stateReader), _stateUpdater(stateUpdater), _statefulService(statefulService) {}
|
||||||
|
|
||||||
esp_err_t handleStateUpdate(PsychicRequest *request, JsonVariant &json) {
|
esp_err_t handleStateUpdate(httpd_req_t *request, JsonVariant &json) {
|
||||||
JsonVariant jsonObject = json.as<JsonVariant>();
|
JsonVariant jsonObject = json.as<JsonVariant>();
|
||||||
StateUpdateResult outcome = _statefulService->updateWithoutPropagation(jsonObject, _stateUpdater);
|
StateUpdateResult outcome = _statefulService->updateWithoutPropagation(jsonObject, _stateUpdater);
|
||||||
|
|
||||||
if (outcome == StateUpdateResult::ERROR)
|
if (outcome == StateUpdateResult::ERROR) {
|
||||||
return request->reply(400);
|
return NativeServer::sendError(request, 400, "Invalid state");
|
||||||
else if ((outcome == StateUpdateResult::CHANGED)) {
|
} else if ((outcome == StateUpdateResult::CHANGED)) {
|
||||||
// persist the changes to the FS
|
|
||||||
_statefulService->callUpdateHandlers(HTTP_ENDPOINT_ORIGIN_ID);
|
_statefulService->callUpdateHandlers(HTTP_ENDPOINT_ORIGIN_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
PsychicJsonResponse response = PsychicJsonResponse(request, false);
|
JsonDocument doc;
|
||||||
jsonObject = response.getRoot();
|
JsonVariant root = doc.to<JsonVariant>();
|
||||||
|
_statefulService->read(root, _stateReader);
|
||||||
_statefulService->read(jsonObject, _stateReader);
|
return NativeServer::sendJson(request, 200, doc);
|
||||||
|
|
||||||
return response.send();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t getState(PsychicRequest *request) {
|
esp_err_t getState(httpd_req_t *request) {
|
||||||
PsychicJsonResponse response = PsychicJsonResponse(request, false);
|
JsonDocument doc;
|
||||||
JsonVariant jsonObject = response.getRoot();
|
JsonVariant root = doc.to<JsonVariant>();
|
||||||
_statefulService->read(jsonObject, _stateReader);
|
_statefulService->read(root, _stateReader);
|
||||||
return response.send();
|
return NativeServer::sendJson(request, 200, doc);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <PsychicHttp.h>
|
#include <esp_http_server.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -43,9 +43,9 @@ class WiFiService : public StatefulService<WiFiSettings> {
|
|||||||
|
|
||||||
const char *getHostname() { return state().hostname.c_str(); }
|
const char *getHostname() { return state().hostname.c_str(); }
|
||||||
|
|
||||||
static esp_err_t handleScan(PsychicRequest *request);
|
static esp_err_t handleScan(httpd_req_t *request);
|
||||||
static esp_err_t getNetworks(PsychicRequest *request);
|
static esp_err_t getNetworks(httpd_req_t *request);
|
||||||
static esp_err_t getNetworkStatus(PsychicRequest *request);
|
static esp_err_t getNetworkStatus(httpd_req_t *request);
|
||||||
|
|
||||||
StatefulHttpEndpoint<WiFiSettings> endpoint;
|
StatefulHttpEndpoint<WiFiSettings> endpoint;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <PsychicHttp.h>
|
#include <communication/native_server.h>
|
||||||
#include "WWWData.h"
|
#include "WWWData.h"
|
||||||
|
|
||||||
void mountStaticAssets(PsychicHttpServer& s);
|
void mountStaticAssets(NativeServer& s);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <ap_service.h>
|
#include <ap_service.h>
|
||||||
|
#include <communication/native_server.h>
|
||||||
|
|
||||||
static const char *TAG = "APService";
|
static const char *TAG = "APService";
|
||||||
|
|
||||||
@@ -12,11 +13,11 @@ APService::~APService() {}
|
|||||||
|
|
||||||
void APService::begin() { _persistence.readFromFS(); }
|
void APService::begin() { _persistence.readFromFS(); }
|
||||||
|
|
||||||
esp_err_t APService::getStatus(PsychicRequest *request) {
|
esp_err_t APService::getStatus(httpd_req_t *request) {
|
||||||
PsychicJsonResponse response = PsychicJsonResponse(request, false);
|
JsonDocument doc;
|
||||||
JsonObject root = response.getRoot();
|
JsonObject root = doc.to<JsonObject>();
|
||||||
status(root);
|
status(root);
|
||||||
return response.send();
|
return NativeServer::sendJson(request, 200, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void APService::status(JsonObject &root) {
|
void APService::status(JsonObject &root) {
|
||||||
@@ -73,7 +74,7 @@ void APService::startAP() {
|
|||||||
WiFi.softAP(state().ssid.c_str(), state().password.c_str(), state().channel, state().ssidHidden,
|
WiFi.softAP(state().ssid.c_str(), state().password.c_str(), state().channel, state().ssidHidden,
|
||||||
state().maxClients);
|
state().maxClients);
|
||||||
#if CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32C3
|
||||||
WiFi.setTxPower(WIFI_POWER_8_5dBm); // https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi
|
WiFi.setTxPower(WIFI_POWER_8_5dBm);
|
||||||
#endif
|
#endif
|
||||||
if (!_dnsServer) {
|
if (!_dnsServer) {
|
||||||
IPAddress apIp = WiFi.softAPIP();
|
IPAddress apIp = WiFi.softAPIP();
|
||||||
@@ -98,4 +99,4 @@ void APService::handleDNS() {
|
|||||||
if (_dnsServer) {
|
if (_dnsServer) {
|
||||||
_dnsServer->processNextRequest();
|
_dnsServer->processNextRequest();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
#include <communication/websocket_adapter.h>
|
|
||||||
|
|
||||||
static const char* TAG = "Websocket";
|
|
||||||
|
|
||||||
Websocket::Websocket(PsychicHttpServer& server, const char* route) : server_(server), route_(route) {
|
|
||||||
socket_.onOpen(std::bind(&Websocket::onWSOpen, this, std::placeholders::_1));
|
|
||||||
socket_.onClose(std::bind(&Websocket::onWSClose, this, std::placeholders::_1));
|
|
||||||
socket_.onFrame(std::bind(&Websocket::onFrame, this, std::placeholders::_1, std::placeholders::_2));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Websocket::begin() { server_.on(route_, &socket_); }
|
|
||||||
|
|
||||||
void Websocket::onWSOpen(PsychicWebSocketClient* client) {
|
|
||||||
ESP_LOGI(TAG, "Client connected: %s [%u]", client->remoteIP().toString().c_str(), client->socket());
|
|
||||||
sendPong(client->socket());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Websocket::onWSClose(PsychicWebSocketClient* client) {
|
|
||||||
ESP_LOGI(TAG, "Client disconnected: %s [%u]", client->remoteIP().toString().c_str(), client->socket());
|
|
||||||
removeClient(client->socket());
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t Websocket::onFrame(PsychicWebSocketRequest* request, httpd_ws_frame* frame) {
|
|
||||||
if (frame->type != HTTPD_WS_TYPE_BINARY) {
|
|
||||||
ESP_LOGW(TAG, "Expected binary frame, got type %d", frame->type);
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleIncoming(frame->payload, frame->len, request->client()->socket());
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Websocket::send(const uint8_t* data, size_t len, int cid) {
|
|
||||||
if (cid >= 0) {
|
|
||||||
auto* client = socket_.getClient(cid);
|
|
||||||
if (client) {
|
|
||||||
esp_err_t err = client->sendMessage(HTTPD_WS_TYPE_BINARY, data, len);
|
|
||||||
if (err != ESP_OK) {
|
|
||||||
ESP_LOGE(TAG, "Failed to send message to client %d: %s (len=%u)", cid, esp_err_to_name(err), len);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ESP_LOGW(TAG, "Client %d not found for send", cid);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
socket_.sendAll(HTTPD_WS_TYPE_BINARY, data, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+7
-13
@@ -1,28 +1,24 @@
|
|||||||
#include <features.h>
|
#include <features.h>
|
||||||
|
#include <communication/native_server.h>
|
||||||
|
|
||||||
namespace feature_service {
|
namespace feature_service {
|
||||||
|
|
||||||
// New function to print all feature flags to log
|
|
||||||
void printFeatureConfiguration() {
|
void printFeatureConfiguration() {
|
||||||
ESP_LOGI("Features", "====================== FEATURE FLAGS ======================");
|
ESP_LOGI("Features", "====================== FEATURE FLAGS ======================");
|
||||||
ESP_LOGI("Features", "Firmware version: %s, name: %s, target: %s", APP_VERSION, APP_NAME, BUILD_TARGET);
|
ESP_LOGI("Features", "Firmware version: %s, name: %s, target: %s", APP_VERSION, APP_NAME, BUILD_TARGET);
|
||||||
|
|
||||||
// Core features
|
|
||||||
ESP_LOGI("Features", "USE_CAMERA: %s", USE_CAMERA ? "enabled" : "disabled");
|
ESP_LOGI("Features", "USE_CAMERA: %s", USE_CAMERA ? "enabled" : "disabled");
|
||||||
ESP_LOGI("Features", "USE_MOTION: %s", USE_MOTION ? "enabled" : "disabled");
|
ESP_LOGI("Features", "USE_MOTION: %s", USE_MOTION ? "enabled" : "disabled");
|
||||||
|
|
||||||
// Sensors
|
|
||||||
ESP_LOGI("Features", "USE_BNO055: %s", USE_BNO055 ? "enabled" : "disabled");
|
ESP_LOGI("Features", "USE_BNO055: %s", USE_BNO055 ? "enabled" : "disabled");
|
||||||
ESP_LOGI("Features", "USE_MPU6050: %s", USE_MPU6050 ? "enabled" : "disabled");
|
ESP_LOGI("Features", "USE_MPU6050: %s", USE_MPU6050 ? "enabled" : "disabled");
|
||||||
ESP_LOGI("Features", "USE_HMC5883: %s", USE_HMC5883 ? "enabled" : "disabled");
|
ESP_LOGI("Features", "USE_HMC5883: %s", USE_HMC5883 ? "enabled" : "disabled");
|
||||||
ESP_LOGI("Features", "USE_BMP180: %s", USE_BMP180 ? "enabled" : "disabled");
|
ESP_LOGI("Features", "USE_BMP180: %s", USE_BMP180 ? "enabled" : "disabled");
|
||||||
ESP_LOGI("Features", "USE_USS: %s", USE_USS ? "enabled" : "disabled");
|
ESP_LOGI("Features", "USE_USS: %s", USE_USS ? "enabled" : "disabled");
|
||||||
|
|
||||||
// Peripherals
|
|
||||||
ESP_LOGI("Features", "USE_PCA9685: %s", USE_PCA9685 ? "enabled" : "disabled");
|
ESP_LOGI("Features", "USE_PCA9685: %s", USE_PCA9685 ? "enabled" : "disabled");
|
||||||
ESP_LOGI("Features", "USE_WS2812: %s", USE_WS2812 ? "enabled" : "disabled");
|
ESP_LOGI("Features", "USE_WS2812: %s", USE_WS2812 ? "enabled" : "disabled");
|
||||||
|
|
||||||
// Web services
|
|
||||||
ESP_LOGI("Features", "USE_MDNS: %s", USE_MDNS ? "enabled" : "disabled");
|
ESP_LOGI("Features", "USE_MDNS: %s", USE_MDNS ? "enabled" : "disabled");
|
||||||
ESP_LOGI("Features", "EMBED_WEBAPP: %s", EMBED_WEBAPP ? "enabled" : "disabled");
|
ESP_LOGI("Features", "EMBED_WEBAPP: %s", EMBED_WEBAPP ? "enabled" : "disabled");
|
||||||
ESP_LOGI("Features", "KINEMATICS_VARIANT: %s", KINEMATICS_VARIANT_STR);
|
ESP_LOGI("Features", "KINEMATICS_VARIANT: %s", KINEMATICS_VARIANT_STR);
|
||||||
@@ -45,9 +41,7 @@ void features_request(const socket_message_FeaturesDataRequest& fd_req, socket_m
|
|||||||
fd_res.variant = const_cast<char*>(KINEMATICS_VARIANT_STR);
|
fd_res.variant = const_cast<char*>(KINEMATICS_VARIANT_STR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void features(JsonObject& root) {
|
||||||
|
|
||||||
void features(JsonObject &root) {
|
|
||||||
root["camera"] = USE_CAMERA ? true : false;
|
root["camera"] = USE_CAMERA ? true : false;
|
||||||
root["imu"] = (USE_MPU6050 || USE_BNO055) ? true : false;
|
root["imu"] = (USE_MPU6050 || USE_BNO055) ? true : false;
|
||||||
root["mag"] = (USE_HMC5883 || USE_BNO055) ? true : false;
|
root["mag"] = (USE_HMC5883 || USE_BNO055) ? true : false;
|
||||||
@@ -63,11 +57,11 @@ void features(JsonObject &root) {
|
|||||||
root["variant"] = KINEMATICS_VARIANT_STR;
|
root["variant"] = KINEMATICS_VARIANT_STR;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t getFeatures(PsychicRequest *request) {
|
esp_err_t getFeatures(httpd_req_t* request) {
|
||||||
PsychicJsonResponse response = PsychicJsonResponse(request, false);
|
JsonDocument doc;
|
||||||
JsonObject root = response.getRoot();
|
JsonObject root = doc.to<JsonObject>();
|
||||||
features(root);
|
features(root);
|
||||||
return response.send();
|
return NativeServer::sendJson(request, 200, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace feature_service
|
} // namespace feature_service
|
||||||
|
|||||||
+26
-57
@@ -1,62 +1,53 @@
|
|||||||
#include <filesystem.h>
|
#include <filesystem.h>
|
||||||
|
#include <communication/native_server.h>
|
||||||
|
|
||||||
static const char *TAG = "FileService";
|
static const char *TAG = "FileService";
|
||||||
|
|
||||||
namespace FileSystem {
|
namespace FileSystem {
|
||||||
|
|
||||||
PsychicUploadHandler *uploadHandler;
|
esp_err_t getFiles(httpd_req_t *request) {
|
||||||
|
std::string files = listFiles("/");
|
||||||
|
httpd_resp_set_type(request, "application/json");
|
||||||
|
return httpd_resp_send(request, files.c_str(), files.length());
|
||||||
|
}
|
||||||
|
|
||||||
class Initializer {
|
esp_err_t getConfigFile(httpd_req_t *request) {
|
||||||
public:
|
const char *uri = request->uri;
|
||||||
Initializer() {
|
std::string path = "/config" + std::string(uri).substr(11);
|
||||||
uploadHandler = new PsychicUploadHandler();
|
if (!ESP_FS.exists(path.c_str())) {
|
||||||
uploadHandler->onUpload([](PsychicRequest *request, const String &filename, uint64_t index, uint8_t *data,
|
return NativeServer::sendError(request, 404, "File not found");
|
||||||
size_t len, bool last) -> esp_err_t {
|
|
||||||
return uploadFile(request, std::string(filename.c_str()), index, data, len, last);
|
|
||||||
});
|
|
||||||
uploadHandler->onRequest([](PsychicRequest *request) { return request->reply(200); });
|
|
||||||
}
|
}
|
||||||
};
|
File file = ESP_FS.open(path.c_str(), "r");
|
||||||
|
|
||||||
static Initializer initializer;
|
|
||||||
|
|
||||||
esp_err_t getFiles(PsychicRequest *request) { return request->reply(200, "application/json", listFiles("/").c_str()); }
|
|
||||||
|
|
||||||
esp_err_t getConfigFile(PsychicRequest *request) {
|
|
||||||
String path = "/config" + request->uri().substring(11);
|
|
||||||
if (!ESP_FS.exists(path)) {
|
|
||||||
return request->reply(404, "text/plain", "File not found");
|
|
||||||
}
|
|
||||||
File file = ESP_FS.open(path, "r");
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return request->reply(500, "text/plain", "Failed to open file");
|
return NativeServer::sendError(request, 500, "Failed to open file");
|
||||||
}
|
}
|
||||||
String content = file.readString();
|
String content = file.readString();
|
||||||
file.close();
|
file.close();
|
||||||
return request->reply(200, "application/json", content.c_str());
|
httpd_resp_set_type(request, "application/json");
|
||||||
|
return httpd_resp_send(request, content.c_str(), content.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t handleDelete(PsychicRequest *request, JsonVariant &json) {
|
esp_err_t handleDelete(httpd_req_t *request, JsonVariant &json) {
|
||||||
if (json.is<JsonObject>()) {
|
if (json.is<JsonObject>()) {
|
||||||
const char *filename = json["file"].as<const char *>();
|
const char *filename = json["file"].as<const char *>();
|
||||||
ESP_LOGI(TAG, "Deleting file: %s", filename);
|
ESP_LOGI(TAG, "Deleting file: %s", filename);
|
||||||
return deleteFile(filename) ? request->reply(200) : request->reply(500);
|
return deleteFile(filename) ? NativeServer::sendOk(request)
|
||||||
|
: NativeServer::sendError(request, 500, "Delete failed");
|
||||||
}
|
}
|
||||||
return request->reply(400);
|
return NativeServer::sendError(request, 400, "Invalid request");
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t handleEdit(PsychicRequest *request, JsonVariant &json) {
|
esp_err_t handleEdit(httpd_req_t *request, JsonVariant &json) {
|
||||||
if (json.is<JsonObject>()) {
|
if (json.is<JsonObject>()) {
|
||||||
const char *filename = json["file"].as<const char *>();
|
const char *filename = json["file"].as<const char *>();
|
||||||
const char *content = json["content"].as<const char *>();
|
const char *content = json["content"].as<const char *>();
|
||||||
ESP_LOGI(TAG, "Editing file: %s", filename);
|
ESP_LOGI(TAG, "Editing file: %s", filename);
|
||||||
return editFile(filename, content) ? request->reply(200) : request->reply(500);
|
return editFile(filename, content) ? NativeServer::sendOk(request)
|
||||||
|
: NativeServer::sendError(request, 500, "Edit failed");
|
||||||
}
|
}
|
||||||
return request->reply(400);
|
return NativeServer::sendError(request, 400, "Invalid request");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helpers */
|
|
||||||
|
|
||||||
bool deleteFile(const char *filename) { return ESP_FS.remove(filename); }
|
bool deleteFile(const char *filename) { return ESP_FS.remove(filename); }
|
||||||
|
|
||||||
std::string listFiles(const std::string &directory, bool isRoot) {
|
std::string listFiles(const std::string &directory, bool isRoot) {
|
||||||
@@ -89,28 +80,6 @@ std::string listFiles(const std::string &directory, bool isRoot) {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t uploadFile(PsychicRequest *request, const std::string &filename, uint64_t index, uint8_t *data, size_t len,
|
|
||||||
bool last) {
|
|
||||||
File file;
|
|
||||||
std::string path = "/www/" + filename;
|
|
||||||
ESP_LOGI(TAG, "Writing %d/%d bytes to: %s\n", (int)index + (int)len, request->contentLength(), path.c_str());
|
|
||||||
|
|
||||||
if (last) ESP_LOGI(TAG, "%s is finished. Total bytes: %d\n", path.c_str(), (int)index + (int)len);
|
|
||||||
|
|
||||||
file = ESP_FS.open(path.c_str(), !index ? FILE_WRITE : FILE_APPEND);
|
|
||||||
if (!file) {
|
|
||||||
ESP_LOGE(TAG, "Failed to open file");
|
|
||||||
return ESP_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!file.write(data, len)) {
|
|
||||||
ESP_LOGE(TAG, "Write failed");
|
|
||||||
return ESP_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool editFile(const char *filename, const char *content) {
|
bool editFile(const char *filename, const char *content) {
|
||||||
File file = ESP_FS.open(filename, FILE_WRITE);
|
File file = ESP_FS.open(filename, FILE_WRITE);
|
||||||
if (!file) return false;
|
if (!file) return false;
|
||||||
@@ -120,10 +89,10 @@ bool editFile(const char *filename, const char *content) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t mkdir(PsychicRequest *request, JsonVariant &json) {
|
esp_err_t mkdir(httpd_req_t *request, JsonVariant &json) {
|
||||||
const char *path = json["path"].as<const char *>();
|
const char *path = json["path"].as<const char *>();
|
||||||
ESP_LOGI(TAG, "Creating directory: %s", path);
|
ESP_LOGI(TAG, "Creating directory: %s", path);
|
||||||
return ESP_FS.mkdir(path) ? request->reply(200) : request->reply(500);
|
return ESP_FS.mkdir(path) ? NativeServer::sendOk(request) : NativeServer::sendError(request, 500, "mkdir failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace FileSystem
|
} // namespace FileSystem
|
||||||
|
|||||||
+83
-93
@@ -1,5 +1,4 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <PsychicHttp.h>
|
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
@@ -11,7 +10,8 @@
|
|||||||
#include <peripherals/servo_controller.h>
|
#include <peripherals/servo_controller.h>
|
||||||
#include <peripherals/led_service.h>
|
#include <peripherals/led_service.h>
|
||||||
#include <peripherals/camera_service.h>
|
#include <peripherals/camera_service.h>
|
||||||
#include <communication/websocket_adapter.h>
|
#include <communication/native_server.h>
|
||||||
|
#include <communication/native_websocket.h>
|
||||||
#include <features.h>
|
#include <features.h>
|
||||||
#include <motion.h>
|
#include <motion.h>
|
||||||
#include <wifi_service.h>
|
#include <wifi_service.h>
|
||||||
@@ -21,11 +21,8 @@
|
|||||||
|
|
||||||
#include <www_mount.hpp>
|
#include <www_mount.hpp>
|
||||||
|
|
||||||
// Communication
|
NativeWebsocket socket {nativeServer, "/api/ws"};
|
||||||
PsychicHttpServer server;
|
|
||||||
Websocket socket {server, "/api/ws"};
|
|
||||||
|
|
||||||
// Core
|
|
||||||
Peripherals peripherals;
|
Peripherals peripherals;
|
||||||
ServoController servoController;
|
ServoController servoController;
|
||||||
MotionService motionService;
|
MotionService motionService;
|
||||||
@@ -39,99 +36,91 @@ Camera::CameraService cameraService;
|
|||||||
MDNSService mdnsService;
|
MDNSService mdnsService;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Service
|
|
||||||
WiFiService wifiService;
|
WiFiService wifiService;
|
||||||
APService apService;
|
APService apService;
|
||||||
|
|
||||||
void setupServer() {
|
void setupServer() {
|
||||||
server.config.max_uri_handlers = 50 + WWW_ASSETS_COUNT;
|
nativeServer.config(50 + WWW_ASSETS_COUNT, 32768, 1000000);
|
||||||
server.config.stack_size = 32768; // 32KB
|
nativeServer.listen(80);
|
||||||
server.maxUploadSize = 1000000; // 1 MB;
|
|
||||||
server.listen(80);
|
nativeServer.on("/api/system/reset", HTTP_POST,
|
||||||
server.on("/api/system/reset", HTTP_POST,
|
[&](httpd_req_t *request, JsonVariant &json) { return system_service::handleReset(request); });
|
||||||
[&](PsychicRequest *request, JsonVariant &json) { return system_service::handleReset(request); });
|
nativeServer.on("/api/system/restart", HTTP_POST,
|
||||||
server.on("/api/system/restart", HTTP_POST,
|
[&](httpd_req_t *request, JsonVariant &json) { return system_service::handleRestart(request); });
|
||||||
[&](PsychicRequest *request, JsonVariant &json) { return system_service::handleRestart(request); });
|
nativeServer.on("/api/system/sleep", HTTP_POST,
|
||||||
server.on("/api/system/sleep", HTTP_POST,
|
[&](httpd_req_t *request, JsonVariant &json) { return system_service::handleSleep(request); });
|
||||||
[&](PsychicRequest *request, JsonVariant &json) { return system_service::handleSleep(request); });
|
|
||||||
#if USE_CAMERA
|
#if USE_CAMERA
|
||||||
server.on("/api/camera/still", HTTP_GET,
|
nativeServer.on("/api/camera/still", HTTP_GET,
|
||||||
[&](PsychicRequest *request) { return cameraService.cameraStill(request); });
|
[&](httpd_req_t *request) { return cameraService.cameraStill(request); });
|
||||||
server.on("/api/camera/stream", HTTP_GET,
|
nativeServer.on("/api/camera/stream", HTTP_GET,
|
||||||
[&](PsychicRequest *request) { return cameraService.cameraStream(request); });
|
[&](httpd_req_t *request) { return cameraService.cameraStream(request); });
|
||||||
server.on("/api/camera/settings", HTTP_GET,
|
nativeServer.on("/api/camera/settings", HTTP_GET,
|
||||||
[&](PsychicRequest *request) { return cameraService.endpoint.getState(request); });
|
[&](httpd_req_t *request) { return cameraService.endpoint.getState(request); });
|
||||||
server.on("/api/camera/settings", HTTP_POST, [&](PsychicRequest *request, JsonVariant &json) {
|
nativeServer.on("/api/camera/settings", HTTP_POST, [&](httpd_req_t *request, JsonVariant &json) {
|
||||||
return cameraService.endpoint.handleStateUpdate(request, json);
|
return cameraService.endpoint.handleStateUpdate(request, json);
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
server.on("/api/servo/config", HTTP_GET,
|
nativeServer.on("/api/servo/config", HTTP_GET,
|
||||||
[&](PsychicRequest *request) { return servoController.endpoint.getState(request); });
|
[&](httpd_req_t *request) { return servoController.endpoint.getState(request); });
|
||||||
server.on("/api/servo/config", HTTP_POST, [&](PsychicRequest *request, JsonVariant &json) {
|
nativeServer.on("/api/servo/config", HTTP_POST, [&](httpd_req_t *request, JsonVariant &json) {
|
||||||
return servoController.endpoint.handleStateUpdate(request, json);
|
return servoController.endpoint.handleStateUpdate(request, json);
|
||||||
});
|
});
|
||||||
|
|
||||||
// WiFi
|
nativeServer.on("/api/wifi/sta/settings", HTTP_GET,
|
||||||
server.on("/api/wifi/sta/settings", HTTP_GET,
|
[&](httpd_req_t *request) { return wifiService.endpoint.getState(request); });
|
||||||
[&](PsychicRequest *request) { return wifiService.endpoint.getState(request); });
|
nativeServer.on("/api/wifi/sta/settings", HTTP_POST, [&](httpd_req_t *request, JsonVariant &json) {
|
||||||
server.on("/api/wifi/sta/settings", HTTP_POST, [&](PsychicRequest *request, JsonVariant &json) {
|
|
||||||
return wifiService.endpoint.handleStateUpdate(request, json);
|
return wifiService.endpoint.handleStateUpdate(request, json);
|
||||||
});
|
});
|
||||||
server.on("/api/wifi/scan", HTTP_GET, [&](PsychicRequest *request) { return wifiService.handleScan(request); });
|
nativeServer.on("/api/wifi/scan", HTTP_GET, [&](httpd_req_t *request) { return wifiService.handleScan(request); });
|
||||||
server.on("/api/wifi/networks", HTTP_GET,
|
nativeServer.on("/api/wifi/networks", HTTP_GET,
|
||||||
[&](PsychicRequest *request) { return wifiService.getNetworks(request); });
|
[&](httpd_req_t *request) { return wifiService.getNetworks(request); });
|
||||||
server.on("/api/wifi/sta/status", HTTP_GET,
|
nativeServer.on("/api/wifi/sta/status", HTTP_GET,
|
||||||
[&](PsychicRequest *request) { return wifiService.getNetworkStatus(request); });
|
[&](httpd_req_t *request) { return wifiService.getNetworkStatus(request); });
|
||||||
|
|
||||||
// AP
|
nativeServer.on("/api/ap/status", HTTP_GET, [&](httpd_req_t *request) { return apService.getStatus(request); });
|
||||||
server.on("/api/ap/status", HTTP_GET, [&](PsychicRequest *request) { return apService.getStatus(request); });
|
nativeServer.on("/api/ap/settings", HTTP_GET,
|
||||||
server.on("/api/ap/settings", HTTP_GET,
|
[&](httpd_req_t *request) { return apService.endpoint.getState(request); });
|
||||||
[&](PsychicRequest *request) { return apService.endpoint.getState(request); });
|
nativeServer.on("/api/ap/settings", HTTP_POST, [&](httpd_req_t *request, JsonVariant &json) {
|
||||||
server.on("/api/ap/settings", HTTP_POST, [&](PsychicRequest *request, JsonVariant &json) {
|
|
||||||
return apService.endpoint.handleStateUpdate(request, json);
|
return apService.endpoint.handleStateUpdate(request, json);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Peripherals
|
nativeServer.on("/api/peripherals", HTTP_GET,
|
||||||
server.on("/api/peripherals", HTTP_GET,
|
[&](httpd_req_t *request) { return peripherals.endpoint.getState(request); });
|
||||||
[&](PsychicRequest *request) { return peripherals.endpoint.getState(request); });
|
nativeServer.on("/api/peripherals", HTTP_POST, [&](httpd_req_t *request, JsonVariant &json) {
|
||||||
server.on("/api/peripherals", HTTP_POST, [&](PsychicRequest *request, JsonVariant &json) {
|
|
||||||
return peripherals.endpoint.handleStateUpdate(request, json);
|
return peripherals.endpoint.handleStateUpdate(request, json);
|
||||||
});
|
});
|
||||||
|
|
||||||
// MDNS
|
|
||||||
#if FT_ENABLED(USE_MDNS)
|
#if FT_ENABLED(USE_MDNS)
|
||||||
server.on("/api/mdns", HTTP_GET, [&](PsychicRequest *request) { return mdnsService.endpoint.getState(request); });
|
nativeServer.on("/api/mdns", HTTP_GET,
|
||||||
server.on("/api/mdns", HTTP_POST, [&](PsychicRequest *request, JsonVariant &json) {
|
[&](httpd_req_t *request) { return mdnsService.endpoint.getState(request); });
|
||||||
|
nativeServer.on("/api/mdns", HTTP_POST, [&](httpd_req_t *request, JsonVariant &json) {
|
||||||
return mdnsService.endpoint.handleStateUpdate(request, json);
|
return mdnsService.endpoint.handleStateUpdate(request, json);
|
||||||
});
|
});
|
||||||
server.on("/api/mdns/status", HTTP_GET, [&](PsychicRequest *request) { return mdnsService.getStatus(request); });
|
nativeServer.on("/api/mdns/status", HTTP_GET, [&](httpd_req_t *request) { return mdnsService.getStatus(request); });
|
||||||
server.on("/api/mdns/query", HTTP_POST,
|
nativeServer.on("/api/mdns/query", HTTP_POST,
|
||||||
[&](PsychicRequest *request, JsonVariant &json) { return mdnsService.queryServices(request, json); });
|
[&](httpd_req_t *request, JsonVariant &json) { return mdnsService.queryServices(request, json); });
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Filesystem
|
nativeServer.on("/api/config/*", HTTP_GET, [](httpd_req_t *request) { return FileSystem::getConfigFile(request); });
|
||||||
server.on("/api/config/*", HTTP_GET, [](PsychicRequest *request) { return FileSystem::getConfigFile(request); });
|
nativeServer.on("/api/files", HTTP_GET, [&](httpd_req_t *request) { return FileSystem::getFiles(request); });
|
||||||
server.on("/api/files", HTTP_GET, [&](PsychicRequest *request) { return FileSystem::getFiles(request); });
|
nativeServer.on("/api/files/delete", HTTP_POST,
|
||||||
server.on("/api/files", HTTP_POST, FileSystem::uploadHandler);
|
[&](httpd_req_t *request, JsonVariant &json) { return FileSystem::handleDelete(request, json); });
|
||||||
server.on("/api/files/delete", HTTP_POST,
|
nativeServer.on("/api/files/edit", HTTP_POST,
|
||||||
[&](PsychicRequest *request, JsonVariant &json) { return FileSystem::handleDelete(request, json); });
|
[&](httpd_req_t *request, JsonVariant &json) { return FileSystem::handleEdit(request, json); });
|
||||||
server.on("/api/files/edit", HTTP_POST,
|
nativeServer.on("/api/files/mkdir", HTTP_POST,
|
||||||
[&](PsychicRequest *request, JsonVariant &json) { return FileSystem::handleEdit(request, json); });
|
[&](httpd_req_t *request, JsonVariant &json) { return FileSystem::mkdir(request, json); });
|
||||||
server.on("/api/files/mkdir", HTTP_POST,
|
|
||||||
[&](PsychicRequest *request, JsonVariant &json) { return FileSystem::mkdir(request, json); });
|
|
||||||
#if EMBED_WEBAPP
|
#if EMBED_WEBAPP
|
||||||
mountStaticAssets(server);
|
mountStaticAssets(nativeServer);
|
||||||
#endif
|
#endif
|
||||||
server.on("/*", HTTP_OPTIONS, [](PsychicRequest *request) { // CORS handling
|
nativeServer.on("/*", HTTP_OPTIONS, [](httpd_req_t *request) {
|
||||||
PsychicResponse response(request);
|
httpd_resp_set_status(request, "200 OK");
|
||||||
response.setCode(200);
|
return httpd_resp_send(request, nullptr, 0);
|
||||||
return response.send();
|
|
||||||
});
|
});
|
||||||
DefaultHeaders::Instance().addHeader("Server", APP_NAME);
|
nativeServer.addDefaultHeader("Server", APP_NAME);
|
||||||
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
|
nativeServer.addDefaultHeader("Access-Control-Allow-Origin", "*");
|
||||||
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "Accept, Content-Type, Authorization");
|
nativeServer.addDefaultHeader("Access-Control-Allow-Headers", "Accept, Content-Type, Authorization");
|
||||||
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
nativeServer.addDefaultHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
||||||
DefaultHeaders::Instance().addHeader("Access-Control-Max-Age", "86400");
|
nativeServer.addDefaultHeader("Access-Control-Max-Age", "86400");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupEventSocket() {
|
void setupEventSocket() {
|
||||||
@@ -164,76 +153,77 @@ void setupEventSocket() {
|
|||||||
data.active ? servoController.activate() : servoController.deactivate();
|
data.active ? servoController.activate() : servoController.deactivate();
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on<socket_message_FSUploadData>([&](const socket_message_FSUploadData &data, int clientId) {
|
socket.on<socket_message_FSUploadData>(
|
||||||
FileSystemWS::fsHandler.handleUploadData(data);
|
[&](const socket_message_FSUploadData &data, int clientId) { FileSystemWS::fsHandler.handleUploadData(data); });
|
||||||
});
|
|
||||||
|
|
||||||
using CorrelationHandler =
|
using CorrelationHandler =
|
||||||
std::function<void(const socket_message_CorrelationRequest &, socket_message_CorrelationResponse &, int)>;
|
std::function<void(const socket_message_CorrelationRequest &, socket_message_CorrelationResponse &, int)>;
|
||||||
static std::map<pb_size_t, CorrelationHandler> correlationHandlers = {
|
static std::map<pb_size_t, CorrelationHandler> correlationHandlers = {
|
||||||
{socket_message_CorrelationRequest_features_data_request_tag, // Features data
|
{socket_message_CorrelationRequest_features_data_request_tag,
|
||||||
[](const auto &req, auto &res, int clientId) {
|
[](const auto &req, auto &res, int clientId) {
|
||||||
res.which_response = socket_message_CorrelationResponse_features_data_response_tag;
|
res.which_response = socket_message_CorrelationResponse_features_data_response_tag;
|
||||||
feature_service::features_request(req.request.features_data_request, res.response.features_data_response);
|
feature_service::features_request(req.request.features_data_request, res.response.features_data_response);
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{socket_message_CorrelationRequest_i2c_scan_data_request_tag, // i2c data
|
{socket_message_CorrelationRequest_i2c_scan_data_request_tag,
|
||||||
[](const auto &req, auto &res, int clientId) {
|
[](const auto &req, auto &res, int clientId) {
|
||||||
res.which_response = socket_message_CorrelationResponse_i2c_scan_data_tag;
|
res.which_response = socket_message_CorrelationResponse_i2c_scan_data_tag;
|
||||||
peripherals.scanI2C();
|
peripherals.scanI2C();
|
||||||
peripherals.getI2CScanProto(res.response.i2c_scan_data);
|
peripherals.getI2CScanProto(res.response.i2c_scan_data);
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{socket_message_CorrelationRequest_imu_calibrate_execute_tag, // Calibration request
|
{socket_message_CorrelationRequest_imu_calibrate_execute_tag,
|
||||||
[](const auto &req, auto &res, int clientId) {
|
[](const auto &req, auto &res, int clientId) {
|
||||||
res.which_response = socket_message_CorrelationResponse_imu_calibrate_data_tag;
|
res.which_response = socket_message_CorrelationResponse_imu_calibrate_data_tag;
|
||||||
res.response.imu_calibrate_data.success = peripherals.calibrateIMU();
|
res.response.imu_calibrate_data.success = peripherals.calibrateIMU();
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{socket_message_CorrelationRequest_system_information_request_tag, // All system information data
|
{socket_message_CorrelationRequest_system_information_request_tag,
|
||||||
[](const auto &req, auto &res, int clientId) {
|
[](const auto &req, auto &res, int clientId) {
|
||||||
res.which_response = socket_message_CorrelationResponse_system_information_response_tag;
|
res.which_response = socket_message_CorrelationResponse_system_information_response_tag;
|
||||||
res.response.system_information_response.has_analytics_data = true;
|
res.response.system_information_response.has_analytics_data = true;
|
||||||
res.response.system_information_response.has_static_system_information = true;
|
res.response.system_information_response.has_static_system_information = true;
|
||||||
system_service::getAnalytics(res.response.system_information_response.analytics_data);
|
system_service::getAnalytics(res.response.system_information_response.analytics_data);
|
||||||
system_service::getStaticSystemInformation(res.response.system_information_response.static_system_information);
|
system_service::getStaticSystemInformation(
|
||||||
|
res.response.system_information_response.static_system_information);
|
||||||
}},
|
}},
|
||||||
|
|
||||||
// Filesystem operations
|
{socket_message_CorrelationRequest_fs_delete_request_tag,
|
||||||
{socket_message_CorrelationRequest_fs_delete_request_tag, // Delete file/directory
|
|
||||||
[](const auto &req, auto &res, int clientId) {
|
[](const auto &req, auto &res, int clientId) {
|
||||||
res.which_response = socket_message_CorrelationResponse_fs_delete_response_tag;
|
res.which_response = socket_message_CorrelationResponse_fs_delete_response_tag;
|
||||||
res.response.fs_delete_response = FileSystemWS::fsHandler.handleDelete(req.request.fs_delete_request);
|
res.response.fs_delete_response = FileSystemWS::fsHandler.handleDelete(req.request.fs_delete_request);
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{socket_message_CorrelationRequest_fs_mkdir_request_tag, // Create directory
|
{socket_message_CorrelationRequest_fs_mkdir_request_tag,
|
||||||
[](const auto &req, auto &res, int clientId) {
|
[](const auto &req, auto &res, int clientId) {
|
||||||
res.which_response = socket_message_CorrelationResponse_fs_mkdir_response_tag;
|
res.which_response = socket_message_CorrelationResponse_fs_mkdir_response_tag;
|
||||||
res.response.fs_mkdir_response = FileSystemWS::fsHandler.handleMkdir(req.request.fs_mkdir_request);
|
res.response.fs_mkdir_response = FileSystemWS::fsHandler.handleMkdir(req.request.fs_mkdir_request);
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{socket_message_CorrelationRequest_fs_list_request_tag, // List directory
|
{socket_message_CorrelationRequest_fs_list_request_tag,
|
||||||
[](const auto &req, auto &res, int clientId) {
|
[](const auto &req, auto &res, int clientId) {
|
||||||
res.which_response = socket_message_CorrelationResponse_fs_list_response_tag;
|
res.which_response = socket_message_CorrelationResponse_fs_list_response_tag;
|
||||||
res.response.fs_list_response = FileSystemWS::fsHandler.handleList(req.request.fs_list_request);
|
res.response.fs_list_response = FileSystemWS::fsHandler.handleList(req.request.fs_list_request);
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{socket_message_CorrelationRequest_fs_download_request_tag, // Streaming download (no response, streams data)
|
{socket_message_CorrelationRequest_fs_download_request_tag,
|
||||||
[](const auto &req, auto &res, int clientId) {
|
[](const auto &req, auto &res, int clientId) {
|
||||||
FileSystemWS::fsHandler.handleDownloadRequest(req.request.fs_download_request, clientId);
|
FileSystemWS::fsHandler.handleDownloadRequest(req.request.fs_download_request, clientId);
|
||||||
res.status_code = 0;
|
res.status_code = 0;
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{socket_message_CorrelationRequest_fs_upload_start_tag, // Upload start
|
{socket_message_CorrelationRequest_fs_upload_start_tag,
|
||||||
[](const auto &req, auto &res, int clientId) {
|
[](const auto &req, auto &res, int clientId) {
|
||||||
res.which_response = socket_message_CorrelationResponse_fs_upload_start_response_tag;
|
res.which_response = socket_message_CorrelationResponse_fs_upload_start_response_tag;
|
||||||
res.response.fs_upload_start_response = FileSystemWS::fsHandler.handleUploadStart(req.request.fs_upload_start, clientId);
|
res.response.fs_upload_start_response =
|
||||||
|
FileSystemWS::fsHandler.handleUploadStart(req.request.fs_upload_start, clientId);
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{socket_message_CorrelationRequest_fs_cancel_transfer_tag, // Cancel transfer
|
{socket_message_CorrelationRequest_fs_cancel_transfer_tag,
|
||||||
[](const auto &req, auto &res, int clientId) {
|
[](const auto &req, auto &res, int clientId) {
|
||||||
res.which_response = socket_message_CorrelationResponse_fs_cancel_transfer_response_tag;
|
res.which_response = socket_message_CorrelationResponse_fs_cancel_transfer_response_tag;
|
||||||
res.response.fs_cancel_transfer_response = FileSystemWS::fsHandler.handleCancelTransfer(req.request.fs_cancel_transfer);
|
res.response.fs_cancel_transfer_response =
|
||||||
|
FileSystemWS::fsHandler.handleCancelTransfer(req.request.fs_cancel_transfer);
|
||||||
}},
|
}},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -339,4 +329,4 @@ void setup() {
|
|||||||
ESP_LOGI("main", "Finished booting");
|
ESP_LOGI("main", "Finished booting");
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() { vTaskDelete(nullptr); }
|
void loop() { vTaskDelete(nullptr); }
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <mdns_service.h>
|
#include <mdns_service.h>
|
||||||
|
#include <communication/native_server.h>
|
||||||
|
|
||||||
static const char *TAG = "MDNSService";
|
static const char *TAG = "MDNSService";
|
||||||
|
|
||||||
@@ -64,11 +65,11 @@ void MDNSService::addServices() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t MDNSService::getStatus(PsychicRequest *request) {
|
esp_err_t MDNSService::getStatus(httpd_req_t *request) {
|
||||||
PsychicJsonResponse response = PsychicJsonResponse(request, false);
|
JsonDocument doc;
|
||||||
JsonVariant root = response.getRoot();
|
JsonVariant root = doc.to<JsonVariant>();
|
||||||
getStatus(root);
|
getStatus(root);
|
||||||
return response.send();
|
return NativeServer::sendJson(request, 200, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MDNSService::getStatus(JsonVariant &root) {
|
void MDNSService::getStatus(JsonVariant &root) {
|
||||||
@@ -76,12 +77,12 @@ void MDNSService::getStatus(JsonVariant &root) {
|
|||||||
root["started"] = _started;
|
root["started"] = _started;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t MDNSService::queryServices(PsychicRequest *request, JsonVariant &json) {
|
esp_err_t MDNSService::queryServices(httpd_req_t *request, JsonVariant &json) {
|
||||||
std::string service = json["service"].as<std::string>();
|
std::string service = json["service"].as<std::string>();
|
||||||
std::string proto = json["protocol"].as<std::string>();
|
std::string proto = json["protocol"].as<std::string>();
|
||||||
|
|
||||||
PsychicJsonResponse response = PsychicJsonResponse(request, false);
|
JsonDocument doc;
|
||||||
JsonVariant root = response.getRoot();
|
JsonVariant root = doc.to<JsonVariant>();
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Querying for service: %s, protocol: %s", service.c_str(), proto.c_str());
|
ESP_LOGI(TAG, "Querying for service: %s, protocol: %s", service.c_str(), proto.c_str());
|
||||||
|
|
||||||
@@ -96,5 +97,5 @@ esp_err_t MDNSService::queryServices(PsychicRequest *request, JsonVariant &json)
|
|||||||
serviceObj["port"] = MDNS.port(i);
|
serviceObj["port"] = MDNS.port(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.send();
|
return NativeServer::sendJson(request, 200, doc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <peripherals/camera_service.h>
|
#include <peripherals/camera_service.h>
|
||||||
|
#include <communication/native_server.h>
|
||||||
|
|
||||||
namespace Camera {
|
namespace Camera {
|
||||||
|
|
||||||
@@ -83,78 +84,60 @@ esp_err_t CameraService::begin() {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t CameraService::cameraStill(PsychicRequest *request) {
|
esp_err_t CameraService::cameraStill(httpd_req_t *request) {
|
||||||
camera_fb_t *fb = safe_camera_fb_get();
|
camera_fb_t *fb = safe_camera_fb_get();
|
||||||
if (!fb) {
|
if (!fb) {
|
||||||
ESP_LOGE(TAG, "Camera capture failed");
|
ESP_LOGE(TAG, "Camera capture failed");
|
||||||
request->reply(500, "text/plain", "Camera capture failed");
|
return NativeServer::sendError(request, 500, "Camera capture failed");
|
||||||
return ESP_FAIL;
|
|
||||||
}
|
}
|
||||||
PsychicStreamResponse response = PsychicStreamResponse(request, "image/jpeg", "capture.jpg");
|
|
||||||
response.beginSend();
|
httpd_resp_set_type(request, "image/jpeg");
|
||||||
response.write(fb->buf, fb->len);
|
httpd_resp_set_hdr(request, "Content-Disposition", "inline; filename=capture.jpg");
|
||||||
|
esp_err_t res = httpd_resp_send(request, (const char *)fb->buf, fb->len);
|
||||||
esp_camera_fb_return(fb);
|
esp_camera_fb_return(fb);
|
||||||
return response.endSend();
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamTask(void *pv) {
|
esp_err_t CameraService::cameraStream(httpd_req_t *request) {
|
||||||
|
httpd_resp_set_type(request, _STREAM_CONTENT_TYPE);
|
||||||
|
|
||||||
|
camera_fb_t *fb = NULL;
|
||||||
|
char part_buf[64];
|
||||||
|
uint8_t *buf = NULL;
|
||||||
|
size_t buf_len = 0;
|
||||||
esp_err_t res = ESP_OK;
|
esp_err_t res = ESP_OK;
|
||||||
|
|
||||||
PsychicRequest *request = static_cast<PsychicRequest *>(pv);
|
while (res == ESP_OK) {
|
||||||
|
|
||||||
httpd_req_t *copy = nullptr;
|
|
||||||
res = httpd_req_async_handler_begin(request->request(), ©);
|
|
||||||
if (res != ESP_OK) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
PsychicHttpServer *server = request->server();
|
|
||||||
PsychicRequest new_request = PsychicRequest(server, copy);
|
|
||||||
request = &new_request;
|
|
||||||
|
|
||||||
PsychicStreamResponse response = PsychicStreamResponse(request, _STREAM_CONTENT_TYPE);
|
|
||||||
camera_fb_t *fb = NULL;
|
|
||||||
|
|
||||||
char *part_buf[64];
|
|
||||||
size_t buf_len = 0;
|
|
||||||
uint8_t *buf = NULL;
|
|
||||||
int64_t fr_start = esp_timer_get_time();
|
|
||||||
|
|
||||||
response.beginSend();
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
fb = safe_camera_fb_get();
|
fb = safe_camera_fb_get();
|
||||||
if (!fb) {
|
if (!fb) {
|
||||||
ESP_LOGE("Stream", "Camera capture failed");
|
ESP_LOGE(TAG, "Camera capture failed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (fb->format != PIXFORMAT_JPEG) {
|
if (fb->format != PIXFORMAT_JPEG) {
|
||||||
if (!frame2jpg(fb, 80, &buf, &buf_len)) break;
|
if (!frame2jpg(fb, 80, &buf, &buf_len)) {
|
||||||
|
esp_camera_fb_return(fb);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
buf_len = fb->len;
|
buf_len = fb->len;
|
||||||
buf = fb->buf;
|
buf = fb->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, buf_len);
|
size_t hlen = snprintf(part_buf, 64, _STREAM_PART, buf_len);
|
||||||
size_t w = response.write((const char *)part_buf, hlen);
|
|
||||||
w += response.write((const char *)buf, buf_len);
|
res = httpd_resp_send_chunk(request, part_buf, hlen);
|
||||||
w += response.write((char *)_STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
|
if (res == ESP_OK) res = httpd_resp_send_chunk(request, (const char *)buf, buf_len);
|
||||||
if (w == 62) break;
|
if (res == ESP_OK) res = httpd_resp_send_chunk(request, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
|
||||||
|
|
||||||
esp_camera_fb_return(fb);
|
esp_camera_fb_return(fb);
|
||||||
safe_sensor_return();
|
safe_sensor_return();
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
taskYIELD();
|
|
||||||
int64_t delay = 30000ll - esp_timer_get_time() - fr_start;
|
|
||||||
if (delay > 0) vTaskDelay(pdMS_TO_TICKS(delay));
|
|
||||||
}
|
|
||||||
ESP_LOGI("Stream", "Stream ended");
|
|
||||||
response.endSend();
|
|
||||||
httpd_req_async_handler_complete(copy);
|
|
||||||
vTaskDelete(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t CameraService::cameraStream(PsychicRequest *request) {
|
vTaskDelay(pdMS_TO_TICKS(30));
|
||||||
xTaskCreate(streamTask, "Stream client task", 4096, request, 4, nullptr);
|
}
|
||||||
vTaskDelay(pdMS_TO_TICKS(100));
|
|
||||||
|
ESP_LOGI(TAG, "Stream ended");
|
||||||
|
httpd_resp_send_chunk(request, NULL, 0);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,4 +176,4 @@ void CameraService::updateCamera() {
|
|||||||
safe_sensor_return();
|
safe_sensor_return();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Camera
|
} // namespace Camera
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
#include "system_service.h"
|
#include "system_service.h"
|
||||||
|
#include <communication/native_server.h>
|
||||||
|
|
||||||
namespace system_service {
|
namespace system_service {
|
||||||
|
|
||||||
static const char *TAG = "SystemService";
|
static const char *TAG = "SystemService";
|
||||||
|
|
||||||
esp_err_t handleReset(PsychicRequest *request) {
|
esp_err_t handleReset(httpd_req_t *request) {
|
||||||
reset();
|
reset();
|
||||||
return request->reply(200);
|
return NativeServer::sendOk(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t handleRestart(PsychicRequest *request) {
|
esp_err_t handleRestart(httpd_req_t *request) {
|
||||||
restart();
|
restart();
|
||||||
return request->reply(200);
|
return NativeServer::sendOk(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t handleSleep(PsychicRequest *request) {
|
esp_err_t handleSleep(httpd_req_t *request) {
|
||||||
sleep();
|
sleep();
|
||||||
return request->reply(200);
|
return NativeServer::sendOk(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
@@ -141,4 +142,4 @@ const char *resetReason(esp_reset_reason_t reason) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace system_service
|
} // namespace system_service
|
||||||
|
|||||||
+19
-21
@@ -1,4 +1,5 @@
|
|||||||
#include <wifi_service.h>
|
#include <wifi_service.h>
|
||||||
|
#include <communication/native_server.h>
|
||||||
|
|
||||||
WiFiService::WiFiService()
|
WiFiService::WiFiService()
|
||||||
: _persistence(WiFiSettings::read, WiFiSettings::update, this, WIFI_SETTINGS_FILE),
|
: _persistence(WiFiSettings::read, WiFiSettings::update, this, WIFI_SETTINGS_FILE),
|
||||||
@@ -38,25 +39,28 @@ void WiFiService::reconfigureWiFiConnection() {
|
|||||||
|
|
||||||
void WiFiService::loop() { EXECUTE_EVERY_N_MS(reconnectDelay, manageSTA()); }
|
void WiFiService::loop() { EXECUTE_EVERY_N_MS(reconnectDelay, manageSTA()); }
|
||||||
|
|
||||||
esp_err_t WiFiService::handleScan(PsychicRequest *request) {
|
esp_err_t WiFiService::handleScan(httpd_req_t *request) {
|
||||||
if (WiFi.scanComplete() != -1) {
|
if (WiFi.scanComplete() != -1) {
|
||||||
WiFi.scanDelete();
|
WiFi.scanDelete();
|
||||||
WiFi.scanNetworks(true);
|
WiFi.scanNetworks(true);
|
||||||
}
|
}
|
||||||
return request->reply(202);
|
httpd_resp_set_status(request, "202 Accepted");
|
||||||
|
return httpd_resp_send(request, nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t WiFiService::getNetworks(PsychicRequest *request) {
|
esp_err_t WiFiService::getNetworks(httpd_req_t *request) {
|
||||||
int numNetworks = WiFi.scanComplete();
|
int numNetworks = WiFi.scanComplete();
|
||||||
if (numNetworks == -1)
|
if (numNetworks == -1) {
|
||||||
return request->reply(202);
|
httpd_resp_set_status(request, "202 Accepted");
|
||||||
else if (numNetworks < -1)
|
return httpd_resp_send(request, nullptr, 0);
|
||||||
|
} else if (numNetworks < -1) {
|
||||||
return handleScan(request);
|
return handleScan(request);
|
||||||
|
}
|
||||||
|
|
||||||
PsychicJsonResponse response = PsychicJsonResponse(request, false);
|
JsonDocument doc;
|
||||||
JsonObject root = response.getRoot();
|
JsonObject root = doc.to<JsonObject>();
|
||||||
getNetworks(root);
|
getNetworks(root);
|
||||||
return response.send();
|
return NativeServer::sendJson(request, 200, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiFiService::setupMDNS(const char *hostname) {
|
void WiFiService::setupMDNS(const char *hostname) {
|
||||||
@@ -80,11 +84,11 @@ void WiFiService::getNetworks(JsonObject &root) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t WiFiService::getNetworkStatus(PsychicRequest *request) {
|
esp_err_t WiFiService::getNetworkStatus(httpd_req_t *request) {
|
||||||
PsychicJsonResponse response = PsychicJsonResponse(request, false);
|
JsonDocument doc;
|
||||||
JsonObject root = response.getRoot();
|
JsonObject root = doc.to<JsonObject>();
|
||||||
getNetworkStatus(root);
|
getNetworkStatus(root);
|
||||||
return response.send();
|
return NativeServer::sendJson(request, 200, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiFiService::getNetworkStatus(JsonObject &root) {
|
void WiFiService::getNetworkStatus(JsonObject &root) {
|
||||||
@@ -116,12 +120,10 @@ void WiFiService::manageSTA() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WiFiService::connectToWiFi() {
|
void WiFiService::connectToWiFi() {
|
||||||
// reset availability flag for all stored networks
|
|
||||||
for (auto &network : state().wifiSettings) {
|
for (auto &network : state().wifiSettings) {
|
||||||
network.available = false;
|
network.available = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scanning for available networks
|
|
||||||
int scanResult = WiFi.scanNetworks();
|
int scanResult = WiFi.scanNetworks();
|
||||||
if (scanResult == WIFI_SCAN_FAILED) {
|
if (scanResult == WIFI_SCAN_FAILED) {
|
||||||
ESP_LOGE("WiFiSettingsService", "WiFi scan failed.");
|
ESP_LOGE("WiFiSettingsService", "WiFi scan failed.");
|
||||||
@@ -130,7 +132,6 @@ void WiFiService::connectToWiFi() {
|
|||||||
} else {
|
} else {
|
||||||
ESP_LOGI("WiFiSettingsService", "%d networks found.", scanResult);
|
ESP_LOGI("WiFiSettingsService", "%d networks found.", scanResult);
|
||||||
|
|
||||||
// find the best network to connect
|
|
||||||
wifi_settings_t *bestNetwork = nullptr;
|
wifi_settings_t *bestNetwork = nullptr;
|
||||||
int32_t bestNetworkDb = FACTORY_WIFI_RSSI_THRESHOLD;
|
int32_t bestNetworkDb = FACTORY_WIFI_RSSI_THRESHOLD;
|
||||||
|
|
||||||
@@ -178,19 +179,16 @@ void WiFiService::connectToWiFi() {
|
|||||||
|
|
||||||
void WiFiService::configureNetwork(wifi_settings_t &network) {
|
void WiFiService::configureNetwork(wifi_settings_t &network) {
|
||||||
if (network.staticIPConfig) {
|
if (network.staticIPConfig) {
|
||||||
// configure for static IP
|
|
||||||
WiFi.config(network.localIP, network.gatewayIP, network.subnetMask, network.dnsIP1, network.dnsIP2);
|
WiFi.config(network.localIP, network.gatewayIP, network.subnetMask, network.dnsIP1, network.dnsIP2);
|
||||||
} else {
|
} else {
|
||||||
// configure for DHCP
|
|
||||||
WiFi.config(IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0));
|
WiFi.config(IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0));
|
||||||
}
|
}
|
||||||
WiFi.setHostname(state().hostname.c_str());
|
WiFi.setHostname(state().hostname.c_str());
|
||||||
|
|
||||||
// attempt to connect to the network
|
|
||||||
WiFi.begin(network.ssid.c_str(), network.password.c_str());
|
WiFi.begin(network.ssid.c_str(), network.password.c_str());
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32C3
|
||||||
WiFi.setTxPower(WIFI_POWER_8_5dBm); // https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi
|
WiFi.setTxPower(WIFI_POWER_8_5dBm);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,4 +208,4 @@ void WiFiService::onStationModeStop(WiFiEvent_t event, WiFiEventInfo_t info) {
|
|||||||
void WiFiService::onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info) {
|
void WiFiService::onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||||
ESP_LOGI("WiFiStatus", "WiFi Got IP. localIP=%s, hostName=%s", WiFi.localIP().toString().c_str(),
|
ESP_LOGI("WiFiStatus", "WiFi Got IP. localIP=%s, hostName=%s", WiFi.localIP().toString().c_str(),
|
||||||
WiFi.getHostname());
|
WiFi.getHostname());
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-19
@@ -1,30 +1,25 @@
|
|||||||
#include "www_mount.hpp"
|
#include "www_mount.hpp"
|
||||||
|
|
||||||
static esp_err_t web_send(PsychicRequest* req, const WebAsset& asset) {
|
static esp_err_t web_send(httpd_req_t* req, const WebAsset& asset) {
|
||||||
PsychicResponse resp(req);
|
httpd_resp_set_status(req, "200 OK");
|
||||||
resp.setCode(200);
|
httpd_resp_set_type(req, asset.mime);
|
||||||
resp.setContentType(asset.mime);
|
if (asset.gz) httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
|
||||||
if (asset.gz) resp.addHeader("Content-Encoding", "gzip");
|
if (WWW_OPT.add_vary) httpd_resp_set_hdr(req, "Vary", "Accept-Encoding");
|
||||||
if (WWW_OPT.add_vary) resp.addHeader("Vary", "Accept-Encoding");
|
|
||||||
char cc[64];
|
char cc[64];
|
||||||
snprintf(cc, sizeof(cc), "public, immutable, max-age=%u", WWW_OPT.max_age);
|
snprintf(cc, sizeof(cc), "public, immutable, max-age=%u", WWW_OPT.max_age);
|
||||||
resp.addHeader("Cache-Control", cc);
|
httpd_resp_set_hdr(req, "Cache-Control", cc);
|
||||||
|
|
||||||
char et[34];
|
char et[34];
|
||||||
snprintf(et, sizeof(et), "\"%08x\"", asset.etag);
|
snprintf(et, sizeof(et), "\"%08x\"", asset.etag);
|
||||||
resp.addHeader("ETag", et);
|
httpd_resp_set_hdr(req, "ETag", et);
|
||||||
resp.setContent(asset.data, asset.len);
|
|
||||||
return resp.send();
|
return httpd_resp_send(req, (const char*)asset.data, asset.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mountStaticAssets(PsychicHttpServer& server) {
|
void mountStaticAssets(NativeServer& server) {
|
||||||
static uint8_t buf[sizeof(PsychicWebHandler) * WWW_ASSETS_COUNT];
|
|
||||||
for (size_t i = 0; i < WWW_ASSETS_COUNT; i++) {
|
for (size_t i = 0; i < WWW_ASSETS_COUNT; i++) {
|
||||||
const WebAsset* a = &WWW_ASSETS[i];
|
const WebAsset* a = &WWW_ASSETS[i];
|
||||||
auto* handle = new (&buf[i * sizeof(PsychicWebHandler)]) PsychicWebHandler();
|
server.on(a->uri, HTTP_GET, [a](httpd_req_t* req) { return web_send(req, *a); });
|
||||||
handle->onRequest([a](PsychicRequest* req) { return web_send(req, *a); });
|
|
||||||
server.on(a->uri, HTTP_GET, handle);
|
|
||||||
if (strcmp(a->uri, WWW_OPT.default_uri) == 0) {
|
|
||||||
server.defaultEndpoint->setHandler(handle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,6 @@ build_src_flags =
|
|||||||
test_ignore = test_embedded
|
test_ignore = test_embedded
|
||||||
board_build.filesystem = littlefs
|
board_build.filesystem = littlefs
|
||||||
lib_deps =
|
lib_deps =
|
||||||
hoeken/PsychicHttp@^1.2.1
|
|
||||||
ArduinoJson@>=7.0.0
|
ArduinoJson@>=7.0.0
|
||||||
teckel12/NewPing@^1.9.7
|
teckel12/NewPing@^1.9.7
|
||||||
jrowberg/I2Cdevlib-MPU6050@^1.0.0
|
jrowberg/I2Cdevlib-MPU6050@^1.0.0
|
||||||
|
|||||||
Reference in New Issue
Block a user