119 lines
3.3 KiB
C++
119 lines
3.3 KiB
C++
#include "src/core/NetMgr.hpp"
|
||
#include "src/core/HttpClient.hpp"
|
||
#include "src/core/SmsMgr.hpp"
|
||
#include "src/core/CommandMgr.hpp"
|
||
#include "src/core/Telemetry.hpp"
|
||
#include "src/app/AppConfig.hpp"
|
||
#include "src/hw/PowerMgr.hpp"
|
||
#include "src/hw/WiFiMgr.hpp"
|
||
#include "src/core/OTAMgr.hpp"
|
||
|
||
|
||
|
||
#define FW_VERSION "1.0.0"
|
||
|
||
AppConfig CFG;
|
||
|
||
static String queryImei() {
|
||
String r = NetMgr::sendAT("AT+CGSN", 3000);
|
||
int s = -1;
|
||
for (int i = 0; i < (int)r.length() - 14; ++i) { if (isDigit(r[i])) { s = i; break; } }
|
||
if (s >= 0) { String imei = r.substring(s, s + 15); imei.trim(); return imei; }
|
||
return "";
|
||
}
|
||
|
||
void setup() {
|
||
Serial.begin(115200);
|
||
Serial2.begin(9600, SERIAL_8N1, 16, 17);
|
||
|
||
// 1) Radio attach
|
||
NetMgr::powerOnSIM7080(4);
|
||
NetMgr::attachAndPdp(CFG.apn.c_str());
|
||
SmsMgr::setup();
|
||
|
||
OTAMgr::setCurrentVersion(FW_VERSION);
|
||
|
||
// 2) Identity
|
||
CFG.imei = queryImei();
|
||
if (CFG.imei.isEmpty()) CFG.imei = "860016049744324";
|
||
|
||
// 3) Init power sim
|
||
PowerMgr::init(true); // car power ON initially (simulate)
|
||
|
||
// 4) Command manager config
|
||
CommandMgr::configure(CFG.baseUrl, CFG.imei);
|
||
|
||
// GNSS power on (if applicable later)
|
||
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() {
|
||
static uint32_t lastTelemetryMs = 0;
|
||
static uint32_t lastPollMs = 0;
|
||
static bool noPowerSent = false;
|
||
|
||
SmsMgr::pollUrc(); // SMS commands
|
||
|
||
bool carOn = PowerMgr::isCarPowerOn();
|
||
|
||
// When car power is ON
|
||
if (carOn) {
|
||
noPowerSent = false; // reset for next OFF cycle
|
||
|
||
// Telemetry every A seconds
|
||
if (millis() - lastTelemetryMs >= CFG.telemetryPeriodSec * 1000UL) {
|
||
double lat, lng, alt, spd, hdg;
|
||
Telemetry::readGNSS(lat, lng, alt, spd, hdg);
|
||
String json = Telemetry::buildJson(CFG.imei, lat, lng, alt, spd, hdg, carOn);
|
||
HttpClient::postJson(CFG.baseUrl, CFG.telemetryPath, json);
|
||
lastTelemetryMs = millis();
|
||
}
|
||
|
||
// Poll commands every B seconds
|
||
if (millis() - lastPollMs >= CFG.commandPollSec * 1000UL) {
|
||
CommandMgr::poll(CFG.commandPollSec * 1000UL); // uses its own timer, but call to force
|
||
lastPollMs = millis();
|
||
}
|
||
}
|
||
// When car power is OFF
|
||
else {
|
||
if (!noPowerSent) {
|
||
String np = Telemetry::buildNoPowerJson(CFG.imei);
|
||
HttpClient::postJson(CFG.baseUrl, CFG.telemetryPath, np);
|
||
noPowerSent = true;
|
||
}
|
||
|
||
// One last command poll to check instructions (e.g., connect Wi‑Fi, sleep C seconds)
|
||
CommandMgr::poll(0);
|
||
|
||
// Placeholder: if server requested home Wi‑Fi, connect
|
||
if (CFG.atHomeRequested) {
|
||
bool ok = WiFiMgr::connectHome("Aussie Broadband 8729", "Ffdfmunfca", 15000);
|
||
Serial.println(ok ? "Home WiFi connected" : "Home WiFi failed");
|
||
if (ok) {
|
||
// You can add local/LAN interactions here; then disconnect:
|
||
WiFiMgr::disconnect();
|
||
}
|
||
CFG.atHomeRequested = false;
|
||
}
|
||
|
||
// Go to deep sleep (placeholder – currently just delay)
|
||
PowerMgr::deepSleep(CFG.sleepSec);
|
||
delay(CFG.sleepSec * 1000UL);
|
||
// On real deep sleep, code resumes at setup() on wake
|
||
// If simulating, continue loop
|
||
}
|
||
|
||
delay(100);
|
||
} |