Make battery alert thresholds configurable
This commit is contained in:
1 parent
f693bdb212
commit
c93d907e85
4 files changed
+88
-8
No files matched your search
+10
-2
@@ -131,15 +131,23 @@ This document provides an overview of CLI commands that can be sent to MeshCore
|
||||
**Usage:**
|
||||
- `get battery.alert`
|
||||
- `set battery.alert <state>`
|
||||
- `get battery.alert.low`
|
||||
- `set battery.alert.low <percent>`
|
||||
- `get battery.alert.critical`
|
||||
- `set battery.alert.critical <percent>`
|
||||
|
||||
**Parameters:**
|
||||
- `state`: `on` (enable) or `off` (disable)
|
||||
- `percent`: Battery percentage threshold
|
||||
|
||||
**Default:** `off`
|
||||
|
||||
**Default thresholds:** `20` for `battery.alert.low`, `10` for `battery.alert.critical`
|
||||
|
||||
**Notes:**
|
||||
- When enabled, sends a `#repeaters` flood text warning if voltage is above `1 V` and the battery estimate is below `20%`.
|
||||
- Warnings repeat every `24` hours, or every `12` hours below `10%`.
|
||||
- When enabled, sends a `#repeaters` flood text warning if voltage is above `1 V` and the battery estimate is below `battery.alert.low`.
|
||||
- Warnings repeat every `24` hours, or every `12` hours below `battery.alert.critical`.
|
||||
- `battery.alert.critical` must be lower than `battery.alert.low`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -74,8 +74,8 @@
|
||||
#endif
|
||||
|
||||
#define LOW_BATTERY_MIN_VALID_MV 1000
|
||||
#define LOW_BATTERY_WARN_PERCENT 20
|
||||
#define LOW_BATTERY_CRITICAL_PERCENT 10
|
||||
#define LOW_BATTERY_WARN_PERCENT_DEFAULT 20
|
||||
#define LOW_BATTERY_CRITICAL_PERCENT_DEFAULT 10
|
||||
#define LOW_BATTERY_CHECK_INTERVAL (60UL * 1000UL)
|
||||
#define LOW_BATTERY_WARN_INTERVAL (24UL * 60UL * 60UL * 1000UL)
|
||||
#define LOW_BATTERY_CRITICAL_INTERVAL (12UL * 60UL * 60UL * 1000UL)
|
||||
@@ -584,6 +584,30 @@ static uint8_t batteryPercentFromMilliVolts(uint16_t batt_mv) {
|
||||
return (uint8_t)pct;
|
||||
}
|
||||
|
||||
static bool parseBatteryAlertPercent(const char* value, uint8_t min_value, uint8_t max_value, uint8_t& result) {
|
||||
if (value == NULL || *value == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t parsed = 0;
|
||||
while (*value) {
|
||||
if (*value < '0' || *value > '9') {
|
||||
return false;
|
||||
}
|
||||
parsed = (uint16_t)(parsed * 10 + (*value - '0'));
|
||||
if (parsed > max_value) {
|
||||
return false;
|
||||
}
|
||||
value++;
|
||||
}
|
||||
if (parsed < min_value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
result = (uint8_t)parsed;
|
||||
return true;
|
||||
}
|
||||
|
||||
mesh::Packet* MyMesh::createPacketCopy(const mesh::Packet* packet, const char* caller) {
|
||||
if (packet == NULL) return NULL;
|
||||
|
||||
@@ -2024,6 +2048,8 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
||||
_prefs.flood_retry_bridge_enabled = 0;
|
||||
_prefs.flood_retry_advert_enabled = 0;
|
||||
_prefs.battery_alert_enabled = 0;
|
||||
_prefs.battery_alert_low_percent = LOW_BATTERY_WARN_PERCENT_DEFAULT;
|
||||
_prefs.battery_alert_critical_percent = LOW_BATTERY_CRITICAL_PERCENT_DEFAULT;
|
||||
_prefs.direct_retry_cr4_snr_x4 = DIRECT_RETRY_CR4_MIN_SNR_X4_DEFAULT;
|
||||
_prefs.direct_retry_cr5_snr_x4 = DIRECT_RETRY_CR5_MIN_SNR_X4_DEFAULT;
|
||||
_prefs.direct_retry_cr7_snr_x4 = DIRECT_RETRY_CR7_MIN_SNR_X4_DEFAULT;
|
||||
@@ -2198,12 +2224,12 @@ void MyMesh::checkBatteryAlert() {
|
||||
|
||||
uint16_t batt_mv = board.getBattMilliVolts();
|
||||
uint8_t batt_pct = batteryPercentFromMilliVolts(batt_mv);
|
||||
if (batt_mv <= LOW_BATTERY_MIN_VALID_MV || batt_pct >= LOW_BATTERY_WARN_PERCENT) {
|
||||
if (batt_mv <= LOW_BATTERY_MIN_VALID_MV || batt_pct >= _prefs.battery_alert_low_percent) {
|
||||
battery_alert_sent = false;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long interval = batt_pct < LOW_BATTERY_CRITICAL_PERCENT
|
||||
unsigned long interval = batt_pct < _prefs.battery_alert_critical_percent
|
||||
? LOW_BATTERY_CRITICAL_INTERVAL
|
||||
: LOW_BATTERY_WARN_INTERVAL;
|
||||
if (battery_alert_sent && !millisHasNowPassed(last_battery_alert_sent + interval)) {
|
||||
@@ -2630,6 +2656,10 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, ClientInfo* sender, char *
|
||||
}
|
||||
} else if (strcmp(command, "get battery.alert") == 0) {
|
||||
sprintf(reply, "> %s", _prefs.battery_alert_enabled ? "on" : "off");
|
||||
} else if (strcmp(command, "get battery.alert.low") == 0) {
|
||||
sprintf(reply, "> %u", (uint32_t)_prefs.battery_alert_low_percent);
|
||||
} else if (strcmp(command, "get battery.alert.critical") == 0) {
|
||||
sprintf(reply, "> %u", (uint32_t)_prefs.battery_alert_critical_percent);
|
||||
} else if (strncmp(command, "set battery.alert ", 18) == 0) {
|
||||
const char* value = command + 18;
|
||||
if (strcmp(value, "on") == 0) {
|
||||
@@ -2645,6 +2675,30 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, ClientInfo* sender, char *
|
||||
} else {
|
||||
strcpy(reply, "Err - usage: set battery.alert <on|off>");
|
||||
}
|
||||
} else if (strncmp(command, "set battery.alert.low ", 22) == 0) {
|
||||
uint8_t percent;
|
||||
if (!parseBatteryAlertPercent(command + 22, 1, 100, percent)) {
|
||||
strcpy(reply, "Err - usage: set battery.alert.low <1-100>");
|
||||
} else if (percent <= _prefs.battery_alert_critical_percent) {
|
||||
strcpy(reply, "Err - low must be greater than critical");
|
||||
} else {
|
||||
_prefs.battery_alert_low_percent = percent;
|
||||
next_battery_alert_check = 0;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
}
|
||||
} else if (strncmp(command, "set battery.alert.critical ", 27) == 0) {
|
||||
uint8_t percent;
|
||||
if (!parseBatteryAlertPercent(command + 27, 0, 99, percent)) {
|
||||
strcpy(reply, "Err - usage: set battery.alert.critical <0-99>");
|
||||
} else if (percent >= _prefs.battery_alert_low_percent) {
|
||||
strcpy(reply, "Err - critical must be less than low");
|
||||
} else {
|
||||
_prefs.battery_alert_critical_percent = percent;
|
||||
next_battery_alert_check = 0;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
}
|
||||
} else if (strncmp(command, "get recent.repeater", 19) == 0
|
||||
|| strncmp(command, "set recent.repeater", 19) == 0
|
||||
|| strncmp(command, "clear recent.repeater", 21) == 0
|
||||
|
||||
@@ -559,6 +559,12 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
_prefs->battery_alert_enabled = 0;
|
||||
size_t battery_alert_read = file.read((uint8_t *)&_prefs->battery_alert_enabled,
|
||||
sizeof(_prefs->battery_alert_enabled)); // 664
|
||||
_prefs->battery_alert_low_percent = 20;
|
||||
_prefs->battery_alert_critical_percent = 10;
|
||||
size_t battery_alert_low_read = file.read((uint8_t *)&_prefs->battery_alert_low_percent,
|
||||
sizeof(_prefs->battery_alert_low_percent)); // 665
|
||||
size_t battery_alert_critical_read = file.read((uint8_t *)&_prefs->battery_alert_critical_percent,
|
||||
sizeof(_prefs->battery_alert_critical_percent)); // 666
|
||||
// PowerSaving-only prefs stored radio_fem_rxgain at 291, before direct retry timing existed.
|
||||
if (radio_fem_rxgain_read != sizeof(_prefs->radio_fem_rxgain)
|
||||
&& legacy_retry_attempts_read == sizeof(legacy_retry_attempts_or_radio_fem_rxgain)
|
||||
@@ -566,7 +572,7 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
|| _prefs->direct_retry_timing_magic[1] != DIRECT_RETRY_TIMING_MAGIC_1)) {
|
||||
_prefs->radio_fem_rxgain = constrain(legacy_retry_attempts_or_radio_fem_rxgain, 0, 1);
|
||||
}
|
||||
// next: 664
|
||||
// next: 667
|
||||
|
||||
// sanitise bad pref values
|
||||
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f);
|
||||
@@ -662,6 +668,14 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
} else {
|
||||
_prefs->battery_alert_enabled = constrain(_prefs->battery_alert_enabled, 0, 1);
|
||||
}
|
||||
if (battery_alert_low_read != sizeof(_prefs->battery_alert_low_percent)
|
||||
|| battery_alert_critical_read != sizeof(_prefs->battery_alert_critical_percent)
|
||||
|| _prefs->battery_alert_low_percent < 1
|
||||
|| _prefs->battery_alert_low_percent > 100
|
||||
|| _prefs->battery_alert_critical_percent >= _prefs->battery_alert_low_percent) {
|
||||
_prefs->battery_alert_low_percent = 20;
|
||||
_prefs->battery_alert_critical_percent = 10;
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
@@ -748,7 +762,9 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
|
||||
file.write((uint8_t *)&_prefs->direct_retry_cr7_snr_x4, sizeof(_prefs->direct_retry_cr7_snr_x4)); // 662
|
||||
file.write((uint8_t *)&_prefs->direct_retry_cr8_snr_x4, sizeof(_prefs->direct_retry_cr8_snr_x4)); // 663
|
||||
file.write((uint8_t *)&_prefs->battery_alert_enabled, sizeof(_prefs->battery_alert_enabled)); // 664
|
||||
// next: 665
|
||||
file.write((uint8_t *)&_prefs->battery_alert_low_percent, sizeof(_prefs->battery_alert_low_percent)); // 665
|
||||
file.write((uint8_t *)&_prefs->battery_alert_critical_percent, sizeof(_prefs->battery_alert_critical_percent)); // 666
|
||||
// next: 667
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
@@ -133,6 +133,8 @@ struct NodePrefs { // persisted to file
|
||||
int8_t direct_retry_cr7_snr_x4;
|
||||
int8_t direct_retry_cr8_snr_x4;
|
||||
uint8_t battery_alert_enabled;
|
||||
uint8_t battery_alert_low_percent;
|
||||
uint8_t battery_alert_critical_percent;
|
||||
};
|
||||
|
||||
class CommonCLICallbacks {
|
||||
|
||||
Reference in new issue
Block a user