CommandMgr: wifi/sleep/periods/ota handlers; integrate OTAMgr check at boot; WiFi home flag flow
This commit is contained in:
@ -43,6 +43,17 @@ void setup() {
|
|||||||
|
|
||||||
// GNSS power on (if applicable later)
|
// GNSS power on (if applicable later)
|
||||||
NetMgr::sendAT("AT+CGNSPWR=1", 2000);
|
NetMgr::sendAT("AT+CGNSPWR=1", 2000);
|
||||||
|
|
||||||
|
OTAMgr::setCurrentVersion(FW_VERSION);
|
||||||
|
String ver, url, sha;
|
||||||
|
if (OTAMgr::check(CFG.baseUrl, CFG.imei, ver, url, sha)) {
|
||||||
|
Serial.println("OTA available: " + ver + " -> " + url);
|
||||||
|
// Optionally apply now:
|
||||||
|
// OTAMgr::apply(url, sha);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "CommandMgr.hpp"
|
#include "CommandMgr.hpp"
|
||||||
#include "HttpClient.hpp"
|
#include "HttpClient.hpp"
|
||||||
#include "AppConfig.hpp"
|
#include "AppConfig.hpp"
|
||||||
|
#include "OTAMgr.hpp"
|
||||||
extern AppConfig CFG;
|
extern AppConfig CFG;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -13,6 +14,41 @@ namespace
|
|||||||
// Extract array of objects from a JSON string like: [{"id":..,"type":"..","payload":{...}}, ...]
|
// Extract array of objects from a JSON string like: [{"id":..,"type":"..","payload":{...}}, ...]
|
||||||
// We’ll do a naive split on "},{" for small payloads; replace with proper JSON parsing later.
|
// We’ll do a naive split on "},{" for small payloads; replace with proper JSON parsing later.
|
||||||
|
|
||||||
|
static int pickInt(const String &j, const char *key)
|
||||||
|
{
|
||||||
|
String pat = String("\"") + key + "\":";
|
||||||
|
int k = j.indexOf(pat);
|
||||||
|
if (k < 0)
|
||||||
|
return -1;
|
||||||
|
k += pat.length();
|
||||||
|
while (k < (int)j.length() && (j[k] == ' ' || j[k] == ':'))
|
||||||
|
k++;
|
||||||
|
int i = k;
|
||||||
|
while (i < (int)j.length() && isDigit(j[i]))
|
||||||
|
i++;
|
||||||
|
if (i <= k)
|
||||||
|
return -1;
|
||||||
|
return j.substring(k, i).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
static String pickStr(const String &j, const char *key)
|
||||||
|
{
|
||||||
|
String pat = String("\"") + key + "\":";
|
||||||
|
int k = j.indexOf(pat);
|
||||||
|
if (k < 0)
|
||||||
|
return "";
|
||||||
|
k += pat.length();
|
||||||
|
while (k < (int)j.length() && (j[k] == ' ' || j[k] == '\"' || j[k] == ':'))
|
||||||
|
k++;
|
||||||
|
if (k > 0 && j[k - 1] == '\"')
|
||||||
|
{
|
||||||
|
int e = j.indexOf('\"', k);
|
||||||
|
if (e > k)
|
||||||
|
return j.substring(k, e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
long extractId(const String &obj)
|
long extractId(const String &obj)
|
||||||
{
|
{
|
||||||
String pat = "\"id\":";
|
String pat = "\"id\":";
|
||||||
@ -248,11 +284,68 @@ namespace CommandMgr
|
|||||||
}
|
}
|
||||||
else if (c.type == "ota")
|
else if (c.type == "ota")
|
||||||
{
|
{
|
||||||
String url = /* parse from payload */;
|
|
||||||
String sha = /* parse if provided */;
|
String url = pickStr(c.payload, "url");
|
||||||
|
String sha = pickStr(c.payload, "sha256");
|
||||||
|
if (!url.length())
|
||||||
|
{
|
||||||
|
execOk = false;
|
||||||
|
detail = "missing url";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
execOk = OTAMgr::apply(url, sha);
|
execOk = OTAMgr::apply(url, sha);
|
||||||
detail = execOk ? "ota applied" : "ota failed";
|
detail = execOk ? "ota applied" : "ota failed";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (c.type == "telemetry_sec")
|
||||||
|
{
|
||||||
|
int sec = pickInt(c.payload, "telemetry_sec");
|
||||||
|
if (sec > 0)
|
||||||
|
{
|
||||||
|
CFG.telemetryPeriodSec = (uint32_t)sec;
|
||||||
|
Serial.printf("Telemetry sec set to %u\n", CFG.telemetryPeriodSec);
|
||||||
|
execOk = true;
|
||||||
|
detail = "telemetry updated";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
execOk = false;
|
||||||
|
detail = "bad telemetry_sec";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c.type == "poll_sec")
|
||||||
|
{
|
||||||
|
int sec = pickInt(c.payload, "poll_sec");
|
||||||
|
if (sec > 0)
|
||||||
|
{
|
||||||
|
CFG.commandPollSec = (uint32_t)sec;
|
||||||
|
Serial.printf("Poll sec set to %u\n", CFG.commandPollSec);
|
||||||
|
execOk = true;
|
||||||
|
detail = "poll updated";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
execOk = false;
|
||||||
|
detail = "bad poll_sec";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c.type == "wifi")
|
||||||
|
{
|
||||||
|
String tgt = pickStr(c.payload, "target");
|
||||||
|
if (tgt.equalsIgnoreCase("home"))
|
||||||
|
{
|
||||||
|
CFG.atHomeRequested = true;
|
||||||
|
Serial.println("WiFi home connect requested");
|
||||||
|
execOk = true;
|
||||||
|
detail = "wifi home requested";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
execOk = false;
|
||||||
|
detail = "unknown wifi target";
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
execOk = true; // unknown; mark ok but do nothing
|
execOk = true; // unknown; mark ok but do nothing
|
||||||
@ -274,6 +367,15 @@ namespace CommandMgr
|
|||||||
|
|
||||||
bool handleSleep(const String &payload)
|
bool handleSleep(const String &payload)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
int sec = pickInt(payload, "interval_sec");
|
||||||
|
if (sec > 0)
|
||||||
|
{
|
||||||
|
CFG.sleepSec = (uint32_t)sec;
|
||||||
|
Serial.printf("Sleep sec set to %u\n", CFG.sleepSec);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: parse {"interval_sec":120}
|
// TODO: parse {"interval_sec":120}
|
||||||
Serial.println("handleSleep payload: " + payload);
|
Serial.println("handleSleep payload: " + payload);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user