|
20 | 20 | #include <Arduino.h> |
21 | 21 | #include <Wire.h> |
22 | 22 | #include <ArduinoJson.h> |
23 | | -#include <LittleFS.h> |
24 | 23 | #include <Notecard.h> |
25 | 24 | #include <Ethernet.h> |
| 25 | +#include <LittleFS.h> |
26 | 26 | #include <math.h> |
27 | 27 | #include <string.h> |
28 | 28 | #include <ctype.h> |
|
39 | 39 |
|
40 | 40 | // Watchdog support for STM32H7 (Arduino Opta) |
41 | 41 | #if defined(ARDUINO_OPTA) || defined(STM32H7xx) |
| 42 | + |
42 | 43 | #include <IWatchdog.h> |
43 | 44 | #define WATCHDOG_AVAILABLE |
44 | 45 | #define WATCHDOG_TIMEOUT_SECONDS 30 |
@@ -197,8 +198,9 @@ static unsigned long gLastPollMillis = 0; |
197 | 198 | static double gLastDailyEmailSentEpoch = 0.0; |
198 | 199 | #define MIN_DAILY_EMAIL_INTERVAL_SECONDS 3600 // Minimum 1 hour between daily emails |
199 | 200 |
|
200 | | -#ifndef strlcpy |
201 | | -static size_t strlcpy(char *dst, const char *src, size_t size) { |
| 201 | +#ifndef ARDUINO_TANKALARM_HAS_STRLCPY |
| 202 | +#define ARDUINO_TANKALARM_HAS_STRLCPY |
| 203 | +size_t strlcpy(char *dst, const char *src, size_t size) { |
202 | 204 | if (!dst || !src || size == 0) { |
203 | 205 | return 0; |
204 | 206 | } |
@@ -2540,6 +2542,22 @@ static void sendClientDataJson(EthernetClient &client); |
2540 | 2542 | static void handleConfigPost(EthernetClient &client, const String &body); |
2541 | 2543 | static void handlePinPost(EthernetClient &client, const String &body); |
2542 | 2544 | static void handleRefreshPost(EthernetClient &client, const String &body); |
| 2545 | +static ConfigDispatchStatus dispatchClientConfig(const char *clientUid, JsonVariantConst cfgObj); |
| 2546 | +static void pollNotecard(); |
| 2547 | +static void processNotefile(const char *fileName, void (*handler)(JsonDocument &, double)); |
| 2548 | +static void handleTelemetry(JsonDocument &doc, double epoch); |
| 2549 | +static void handleAlarm(JsonDocument &doc, double epoch); |
| 2550 | +static void handleDaily(JsonDocument &doc, double epoch); |
| 2551 | +static TankRecord *upsertTankRecord(const char *clientUid, uint8_t tankNumber); |
| 2552 | +static void sendSmsAlert(const char *message); |
| 2553 | +static void sendDailyEmail(); |
| 2554 | +static void loadClientConfigSnapshots(); |
| 2555 | +static void saveClientConfigSnapshots(); |
| 2556 | +static void cacheClientConfigFromBuffer(const char *clientUid, const char *buffer); |
| 2557 | +static ClientConfigSnapshot *findClientConfigSnapshot(const char *clientUid); |
| 2558 | +static bool checkSmsRateLimit(TankRecord *rec); |
| 2559 | +static void publishViewerSummary(); |
| 2560 | +static double computeNextAlignedEpoch(double epoch, uint8_t baseHour, uint32_t intervalSeconds); |
2543 | 2561 | enum class ConfigDispatchStatus : uint8_t { |
2544 | 2562 | Ok = 0, |
2545 | 2563 | PayloadTooLarge, |
@@ -2568,22 +2586,6 @@ static void handleRefreshPost(EthernetClient &client, const String &body) { |
2568 | 2586 | pollNotecard(); |
2569 | 2587 | sendClientDataJson(client); |
2570 | 2588 | } |
2571 | | -static ConfigDispatchStatus dispatchClientConfig(const char *clientUid, JsonVariantConst cfgObj); |
2572 | | -static void pollNotecard(); |
2573 | | -static void processNotefile(const char *fileName, void (*handler)(JsonDocument &, double)); |
2574 | | -static void handleTelemetry(JsonDocument &doc, double epoch); |
2575 | | -static void handleAlarm(JsonDocument &doc, double epoch); |
2576 | | -static void handleDaily(JsonDocument &doc, double epoch); |
2577 | | -static TankRecord *upsertTankRecord(const char *clientUid, uint8_t tankNumber); |
2578 | | -static void sendSmsAlert(const char *message); |
2579 | | -static void sendDailyEmail(); |
2580 | | -static void loadClientConfigSnapshots(); |
2581 | | -static void saveClientConfigSnapshots(); |
2582 | | -static void cacheClientConfigFromBuffer(const char *clientUid, const char *buffer); |
2583 | | -static ClientConfigSnapshot *findClientConfigSnapshot(const char *clientUid); |
2584 | | -static bool checkSmsRateLimit(TankRecord *rec); |
2585 | | -static void publishViewerSummary(); |
2586 | | -static double computeNextAlignedEpoch(double epoch, uint8_t baseHour, uint32_t intervalSeconds); |
2587 | 2589 |
|
2588 | 2590 | void setup() { |
2589 | 2591 | Serial.begin(115200); |
@@ -3057,7 +3059,11 @@ static void respondHtml(EthernetClient &client, const String &body) { |
3057 | 3059 | static void respondJson(EthernetClient &client, const String &body, int status) { |
3058 | 3060 | client.print(F("HTTP/1.1 ")); |
3059 | 3061 | client.print(status); |
3060 | | - client.println(status == 200 ? F(" OK") : ""); |
| 3062 | + if (status == 200) { |
| 3063 | + client.println(F(" OK")); |
| 3064 | + } else { |
| 3065 | + client.println(); |
| 3066 | + } |
3061 | 3067 | client.println(F("Content-Type: application/json")); |
3062 | 3068 | client.print(F("Content-Length: ")); |
3063 | 3069 | client.println(body.length()); |
@@ -3396,7 +3402,6 @@ static ConfigDispatchStatus dispatchClientConfig(const char *clientUid, JsonVari |
3396 | 3402 |
|
3397 | 3403 | J *body = JParse(buffer); |
3398 | 3404 | if (!body) { |
3399 | | - notecard.deleteRequest(req); |
3400 | 3405 | return ConfigDispatchStatus::PayloadTooLarge; |
3401 | 3406 | } |
3402 | 3407 | JAddItemToObject(req, "body", body); |
@@ -3438,7 +3443,7 @@ static void processNotefile(const char *fileName, void (*handler)(JsonDocument & |
3438 | 3443 | break; |
3439 | 3444 | } |
3440 | 3445 |
|
3441 | | - char *json = JConvertToJson(body); |
| 3446 | + char *json = JConvertToJSONString(body); |
3442 | 3447 | double epoch = JGetNumber(rsp, "time"); |
3443 | 3448 | if (json) { |
3444 | 3449 | DynamicJsonDocument doc(4096); |
@@ -3635,7 +3640,6 @@ static void sendSmsAlert(const char *message) { |
3635 | 3640 | JAddBoolToObject(req, "sync", true); |
3636 | 3641 | J *body = JParse(buffer); |
3637 | 3642 | if (!body) { |
3638 | | - notecard.deleteRequest(req); |
3639 | 3643 | return; |
3640 | 3644 | } |
3641 | 3645 | JAddItemToObject(req, "body", body); |
@@ -3691,7 +3695,6 @@ static void sendDailyEmail() { |
3691 | 3695 | JAddBoolToObject(req, "sync", true); |
3692 | 3696 | J *body = JParse(buffer); |
3693 | 3697 | if (!body) { |
3694 | | - notecard.deleteRequest(req); |
3695 | 3698 | return; |
3696 | 3699 | } |
3697 | 3700 | JAddItemToObject(req, "body", body); |
@@ -3738,7 +3741,6 @@ static void publishViewerSummary() { |
3738 | 3741 | JAddBoolToObject(req, "sync", true); |
3739 | 3742 | J *body = JParse(json.c_str()); |
3740 | 3743 | if (!body) { |
3741 | | - notecard.deleteRequest(req); |
3742 | 3744 | Serial.println(F("Viewer summary JSON parse failed")); |
3743 | 3745 | return; |
3744 | 3746 | } |
|
0 commit comments