Skip to content

Commit a9cdc14

Browse files
Copilotdorkmo
andcommitted
Implement solar power saving features and deep sleep
Co-authored-by: dorkmo <[email protected]>
1 parent 3e5915a commit a9cdc14

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

TankAlarm-112025-Client-BluesOpta/TankAlarm-112025-Client-BluesOpta.ino

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ struct ClientConfig {
358358
// Optional clear button configuration
359359
int8_t clearButtonPin; // Pin for physical clear button (-1 = disabled)
360360
bool clearButtonActiveHigh; // true = button active when HIGH, false = active when LOW (with pullup)
361+
// Power saving configuration
362+
bool solarPowered; // true = solar powered (use power saving features), false = grid-tied
361363
};
362364

363365
struct TankRuntime {
@@ -658,7 +660,12 @@ void loop() {
658660
}
659661

660662
// Sleep to reduce power consumption between loop iterations
661-
delay(100);
663+
// Use Mbed OS deep sleep for better power efficiency (reduces idle current significantly)
664+
#if defined(ARDUINO_OPTA) || defined(ARDUINO_ARCH_MBED)
665+
ThisThread::sleep_for(100ms); // Deep sleep for 100ms - CPU enters low-power state
666+
#else
667+
delay(100); // Fallback for non-Mbed platforms
668+
#endif
662669
}
663670

664671
static void initializeStorage() {
@@ -767,6 +774,9 @@ static void createDefaultConfig(ClientConfig &cfg) {
767774
// Clear button defaults (disabled)
768775
cfg.clearButtonPin = -1; // -1 = disabled
769776
cfg.clearButtonActiveHigh = false; // Active LOW with pullup (button connects to GND)
777+
778+
// Power saving defaults (grid-tied, no special power saving)
779+
cfg.solarPowered = false; // false = grid-tied (default)
770780
}
771781

772782
static bool loadConfigFromFlash(ClientConfig &cfg) {
@@ -842,6 +852,9 @@ static bool loadConfigFromFlash(ClientConfig &cfg) {
842852
// Load clear button configuration
843853
cfg.clearButtonPin = doc["clearButtonPin"].is<int>() ? doc["clearButtonPin"].as<int8_t>() : -1;
844854
cfg.clearButtonActiveHigh = doc["clearButtonActiveHigh"].is<bool>() ? doc["clearButtonActiveHigh"].as<bool>() : false;
855+
856+
// Load power saving configuration
857+
cfg.solarPowered = doc["solarPowered"].is<bool>() ? doc["solarPowered"].as<bool>() : false;
845858

846859
cfg.tankCount = doc["tanks"].is<JsonArray>() ? min<uint8_t>(doc["tanks"].size(), MAX_TANKS) : 0;
847860

@@ -978,6 +991,9 @@ static bool saveConfigToFlash(const ClientConfig &cfg) {
978991
// Save clear button configuration
979992
doc["clearButtonPin"] = cfg.clearButtonPin;
980993
doc["clearButtonActiveHigh"] = cfg.clearButtonActiveHigh;
994+
995+
// Save power saving configuration
996+
doc["solarPowered"] = cfg.solarPowered;
981997

982998
JsonArray tanks = doc.createNestedArray("tanks");
983999
for (uint8_t i = 0; i < cfg.tankCount; ++i) {
@@ -1176,9 +1192,19 @@ static void initializeNotecard() {
11761192
req = notecard.newRequest("hub.set");
11771193
if (req) {
11781194
JAddStringToObject(req, "product", PRODUCT_UID);
1179-
JAddStringToObject(req, "mode", "periodic");
1180-
JAddIntToObject(req, "outbound", 360); // Sync every 6 hours
1181-
JAddIntToObject(req, "inbound", 10); // Check for inbound every 10 minutes
1195+
1196+
// Power saving configuration based on power source
1197+
if (gConfig.solarPowered) {
1198+
// Solar powered: Use periodic mode with extended inbound check to save power
1199+
JAddStringToObject(req, "mode", "periodic");
1200+
JAddIntToObject(req, "outbound", 360); // Sync every 6 hours
1201+
JAddIntToObject(req, "inbound", 60); // Check for inbound every 60 minutes (power saving)
1202+
} else {
1203+
// Grid-tied: Use continuous mode for faster response times
1204+
JAddStringToObject(req, "mode", "continuous");
1205+
// In continuous mode, outbound/inbound are not used - always connected
1206+
}
1207+
11821208
// No route needed - using fleet-based targeting
11831209
notecard.sendRequest(req);
11841210
}
@@ -1435,6 +1461,15 @@ static void applyConfigUpdate(const JsonDocument &doc) {
14351461
if (doc.containsKey("clearButtonActiveHigh")) {
14361462
gConfig.clearButtonActiveHigh = doc["clearButtonActiveHigh"].as<bool>();
14371463
}
1464+
1465+
// Handle power saving configuration
1466+
if (doc.containsKey("solarPowered")) {
1467+
bool newSolarPowered = doc["solarPowered"].as<bool>();
1468+
if (newSolarPowered != gConfig.solarPowered) {
1469+
gConfig.solarPowered = newSolarPowered;
1470+
hardwareChanged = true; // Need to reconfigure Notecard hub settings
1471+
}
1472+
}
14381473

14391474
if (doc.containsKey("tanks")) {
14401475
hardwareChanged = true; // Tank configuration affects hardware

TankAlarm-112025-Server-BluesOpta/TankAlarm-112025-Server-BluesOpta.ino

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,14 @@ static const char CONFIG_GENERATOR_HTML[] PROGMEM = R"HTML(
748748
<label class="field"><span>Daily Report Email Recipient</span><input id="dailyEmail" type="email"></label>
749749
</div>
750750
751+
<h3>Power Configuration</h3>
752+
<div class="form-grid">
753+
<label class="field" style="display: flex; align-items: center; gap: 8px; grid-column: 1 / -1;">
754+
<input type="checkbox" id="solarPowered" style="width: auto;">
755+
<span>Solar Powered<span class="tooltip-icon" tabindex="0" data-tooltip="Enable power saving features for solar-powered installations. Uses periodic mode with 60-minute inbound check intervals and deep sleep routines. When disabled (grid-tied), uses continuous mode for faster response times.">?</span></span>
756+
</label>
757+
</div>
758+
751759
<h3>Sensors</h3>
752760
<div id="sensorsContainer"></div>
753761
@@ -1394,6 +1402,7 @@ static const char CONFIG_GENERATOR_HTML[] PROGMEM = R"HTML(
13941402
reportHour: reportHour,
13951403
reportMinute: reportMinute,
13961404
dailyEmail: document.getElementById('dailyEmail').value.trim(),
1405+
solarPowered: document.getElementById('solarPowered').checked,
13971406
tanks: []
13981407
};
13991408

0 commit comments

Comments
 (0)