feat: improve task handling, refactoring

This commit is contained in:
2025-08-28 20:46:27 +02:00
parent d7e98a41fa
commit 4b63d1011f
8 changed files with 83 additions and 183 deletions

View File

@@ -11,9 +11,6 @@
#include "NodeInfo.h" #include "NodeInfo.h"
#include "TaskManager.h" #include "TaskManager.h"
using namespace std;
using namespace std::placeholders;
class ApiServer { class ApiServer {
public: public:
ApiServer(NodeContext& ctx, TaskManager& taskMgr, uint16_t port = 80); ApiServer(NodeContext& ctx, TaskManager& taskMgr, uint16_t port = 80);
@@ -47,7 +44,7 @@ private:
std::vector<std::tuple<String, int>> serviceRegistry; std::vector<std::tuple<String, int>> serviceRegistry;
std::vector<EndpointCapability> capabilityRegistry; std::vector<EndpointCapability> capabilityRegistry;
void onClusterMembersRequest(AsyncWebServerRequest *request); void onClusterMembersRequest(AsyncWebServerRequest *request);
void methodToStr(const std::tuple<String, int> &endpoint, ArduinoJson::V742PB22::JsonObject &apiObj); void methodToStr(const std::tuple<String, int> &endpoint, JsonObject &apiObj);
void onSystemStatusRequest(AsyncWebServerRequest *request); void onSystemStatusRequest(AsyncWebServerRequest *request);
void onFirmwareUpdateRequest(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 onFirmwareUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final);
@@ -59,4 +56,7 @@ private:
// Capabilities endpoint // Capabilities endpoint
void onCapabilitiesRequest(AsyncWebServerRequest *request); void onCapabilitiesRequest(AsyncWebServerRequest *request);
// Internal helpers
void registerServiceForLocalNode(const String& uri, int method);
}; };

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#include <TaskSchedulerDeclarations.h>
#include <WiFiUdp.h> #include <WiFiUdp.h>
#include <map> #include <map>
#include "NodeInfo.h" #include "NodeInfo.h"
@@ -11,7 +11,6 @@ class NodeContext {
public: public:
NodeContext(); NodeContext();
~NodeContext(); ~NodeContext();
Scheduler* scheduler;
WiFiUDP* udp; WiFiUDP* udp;
String hostname; String hostname;
IPAddress localIP; IPAddress localIP;

View File

@@ -7,10 +7,6 @@
#include "NodeContext.h" #include "NodeContext.h"
#include <ArduinoJson.h> #include <ArduinoJson.h>
// Forward declarations to avoid multiple definition errors
class Task;
class Scheduler;
// Define our own callback type to avoid conflict with TaskScheduler // Define our own callback type to avoid conflict with TaskScheduler
using TaskFunction = std::function<void()>; using TaskFunction = std::function<void()>;
@@ -60,13 +56,8 @@ public:
private: private:
NodeContext& ctx; NodeContext& ctx;
std::vector<Task*> tasks;
std::vector<TaskDefinition> taskDefinitions; std::vector<TaskDefinition> taskDefinitions;
std::vector<unsigned long> lastExecutionTimes;
Task* findTask(const std::string& name) const; int findTaskIndex(const std::string& name) const;
void createTask(const TaskDefinition& taskDef);
// Static callback registry for all TaskManager instances
static std::map<std::string, std::function<void()>> callbackRegistry;
static void executeCallback(const std::string& taskName);
}; };

View File

@@ -17,7 +17,6 @@ monitor_speed = 115200
lib_deps = lib_deps =
esp32async/ESPAsyncWebServer@^3.8.0 esp32async/ESPAsyncWebServer@^3.8.0
bblanchon/ArduinoJson@^7.4.2 bblanchon/ArduinoJson@^7.4.2
arkhipenko/TaskScheduler@^3.8.5
[env:esp01_1m] [env:esp01_1m]
platform = platformio/espressif8266@^4.2.1 platform = platformio/espressif8266@^4.2.1

View File

@@ -1,29 +1,38 @@
#include "ApiServer.h" #include "ApiServer.h"
#include <algorithm> #include <algorithm>
// Shared helper for HTTP method to string
static const char* methodStrFromInt(int method) {
switch (method) {
case HTTP_GET: return "GET";
case HTTP_POST: return "POST";
case HTTP_PUT: return "PUT";
case HTTP_DELETE: return "DELETE";
case HTTP_PATCH: return "PATCH";
default: return "UNKNOWN";
}
}
ApiServer::ApiServer(NodeContext& ctx, TaskManager& taskMgr, uint16_t port) : server(port), ctx(ctx), taskManager(taskMgr) {} ApiServer::ApiServer(NodeContext& ctx, TaskManager& taskMgr, uint16_t port) : server(port), ctx(ctx), taskManager(taskMgr) {}
void ApiServer::addEndpoint(const String& uri, int method, std::function<void(AsyncWebServerRequest*)> requestHandler) { void ApiServer::registerServiceForLocalNode(const String& uri, int method) {
serviceRegistry.push_back(std::make_tuple(uri, method)); serviceRegistry.push_back(std::make_tuple(uri, method));
// Store in NodeInfo for local node
if (ctx.memberList && !ctx.memberList->empty()) { if (ctx.memberList && !ctx.memberList->empty()) {
auto it = ctx.memberList->find(ctx.hostname); auto it = ctx.memberList->find(ctx.hostname);
if (it != ctx.memberList->end()) { if (it != ctx.memberList->end()) {
it->second.apiEndpoints.push_back(std::make_tuple(uri, method)); it->second.apiEndpoints.push_back(std::make_tuple(uri, method));
} }
} }
}
void ApiServer::addEndpoint(const String& uri, int method, std::function<void(AsyncWebServerRequest*)> requestHandler) {
registerServiceForLocalNode(uri, method);
server.on(uri.c_str(), method, requestHandler); server.on(uri.c_str(), method, requestHandler);
} }
void ApiServer::addEndpoint(const String& uri, int method, std::function<void(AsyncWebServerRequest*)> requestHandler, void ApiServer::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) { std::function<void(AsyncWebServerRequest*, const String&, size_t, uint8_t*, size_t, bool)> uploadHandler) {
serviceRegistry.push_back(std::make_tuple(uri, method)); registerServiceForLocalNode(uri, method);
if (ctx.memberList && !ctx.memberList->empty()) {
auto it = ctx.memberList->find(ctx.hostname);
if (it != ctx.memberList->end()) {
it->second.apiEndpoints.push_back(std::make_tuple(uri, method));
}
}
server.on(uri.c_str(), method, requestHandler, uploadHandler); server.on(uri.c_str(), method, requestHandler, uploadHandler);
} }
@@ -31,13 +40,7 @@ void ApiServer::addEndpoint(const String& uri, int method, std::function<void(As
void ApiServer::addEndpoint(const String& uri, int method, std::function<void(AsyncWebServerRequest*)> requestHandler, void ApiServer::addEndpoint(const String& uri, int method, std::function<void(AsyncWebServerRequest*)> requestHandler,
const std::vector<ParamSpec>& params) { const std::vector<ParamSpec>& params) {
capabilityRegistry.push_back(EndpointCapability{uri, method, params}); capabilityRegistry.push_back(EndpointCapability{uri, method, params});
serviceRegistry.push_back(std::make_tuple(uri, method)); registerServiceForLocalNode(uri, method);
if (ctx.memberList && !ctx.memberList->empty()) {
auto it = ctx.memberList->find(ctx.hostname);
if (it != ctx.memberList->end()) {
it->second.apiEndpoints.push_back(std::make_tuple(uri, method));
}
}
server.on(uri.c_str(), method, requestHandler); server.on(uri.c_str(), method, requestHandler);
} }
@@ -45,13 +48,7 @@ void ApiServer::addEndpoint(const String& uri, int method, std::function<void(As
std::function<void(AsyncWebServerRequest*, const String&, size_t, uint8_t*, size_t, bool)> uploadHandler, std::function<void(AsyncWebServerRequest*, const String&, size_t, uint8_t*, size_t, bool)> uploadHandler,
const std::vector<ParamSpec>& params) { const std::vector<ParamSpec>& params) {
capabilityRegistry.push_back(EndpointCapability{uri, method, params}); capabilityRegistry.push_back(EndpointCapability{uri, method, params});
serviceRegistry.push_back(std::make_tuple(uri, method)); registerServiceForLocalNode(uri, method);
if (ctx.memberList && !ctx.memberList->empty()) {
auto it = ctx.memberList->find(ctx.hostname);
if (it != ctx.memberList->end()) {
it->second.apiEndpoints.push_back(std::make_tuple(uri, method));
}
}
server.on(uri.c_str(), method, requestHandler, uploadHandler); server.on(uri.c_str(), method, requestHandler, uploadHandler);
} }
@@ -131,37 +128,15 @@ void ApiServer::onClusterMembersRequest(AsyncWebServerRequest *request) {
request->send(200, "application/json", json); request->send(200, "application/json", json);
} }
void ApiServer::methodToStr(const std::tuple<String, int> &endpoint, ArduinoJson::V742PB22::JsonObject &apiObj) void ApiServer::methodToStr(const std::tuple<String, int> &endpoint, JsonObject &apiObj)
{ {
int method = std::get<1>(endpoint); int method = std::get<1>(endpoint);
const char *methodStr = nullptr; apiObj["method"] = methodStrFromInt(method);
switch (method)
{
case HTTP_GET:
methodStr = "GET";
break;
case HTTP_POST:
methodStr = "POST";
break;
case HTTP_PUT:
methodStr = "PUT";
break;
case HTTP_DELETE:
methodStr = "DELETE";
break;
case HTTP_PATCH:
methodStr = "PATCH";
break;
default:
methodStr = "UNKNOWN";
break;
}
apiObj["method"] = methodStr;
} }
void ApiServer::onFirmwareUpdateRequest(AsyncWebServerRequest *request) { void ApiServer::onFirmwareUpdateRequest(AsyncWebServerRequest *request) {
bool hasError = !Update.hasError(); bool success = !Update.hasError();
AsyncWebServerResponse *response = request->beginResponse(200, "application/json", hasError ? "{\"status\": \"OK\"}" : "{\"status\": \"FAIL\"}"); AsyncWebServerResponse *response = request->beginResponse(200, "application/json", success ? "{\"status\": \"OK\"}" : "{\"status\": \"FAIL\"}");
response->addHeader("Connection", "close"); response->addHeader("Connection", "close");
request->send(response); request->send(response);
request->onDisconnect([]() { request->onDisconnect([]() {
@@ -183,8 +158,6 @@ void ApiServer::onFirmwareUpload(AsyncWebServerRequest *request, const String &f
response->addHeader("Connection", "close"); response->addHeader("Connection", "close");
request->send(response); request->send(response);
return; return;
} else {
Update.printError(Serial);
} }
} }
if (!Update.hasError()){ if (!Update.hasError()){
@@ -221,10 +194,14 @@ void ApiServer::onRestartRequest(AsyncWebServerRequest *request) {
} }
void ApiServer::onTaskStatusRequest(AsyncWebServerRequest *request) { void ApiServer::onTaskStatusRequest(AsyncWebServerRequest *request) {
JsonDocument doc; // Use a separate document as scratch space for task statuses to avoid interfering with the response root
JsonDocument scratch;
// Get comprehensive task status from TaskManager // Get comprehensive task status from TaskManager
auto taskStatuses = taskManager.getAllTaskStatuses(doc); auto taskStatuses = taskManager.getAllTaskStatuses(scratch);
// Build response document
JsonDocument doc;
// Add summary information // Add summary information
JsonObject summaryObj = doc["summary"].to<JsonObject>(); JsonObject summaryObj = doc["summary"].to<JsonObject>();
@@ -344,16 +321,6 @@ void ApiServer::onCapabilitiesRequest(AsyncWebServerRequest *request) {
auto makeKey = [](const String& uri, int method) { auto makeKey = [](const String& uri, int method) {
String k = uri; k += "|"; k += method; return k; String k = uri; k += "|"; k += method; return k;
}; };
auto methodStrFromInt = [](int method) -> const char* {
switch (method) {
case HTTP_GET: return "GET";
case HTTP_POST: return "POST";
case HTTP_PUT: return "PUT";
case HTTP_DELETE: return "DELETE";
case HTTP_PATCH: return "PATCH";
default: return "UNKNOWN";
}
};
// Rich entries first // Rich entries first
for (const auto& cap : capabilityRegistry) { for (const auto& cap : capabilityRegistry) {

View File

@@ -1,14 +1,12 @@
#include "NodeContext.h" #include "NodeContext.h"
NodeContext::NodeContext() { NodeContext::NodeContext() {
scheduler = new Scheduler();
udp = new WiFiUDP(); udp = new WiFiUDP();
memberList = new std::map<String, NodeInfo>(); memberList = new std::map<String, NodeInfo>();
hostname = ""; hostname = "";
} }
NodeContext::~NodeContext() { NodeContext::~NodeContext() {
delete scheduler;
delete udp; delete udp;
delete memberList; delete memberList;
} }

View File

@@ -14,7 +14,7 @@ void updateNodeStatus(NodeInfo &node, unsigned long now, unsigned long inactive_
if (diff < inactive_threshold) { if (diff < inactive_threshold) {
node.status = NodeInfo::ACTIVE; node.status = NodeInfo::ACTIVE;
} else if (diff < dead_threshold) { } else if (diff < dead_threshold) {
node.status = NodeInfo::DEAD; node.status = NodeInfo::INACTIVE;
} else { } else {
node.status = NodeInfo::DEAD; node.status = NodeInfo::DEAD;
} }

View File

@@ -1,18 +1,9 @@
#include "TaskManager.h" #include "TaskManager.h"
#include <Arduino.h> #include <Arduino.h>
#include <TaskScheduler.h>
// Define static members
std::map<std::string, std::function<void()>> TaskManager::callbackRegistry;
TaskManager::TaskManager(NodeContext& ctx) : ctx(ctx) {} TaskManager::TaskManager(NodeContext& ctx) : ctx(ctx) {}
TaskManager::~TaskManager() { TaskManager::~TaskManager() {
// Clean up tasks
for (auto task : tasks) {
delete task;
}
tasks.clear();
} }
void TaskManager::registerTask(const std::string& name, unsigned long interval, TaskFunction callback, bool enabled, bool autoStart) { void TaskManager::registerTask(const std::string& name, unsigned long interval, TaskFunction callback, bool enabled, bool autoStart) {
@@ -25,44 +16,21 @@ void TaskManager::registerTask(const TaskDefinition& taskDef) {
} }
void TaskManager::initialize() { void TaskManager::initialize() {
// Initialize the scheduler // Ensure timing vector matches number of tasks
ctx.scheduler->init(); lastExecutionTimes.assign(taskDefinitions.size(), 0UL);
// Create all registered tasks
for (const auto& taskDef : taskDefinitions) {
createTask(taskDef);
}
// Enable tasks that should auto-start // Enable tasks that should auto-start
for (const auto& taskDef : taskDefinitions) { for (auto& taskDef : taskDefinitions) {
if (taskDef.autoStart && taskDef.enabled) { if (taskDef.autoStart && taskDef.enabled) {
enableTask(taskDef.name); taskDef.enabled = true;
} }
} }
} }
void TaskManager::createTask(const TaskDefinition& taskDef) {
// Store the callback in the static registry
callbackRegistry[taskDef.name] = taskDef.callback;
// Create a dummy task - we'll handle execution ourselves
Task* task = new Task(0, TASK_FOREVER, []() { /* Dummy callback */ });
task->setInterval(taskDef.interval);
// Add to scheduler
ctx.scheduler->addTask(*task);
// Store task pointer
tasks.push_back(task);
Serial.printf("[TaskManager] Created task: %s (interval: %lu ms)\n",
taskDef.name.c_str(), taskDef.interval);
}
void TaskManager::enableTask(const std::string& name) { void TaskManager::enableTask(const std::string& name) {
Task* task = findTask(name); int idx = findTaskIndex(name);
if (task) { if (idx >= 0) {
task->enable(); taskDefinitions[idx].enabled = true;
Serial.printf("[TaskManager] Enabled task: %s\n", name.c_str()); Serial.printf("[TaskManager] Enabled task: %s\n", name.c_str());
} else { } else {
Serial.printf("[TaskManager] Warning: Task not found: %s\n", name.c_str()); Serial.printf("[TaskManager] Warning: Task not found: %s\n", name.c_str());
@@ -70,9 +38,9 @@ void TaskManager::enableTask(const std::string& name) {
} }
void TaskManager::disableTask(const std::string& name) { void TaskManager::disableTask(const std::string& name) {
Task* task = findTask(name); int idx = findTaskIndex(name);
if (task) { if (idx >= 0) {
task->disable(); taskDefinitions[idx].enabled = false;
Serial.printf("[TaskManager] Disabled task: %s\n", name.c_str()); Serial.printf("[TaskManager] Disabled task: %s\n", name.c_str());
} else { } else {
Serial.printf("[TaskManager] Warning: Task not found: %s\n", name.c_str()); Serial.printf("[TaskManager] Warning: Task not found: %s\n", name.c_str());
@@ -80,9 +48,9 @@ void TaskManager::disableTask(const std::string& name) {
} }
void TaskManager::setTaskInterval(const std::string& name, unsigned long interval) { void TaskManager::setTaskInterval(const std::string& name, unsigned long interval) {
Task* task = findTask(name); int idx = findTaskIndex(name);
if (task) { if (idx >= 0) {
task->setInterval(interval); taskDefinitions[idx].interval = interval;
Serial.printf("[TaskManager] Set interval for task %s: %lu ms\n", name.c_str(), interval); Serial.printf("[TaskManager] Set interval for task %s: %lu ms\n", name.c_str(), interval);
} else { } else {
Serial.printf("[TaskManager] Warning: Task not found: %s\n", name.c_str()); Serial.printf("[TaskManager] Warning: Task not found: %s\n", name.c_str());
@@ -90,50 +58,38 @@ void TaskManager::setTaskInterval(const std::string& name, unsigned long interva
} }
void TaskManager::startTask(const std::string& name) { void TaskManager::startTask(const std::string& name) {
Task* task = findTask(name); enableTask(name);
if (task) {
task->enable();
Serial.printf("[TaskManager] Started task: %s\n", name.c_str());
} else {
Serial.printf("[TaskManager] Warning: Task not found: %s\n", name.c_str());
}
} }
void TaskManager::stopTask(const std::string& name) { void TaskManager::stopTask(const std::string& name) {
Task* task = findTask(name); disableTask(name);
if (task) {
task->disable();
Serial.printf("[TaskManager] Stopped task: %s\n", name.c_str());
} else {
Serial.printf("[TaskManager] Warning: Task not found: %s\n", name.c_str());
}
} }
bool TaskManager::isTaskEnabled(const std::string& name) const { bool TaskManager::isTaskEnabled(const std::string& name) const {
Task* task = findTask(name); int idx = findTaskIndex(name);
return task ? task->isEnabled() : false; return idx >= 0 ? taskDefinitions[idx].enabled : false;
} }
bool TaskManager::isTaskRunning(const std::string& name) const { bool TaskManager::isTaskRunning(const std::string& name) const {
Task* task = findTask(name); int idx = findTaskIndex(name);
return task ? task->isEnabled() : false; return idx >= 0 ? taskDefinitions[idx].enabled : false;
} }
unsigned long TaskManager::getTaskInterval(const std::string& name) const { unsigned long TaskManager::getTaskInterval(const std::string& name) const {
Task* task = findTask(name); int idx = findTaskIndex(name);
return task ? task->getInterval() : 0; return idx >= 0 ? taskDefinitions[idx].interval : 0;
} }
void TaskManager::enableAllTasks() { void TaskManager::enableAllTasks() {
for (auto task : tasks) { for (auto& taskDef : taskDefinitions) {
task->enable(); taskDef.enabled = true;
} }
Serial.println("[TaskManager] Enabled all tasks"); Serial.println("[TaskManager] Enabled all tasks");
} }
void TaskManager::disableAllTasks() { void TaskManager::disableAllTasks() {
for (auto task : tasks) { for (auto& taskDef : taskDefinitions) {
task->disable(); taskDef.enabled = false;
} }
Serial.println("[TaskManager] Disabled all tasks"); Serial.println("[TaskManager] Disabled all tasks");
} }
@@ -142,41 +98,32 @@ void TaskManager::printTaskStatus() const {
Serial.println("\n[TaskManager] Task Status:"); Serial.println("\n[TaskManager] Task Status:");
Serial.println("=========================="); Serial.println("==========================");
for (size_t i = 0; i < tasks.size() && i < taskDefinitions.size(); ++i) { for (const auto& taskDef : taskDefinitions) {
const auto& taskDef = taskDefinitions[i];
const auto& task = tasks[i];
Serial.printf(" %s: %s (interval: %lu ms)\n", Serial.printf(" %s: %s (interval: %lu ms)\n",
taskDef.name.c_str(), taskDef.name.c_str(),
task->isEnabled() ? "ENABLED" : "DISABLED", taskDef.enabled ? "ENABLED" : "DISABLED",
task->getInterval()); taskDef.interval);
} }
Serial.println("==========================\n"); Serial.println("==========================\n");
} }
void TaskManager::execute() { void TaskManager::execute() {
// Execute all enabled tasks by calling their stored callbacks // Ensure timing vector matches number of tasks
static unsigned long lastExecutionTimes[100] = {0}; // Simple array for timing if (lastExecutionTimes.size() != taskDefinitions.size()) {
static int taskCount = 0; lastExecutionTimes.assign(taskDefinitions.size(), 0UL);
if (taskCount == 0) {
taskCount = tasks.size();
} }
unsigned long currentTime = millis(); unsigned long currentTime = millis();
for (size_t i = 0; i < tasks.size() && i < taskDefinitions.size(); ++i) { for (size_t i = 0; i < taskDefinitions.size(); ++i) {
Task* task = tasks[i]; auto& taskDef = taskDefinitions[i];
const std::string& taskName = taskDefinitions[i].name;
if (task->isEnabled()) { if (taskDef.enabled) {
// Check if it's time to run this task // Check if it's time to run this task
if (currentTime - lastExecutionTimes[i] >= task->getInterval()) { if (currentTime - lastExecutionTimes[i] >= taskDef.interval) {
// Execute the stored callback if (taskDef.callback) {
if (callbackRegistry.find(taskName) != callbackRegistry.end()) { taskDef.callback();
callbackRegistry[taskName]();
} }
// Update the last execution time // Update the last execution time
lastExecutionTimes[i] = currentTime; lastExecutionTimes[i] = currentTime;
} }
@@ -184,27 +131,26 @@ void TaskManager::execute() {
} }
} }
Task* TaskManager::findTask(const std::string& name) const { int TaskManager::findTaskIndex(const std::string& name) const {
for (size_t i = 0; i < tasks.size() && i < taskDefinitions.size(); ++i) { for (size_t i = 0; i < taskDefinitions.size(); ++i) {
if (taskDefinitions[i].name == name) { if (taskDefinitions[i].name == name) {
return tasks[i]; return static_cast<int>(i);
} }
} }
return nullptr; return -1;
} }
std::vector<std::pair<std::string, JsonObject>> TaskManager::getAllTaskStatuses(JsonDocument& doc) const { std::vector<std::pair<std::string, JsonObject>> TaskManager::getAllTaskStatuses(JsonDocument& doc) const {
std::vector<std::pair<std::string, JsonObject>> taskStatuses; std::vector<std::pair<std::string, JsonObject>> taskStatuses;
for (size_t i = 0; i < tasks.size() && i < taskDefinitions.size(); ++i) { for (size_t i = 0; i < taskDefinitions.size(); ++i) {
const auto& taskDef = taskDefinitions[i]; const auto& taskDef = taskDefinitions[i];
const auto& task = tasks[i];
JsonObject taskStatus = doc.add<JsonObject>(); JsonObject taskStatus = doc.add<JsonObject>();
taskStatus["name"] = taskDef.name; taskStatus["name"] = taskDef.name;
taskStatus["interval"] = task->getInterval(); taskStatus["interval"] = taskDef.interval;
taskStatus["enabled"] = task->isEnabled(); taskStatus["enabled"] = taskDef.enabled;
taskStatus["running"] = task->isEnabled(); // For now, enabled = running taskStatus["running"] = taskDef.enabled; // For now, enabled = running
taskStatus["autoStart"] = taskDef.autoStart; taskStatus["autoStart"] = taskDef.autoStart;
taskStatuses.push_back(std::make_pair(taskDef.name, taskStatus)); taskStatuses.push_back(std::make_pair(taskDef.name, taskStatus));