mirror of
https://github.com/MrUnknownDE/OpenIris-ESPIDF.git
synced 2026-04-19 06:23:44 +02:00
Improvements and refactors after CR, add option to modify mdns name and simplify setup tool
This commit is contained in:
@@ -25,66 +25,70 @@ std::unordered_map<std::string, CommandType> commandTypeMap = {
|
||||
{"get_device_mode", CommandType::GET_DEVICE_MODE},
|
||||
};
|
||||
|
||||
std::function<CommandResult()> CommandManager::createCommand(const CommandType type, std::string_view json) const {
|
||||
std::function<CommandResult()> CommandManager::createCommand(const CommandType type, std::string_view json) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case CommandType::PING:
|
||||
return { PingCommand };
|
||||
return {PingCommand};
|
||||
case CommandType::PAUSE:
|
||||
return [json] {
|
||||
PausePayload payload;
|
||||
cJSON* root = cJSON_Parse(std::string(json).c_str());
|
||||
if (root) {
|
||||
cJSON* pauseItem = cJSON_GetObjectItem(root, "pause");
|
||||
if (pauseItem && cJSON_IsBool(pauseItem)) {
|
||||
payload.pause = cJSON_IsTrue(pauseItem);
|
||||
} else {
|
||||
payload.pause = true; // Default to pause if not specified
|
||||
}
|
||||
cJSON_Delete(root);
|
||||
} else {
|
||||
payload.pause = true; // Default to pause if parsing fails
|
||||
}
|
||||
return PauseCommand(payload);
|
||||
};
|
||||
return [json]
|
||||
{ return PauseCommand(json); };
|
||||
case CommandType::SET_STREAMING_MODE:
|
||||
return [this, json] {return setDeviceModeCommand(this->registry, json); };
|
||||
return [this, json]
|
||||
{ return setDeviceModeCommand(this->registry, json); };
|
||||
case CommandType::UPDATE_OTA_CREDENTIALS:
|
||||
return [this, json] { return updateOTACredentialsCommand(this->registry, json); };
|
||||
return [this, json]
|
||||
{ return updateOTACredentialsCommand(this->registry, json); };
|
||||
case CommandType::SET_WIFI:
|
||||
return [this, json] { return setWiFiCommand(this->registry, json); };
|
||||
return [this, json]
|
||||
{ return setWiFiCommand(this->registry, json); };
|
||||
case CommandType::UPDATE_WIFI:
|
||||
return [this, json] { return updateWiFiCommand(this->registry, json); };
|
||||
return [this, json]
|
||||
{ return updateWiFiCommand(this->registry, json); };
|
||||
case CommandType::UPDATE_AP_WIFI:
|
||||
return [this, json] { return updateAPWiFiCommand(this->registry, json); };
|
||||
return [this, json]
|
||||
{ return updateAPWiFiCommand(this->registry, json); };
|
||||
case CommandType::DELETE_NETWORK:
|
||||
return [this, json] { return deleteWiFiCommand(this->registry, json); };
|
||||
return [this, json]
|
||||
{ return deleteWiFiCommand(this->registry, json); };
|
||||
case CommandType::SET_MDNS:
|
||||
return [this, json] { return setMDNSCommand(this->registry, json); };
|
||||
return [this, json]
|
||||
{ return setMDNSCommand(this->registry, json); };
|
||||
case CommandType::UPDATE_CAMERA:
|
||||
return [this, json] { return updateCameraCommand(this->registry, json); };
|
||||
return [this, json]
|
||||
{ return updateCameraCommand(this->registry, json); };
|
||||
case CommandType::RESTART_CAMERA:
|
||||
return [this, json] { return restartCameraCommand(this->registry, json); };
|
||||
return [this, json]
|
||||
{ return restartCameraCommand(this->registry, json); };
|
||||
case CommandType::GET_CONFIG:
|
||||
return [this] { return getConfigCommand(this->registry); };
|
||||
return [this]
|
||||
{ return getConfigCommand(this->registry); };
|
||||
case CommandType::SAVE_CONFIG:
|
||||
return [this] { return saveConfigCommand(this->registry); };
|
||||
return [this]
|
||||
{ return saveConfigCommand(this->registry); };
|
||||
case CommandType::RESET_CONFIG:
|
||||
return [this, json] { return resetConfigCommand(this->registry, json); };
|
||||
return [this, json]
|
||||
{ return resetConfigCommand(this->registry, json); };
|
||||
case CommandType::RESTART_DEVICE:
|
||||
return restartDeviceCommand;
|
||||
case CommandType::SCAN_NETWORKS:
|
||||
return [this] { return scanNetworksCommand(this->registry); };
|
||||
return [this]
|
||||
{ return scanNetworksCommand(this->registry); };
|
||||
case CommandType::START_STREAMING:
|
||||
return startStreamingCommand;
|
||||
case CommandType::GET_WIFI_STATUS:
|
||||
return [this] { return getWiFiStatusCommand(this->registry); };
|
||||
return [this]
|
||||
{ return getWiFiStatusCommand(this->registry); };
|
||||
case CommandType::CONNECT_WIFI:
|
||||
return [this] { return connectWiFiCommand(this->registry); };
|
||||
return [this]
|
||||
{ return connectWiFiCommand(this->registry); };
|
||||
case CommandType::SWITCH_MODE:
|
||||
return [this, json] { return switchModeCommand(this->registry, json); };
|
||||
return [this, json]
|
||||
{ return switchModeCommand(this->registry, json); };
|
||||
case CommandType::GET_DEVICE_MODE:
|
||||
return [this] { return getDeviceModeCommand(this->registry); };
|
||||
return [this]
|
||||
{ return getDeviceModeCommand(this->registry); };
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
@@ -135,7 +139,7 @@ CommandResult CommandManager::executeFromJson(const std::string_view json) const
|
||||
cJSON_AddItemToArray(responses, response);
|
||||
}
|
||||
|
||||
char* jsonString = cJSON_Print(responseDocument);
|
||||
char *jsonString = cJSON_Print(responseDocument);
|
||||
cJSON_Delete(responseDocument);
|
||||
cJSON_Delete(parsedJson);
|
||||
|
||||
|
||||
@@ -22,30 +22,30 @@ public:
|
||||
CommandResult(std::string message, const Status status)
|
||||
{
|
||||
this->status = status;
|
||||
|
||||
// Escape quotes and backslashes in the message for JSON
|
||||
std::string escapedMessage = message;
|
||||
size_t pos = 0;
|
||||
// First escape backslashes
|
||||
while ((pos = escapedMessage.find('\\', pos)) != std::string::npos) {
|
||||
while ((pos = escapedMessage.find('\\', pos)) != std::string::npos)
|
||||
{
|
||||
escapedMessage.replace(pos, 1, "\\\\");
|
||||
pos += 2;
|
||||
}
|
||||
// Then escape quotes
|
||||
pos = 0;
|
||||
while ((pos = escapedMessage.find('"', pos)) != std::string::npos) {
|
||||
while ((pos = escapedMessage.find('"', pos)) != std::string::npos)
|
||||
{
|
||||
escapedMessage.replace(pos, 1, "\\\"");
|
||||
pos += 2;
|
||||
}
|
||||
|
||||
|
||||
if (status == Status::SUCCESS)
|
||||
{
|
||||
// we gotta do it this way, because if we define it as { "result": " {} " } it crashes the compiler, lol
|
||||
this->message = std::format("{}\"result\":\"{}\"{}", "{", escapedMessage, "}");
|
||||
this->message = std::format("{{\"result\":\"{}\"}}", escapedMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->message = std::format("{}\"error\":\"{}\"{}", "{", escapedMessage, "}");
|
||||
this->message = std::format("{{\"error\":\"{}\"}}", escapedMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
{
|
||||
return CommandResult(message, Status::FAILURE);
|
||||
}
|
||||
|
||||
|
||||
// Create a result that returns raw JSON without wrapper
|
||||
static CommandResult getRawJsonResult(const std::string &jsonMessage)
|
||||
{
|
||||
@@ -70,7 +70,6 @@ public:
|
||||
}
|
||||
|
||||
std::string getResult() const { return this->message; }
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,25 +1,24 @@
|
||||
#include "device_commands.hpp"
|
||||
|
||||
#include <cJSON.h>
|
||||
#include <ProjectConfig.hpp>
|
||||
#include "esp_timer.h"
|
||||
#include <main_globals.hpp>
|
||||
|
||||
// Implementation inspired by SummerSigh work, initial PR opened in openiris repo, adapted to this rewrite
|
||||
CommandResult setDeviceModeCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload) {
|
||||
CommandResult setDeviceModeCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload)
|
||||
{
|
||||
const auto parsedJson = cJSON_Parse(jsonPayload.data());
|
||||
if (parsedJson == nullptr) {
|
||||
if (parsedJson == nullptr)
|
||||
{
|
||||
return CommandResult::getErrorResult("Invalid payload");
|
||||
}
|
||||
|
||||
const auto modeObject = cJSON_GetObjectItem(parsedJson, "mode");
|
||||
if (modeObject == nullptr) {
|
||||
if (modeObject == nullptr)
|
||||
{
|
||||
return CommandResult::getErrorResult("Invalid payload - missing mode");
|
||||
}
|
||||
|
||||
const auto mode = modeObject->valueint;
|
||||
|
||||
if (mode < 0 || mode > 2) {
|
||||
if (mode < 0 || mode > 2)
|
||||
{
|
||||
return CommandResult::getErrorResult("Invalid payload - unsupported mode");
|
||||
}
|
||||
|
||||
@@ -29,10 +28,12 @@ CommandResult setDeviceModeCommand(std::shared_ptr<DependencyRegistry> registry,
|
||||
return CommandResult::getSuccessResult("Device mode set");
|
||||
}
|
||||
|
||||
CommandResult updateOTACredentialsCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload) {
|
||||
CommandResult updateOTACredentialsCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload)
|
||||
{
|
||||
const auto parsedJson = cJSON_Parse(jsonPayload.data());
|
||||
|
||||
if (parsedJson == nullptr) {
|
||||
if (parsedJson == nullptr)
|
||||
{
|
||||
return CommandResult::getErrorResult("Invalid payload");
|
||||
}
|
||||
|
||||
@@ -42,18 +43,23 @@ CommandResult updateOTACredentialsCommand(std::shared_ptr<DependencyRegistry> re
|
||||
auto OTAPassword = oldDeviceConfig.OTAPassword;
|
||||
auto OTAPort = oldDeviceConfig.OTAPort;
|
||||
|
||||
if (const auto OTALoginObject = cJSON_GetObjectItem(parsedJson, "login"); OTALoginObject != nullptr) {
|
||||
if (const auto newLogin = OTALoginObject->valuestring; strcmp(newLogin, "") != 0) {
|
||||
if (const auto OTALoginObject = cJSON_GetObjectItem(parsedJson, "login"); OTALoginObject != nullptr)
|
||||
{
|
||||
if (const auto newLogin = OTALoginObject->valuestring; strcmp(newLogin, "") != 0)
|
||||
{
|
||||
OTALogin = newLogin;
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto OTAPasswordObject = cJSON_GetObjectItem(parsedJson, "password"); OTAPasswordObject != nullptr) {
|
||||
if (const auto OTAPasswordObject = cJSON_GetObjectItem(parsedJson, "password"); OTAPasswordObject != nullptr)
|
||||
{
|
||||
OTAPassword = OTAPasswordObject->valuestring;
|
||||
}
|
||||
|
||||
if (const auto OTAPortObject = cJSON_GetObjectItem(parsedJson, "port"); OTAPortObject != nullptr) {
|
||||
if (const auto newPort = OTAPortObject->valueint; newPort >= 82) {
|
||||
if (const auto OTAPortObject = cJSON_GetObjectItem(parsedJson, "port"); OTAPortObject != nullptr)
|
||||
{
|
||||
if (const auto newPort = OTAPortObject->valueint; newPort >= 82)
|
||||
{
|
||||
OTAPort = newPort;
|
||||
}
|
||||
}
|
||||
@@ -62,70 +68,82 @@ CommandResult updateOTACredentialsCommand(std::shared_ptr<DependencyRegistry> re
|
||||
return CommandResult::getSuccessResult("OTA Config set");
|
||||
}
|
||||
|
||||
CommandResult restartDeviceCommand() {
|
||||
CommandResult restartDeviceCommand()
|
||||
{
|
||||
OpenIrisTasks::ScheduleRestart(2000);
|
||||
return CommandResult::getSuccessResult("Device restarted");
|
||||
}
|
||||
|
||||
CommandResult startStreamingCommand() {
|
||||
CommandResult startStreamingCommand()
|
||||
{
|
||||
activateStreaming(false); // Don't disable setup interfaces by default
|
||||
return CommandResult::getSuccessResult("Streaming started");
|
||||
}
|
||||
|
||||
CommandResult switchModeCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload) {
|
||||
CommandResult switchModeCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload)
|
||||
{
|
||||
const auto parsedJson = cJSON_Parse(jsonPayload.data());
|
||||
if (parsedJson == nullptr) {
|
||||
if (parsedJson == nullptr)
|
||||
{
|
||||
return CommandResult::getErrorResult("Invalid payload");
|
||||
}
|
||||
|
||||
const auto modeObject = cJSON_GetObjectItem(parsedJson, "mode");
|
||||
if (modeObject == nullptr) {
|
||||
if (modeObject == nullptr)
|
||||
{
|
||||
return CommandResult::getErrorResult("Invalid payload - missing mode");
|
||||
}
|
||||
|
||||
const char* modeStr = modeObject->valuestring;
|
||||
const char *modeStr = modeObject->valuestring;
|
||||
StreamingMode newMode;
|
||||
|
||||
|
||||
ESP_LOGI("[DEVICE_COMMANDS]", "Switch mode command received with mode: %s", modeStr);
|
||||
|
||||
if (strcmp(modeStr, "uvc") == 0 || strcmp(modeStr, "UVC") == 0) {
|
||||
|
||||
if (strcmp(modeStr, "uvc") == 0)
|
||||
{
|
||||
newMode = StreamingMode::UVC;
|
||||
} else if (strcmp(modeStr, "wifi") == 0 || strcmp(modeStr, "WiFi") == 0 || strcmp(modeStr, "WIFI") == 0) {
|
||||
}
|
||||
else if (strcmp(modeStr, "wifi") == 0)
|
||||
{
|
||||
newMode = StreamingMode::WIFI;
|
||||
} else if (strcmp(modeStr, "auto") == 0 || strcmp(modeStr, "AUTO") == 0) {
|
||||
}
|
||||
else if (strcmp(modeStr, "auto") == 0)
|
||||
{
|
||||
newMode = StreamingMode::AUTO;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return CommandResult::getErrorResult("Invalid mode - use 'uvc', 'wifi', or 'auto'");
|
||||
}
|
||||
|
||||
const auto projectConfig = registry->resolve<ProjectConfig>(DependencyType::project_config);
|
||||
ESP_LOGI("[DEVICE_COMMANDS]", "Setting device mode to: %d", (int)newMode);
|
||||
projectConfig->setDeviceMode(newMode);
|
||||
|
||||
|
||||
cJSON_Delete(parsedJson);
|
||||
|
||||
return CommandResult::getSuccessResult("Device mode switched, restart to apply");
|
||||
}
|
||||
|
||||
CommandResult getDeviceModeCommand(std::shared_ptr<DependencyRegistry> registry) {
|
||||
CommandResult getDeviceModeCommand(std::shared_ptr<DependencyRegistry> registry)
|
||||
{
|
||||
const auto projectConfig = registry->resolve<ProjectConfig>(DependencyType::project_config);
|
||||
StreamingMode currentMode = projectConfig->getDeviceMode();
|
||||
|
||||
const char* modeStr = "unknown";
|
||||
switch (currentMode) {
|
||||
case StreamingMode::UVC:
|
||||
modeStr = "UVC";
|
||||
break;
|
||||
case StreamingMode::WIFI:
|
||||
modeStr = "WiFi";
|
||||
break;
|
||||
case StreamingMode::AUTO:
|
||||
modeStr = "Auto";
|
||||
break;
|
||||
|
||||
const char *modeStr = "unknown";
|
||||
switch (currentMode)
|
||||
{
|
||||
case StreamingMode::UVC:
|
||||
modeStr = "UVC";
|
||||
break;
|
||||
case StreamingMode::WIFI:
|
||||
modeStr = "WiFi";
|
||||
break;
|
||||
case StreamingMode::AUTO:
|
||||
modeStr = "Auto";
|
||||
break;
|
||||
}
|
||||
|
||||
char result[100];
|
||||
sprintf(result, "{\"mode\":\"%s\",\"value\":%d}", modeStr, (int)currentMode);
|
||||
|
||||
|
||||
auto result = std::format("{{ \"mode\": \"{}\", \"value\": {} }}", modeStr, static_cast<int>(currentMode));
|
||||
return CommandResult::getSuccessResult(result);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
#include "CommandResult.hpp"
|
||||
#include "ProjectConfig.hpp"
|
||||
#include "OpenIrisTasks.hpp"
|
||||
#include "DependencyRegistry.hpp"
|
||||
#include "esp_timer.h"
|
||||
#include "cJSON.h"
|
||||
#include "main_globals.hpp"
|
||||
|
||||
#include <format>
|
||||
#include <string>
|
||||
|
||||
CommandResult setDeviceModeCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload);
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#include "scan_commands.hpp"
|
||||
#include "cJSON.h"
|
||||
#include "esp_log.h"
|
||||
#include <string>
|
||||
|
||||
CommandResult scanNetworksCommand(std::shared_ptr<DependencyRegistry> registry) {
|
||||
CommandResult scanNetworksCommand(std::shared_ptr<DependencyRegistry> registry)
|
||||
{
|
||||
auto wifiManager = registry->resolve<WiFiManager>(DependencyType::wifi_manager);
|
||||
if (!wifiManager) {
|
||||
if (!wifiManager)
|
||||
{
|
||||
return CommandResult::getErrorResult("WiFiManager not available");
|
||||
}
|
||||
|
||||
@@ -15,7 +14,8 @@ CommandResult scanNetworksCommand(std::shared_ptr<DependencyRegistry> registry)
|
||||
cJSON *networksArray = cJSON_CreateArray();
|
||||
cJSON_AddItemToObject(root, "networks", networksArray);
|
||||
|
||||
for (const auto& network : networks) {
|
||||
for (const auto &network : networks)
|
||||
{
|
||||
cJSON *networkObject = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(networkObject, "ssid", network.ssid.c_str());
|
||||
cJSON_AddNumberToObject(networkObject, "channel", network.channel);
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#ifndef SCAN_COMMANDS_HPP
|
||||
#define SCAN_COMMANDS_HPP
|
||||
|
||||
#include "../CommandResult.hpp"
|
||||
#include "../DependencyRegistry.hpp"
|
||||
#include "CommandResult.hpp"
|
||||
#include "DependencyRegistry.hpp"
|
||||
#include "esp_log.h"
|
||||
#include <cJSON.h>
|
||||
#include <wifiManager.hpp>
|
||||
#include <string>
|
||||
|
||||
CommandResult scanNetworksCommand(std::shared_ptr<DependencyRegistry> registry);
|
||||
|
||||
|
||||
@@ -1,24 +1,39 @@
|
||||
#include "simple_commands.hpp"
|
||||
#include "main_globals.hpp"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char* TAG = "SimpleCommands";
|
||||
static const char *TAG = "SimpleCommands";
|
||||
|
||||
CommandResult PingCommand()
|
||||
{
|
||||
return CommandResult::getSuccessResult("pong");
|
||||
};
|
||||
|
||||
CommandResult PauseCommand(const PausePayload& payload)
|
||||
CommandResult PauseCommand(std::string_view jsonPayload)
|
||||
{
|
||||
PausePayload payload;
|
||||
// pause by default if this command gets executed, even if the payload was invalid
|
||||
payload.pause = true;
|
||||
|
||||
cJSON *root = cJSON_Parse(std::string(jsonPayload).c_str());
|
||||
if (root)
|
||||
{
|
||||
cJSON *pauseItem = cJSON_GetObjectItem(root, "pause");
|
||||
if (pauseItem && cJSON_IsBool(pauseItem))
|
||||
{
|
||||
payload.pause = cJSON_IsTrue(pauseItem);
|
||||
}
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Pause command received: %s", payload.pause ? "true" : "false");
|
||||
|
||||
startupPaused = payload.pause;
|
||||
|
||||
if (payload.pause) {
|
||||
|
||||
setStartupPaused(payload.pause);
|
||||
if (payload.pause)
|
||||
{
|
||||
ESP_LOGI(TAG, "Startup paused - device will remain in configuration mode");
|
||||
return CommandResult::getSuccessResult("Startup paused");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "Startup resumed");
|
||||
return CommandResult::getSuccessResult("Startup resumed");
|
||||
}
|
||||
|
||||
@@ -4,8 +4,11 @@
|
||||
#include <string>
|
||||
#include "CommandResult.hpp"
|
||||
#include "CommandSchema.hpp"
|
||||
#include "main_globals.hpp"
|
||||
#include "esp_log.h"
|
||||
#include <cJSON.h>
|
||||
|
||||
CommandResult PingCommand();
|
||||
CommandResult PauseCommand(const PausePayload& payload);
|
||||
CommandResult PauseCommand(std::string_view jsonPayload);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user