Merge pull request #45 from xJARiD/develop
fix: reduce repeater battery polling
This commit is contained in:
+1
-2
@@ -86,8 +86,7 @@ Legacy dotted aliases are also accepted:
|
||||
|
||||
### Board Battery Reporting
|
||||
|
||||
- `get battery.reporting`: shows whether board battery reporting is enabled. Support is board-dependent.
|
||||
- `set battery.reporting on|off`: enables or disables battery voltage reporting on supported boards. This is currently useful for Heltec V3 boards where USB-only power can produce misleading battery readings. If your board needs this too, open an issue and support can be added board-by-board.
|
||||
- On repeater MQTT builds, background battery sampling used for MQTT/status history is rate-limited to about once per minute. Explicit status and telemetry requests still refresh the reading immediately.
|
||||
|
||||
### T-Beam 1W Fan Control
|
||||
|
||||
|
||||
@@ -165,6 +165,30 @@ Notes:
|
||||
- the refresh buttons load the current value from the repeater
|
||||
- the save buttons send the matching CLI command immediately
|
||||
|
||||
## Ghost Node Mode
|
||||
|
||||
Ghost Node Mode is a convenience control on `/app` for a repeater that should stay on Wi-Fi and MQTT, but should not actively behave like another nearby repeater.
|
||||
|
||||
Typical use case:
|
||||
|
||||
- an indoor or colocated MQTT observer where another repeater nearby is already doing the RF relay work
|
||||
- a node you want feeding MQTT, web status, and troubleshooting data without also adding extra repeat traffic or adverts
|
||||
|
||||
When enabled, Ghost Node Mode:
|
||||
|
||||
- turns `repeat` off
|
||||
- sets `advert.interval` to `0`
|
||||
- sets `flood.advert.interval` to `0`
|
||||
- leaves the local web panel and MQTT features running
|
||||
|
||||
When disabled, the panel restores the prior repeat and advert settings if it still knows them from the current browser session. If not, it falls back to:
|
||||
|
||||
- `repeat on`
|
||||
- `advert.interval 60`
|
||||
- `flood.advert.interval 12`
|
||||
|
||||
This mode is useful when you want the device to observe and publish, not to act as an additional RF repeater. It does not create a separate firmware role; it is just a grouped web-panel shortcut for those existing settings.
|
||||
|
||||
## MQTT Settings
|
||||
|
||||
This section includes:
|
||||
|
||||
@@ -28,44 +28,14 @@
|
||||
|
||||
namespace {
|
||||
|
||||
struct WebSensorSnapshot {
|
||||
bool has_supply_voltage = false;
|
||||
float supply_voltage_v = NAN;
|
||||
|
||||
bool has_sensor_temp = false;
|
||||
float sensor_temp_c = NAN;
|
||||
|
||||
bool has_mcu_temp = false;
|
||||
float mcu_temp_c = NAN;
|
||||
|
||||
bool has_humidity = false;
|
||||
float humidity_pct = NAN;
|
||||
|
||||
bool has_pressure = false;
|
||||
float pressure_hpa = NAN;
|
||||
|
||||
bool has_pressure_altitude = false;
|
||||
float pressure_altitude_m = NAN;
|
||||
|
||||
bool has_gps = false;
|
||||
bool gps_enabled = false;
|
||||
bool gps_fix = false;
|
||||
bool has_gps_lat = false;
|
||||
float gps_lat = NAN;
|
||||
bool has_gps_lon = false;
|
||||
float gps_lon = NAN;
|
||||
bool has_gps_altitude = false;
|
||||
float gps_altitude_m = NAN;
|
||||
bool has_satellites = false;
|
||||
long satellites = 0;
|
||||
};
|
||||
|
||||
WebSensorSnapshot collectWebSensorSnapshot(mesh::MainBoard& board, SensorManager& sensors) {
|
||||
WebSensorSnapshot collectWebSensorSnapshot(mesh::MainBoard& board, SensorManager& sensors, uint16_t battery_mv) {
|
||||
WebSensorSnapshot snapshot;
|
||||
snapshot.has_battery = true;
|
||||
snapshot.battery_mv = battery_mv;
|
||||
|
||||
CayenneLPP sensor_telemetry(200);
|
||||
sensor_telemetry.reset();
|
||||
sensor_telemetry.addVoltage(TELEM_CHANNEL_SELF, static_cast<float>(board.getBattMilliVolts()) / 1000.0f);
|
||||
sensor_telemetry.addVoltage(TELEM_CHANNEL_SELF, static_cast<float>(battery_mv) / 1000.0f);
|
||||
sensors.querySensors(0xFF, sensor_telemetry);
|
||||
|
||||
const float board_temp_c = board.getMCUTemperature();
|
||||
@@ -567,7 +537,7 @@ int MyMesh::handleRequest(ClientInfo *sender, uint32_t sender_timestamp, uint8_t
|
||||
|
||||
if (payload[0] == REQ_TYPE_GET_STATUS) { // guests can also access this now
|
||||
RepeaterStats stats;
|
||||
stats.batt_milli_volts = board.getBattMilliVolts();
|
||||
stats.batt_milli_volts = getBatteryMilliVolts(true);
|
||||
stats.curr_tx_queue_len = _mgr->getOutboundTotal();
|
||||
stats.noise_floor = (int16_t)_radio->getNoiseFloor();
|
||||
stats.last_rssi = (int16_t)radio_driver.getLastRSSI();
|
||||
@@ -593,7 +563,7 @@ int MyMesh::handleRequest(ClientInfo *sender, uint32_t sender_timestamp, uint8_t
|
||||
uint8_t perm_mask = ~(payload[1]); // NEW: first reserved byte (of 4), is now inverse mask to apply to permissions
|
||||
|
||||
telemetry.reset();
|
||||
telemetry.addVoltage(TELEM_CHANNEL_SELF, (float)board.getBattMilliVolts() / 1000.0f);
|
||||
telemetry.addVoltage(TELEM_CHANNEL_SELF, (float)getBatteryMilliVolts(true) / 1000.0f);
|
||||
|
||||
// query other sensors -- target specific
|
||||
if ((sender->permissions & PERM_ACL_ROLE_MASK) == PERM_ACL_GUEST) {
|
||||
@@ -1219,12 +1189,15 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
||||
_archive = nullptr;
|
||||
uptime_millis = 0;
|
||||
next_archive_neighbours_flush_ms = 0;
|
||||
next_battery_sample_ms = 0;
|
||||
next_history_sample_ms = 0;
|
||||
next_local_advert = next_flood_advert = 0;
|
||||
dirty_contacts_expiry = 0;
|
||||
set_radio_at = revert_radio_at = 0;
|
||||
_logging = false;
|
||||
_archive_neighbours_dirty = false;
|
||||
_battery_sample_valid = false;
|
||||
_battery_mv_cache = 0;
|
||||
region_load_active = false;
|
||||
memset(&_stats_state, 0, sizeof(_stats_state));
|
||||
|
||||
@@ -1267,7 +1240,7 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
||||
_prefs.advert_loc_policy = ADVERT_LOC_PREFS;
|
||||
|
||||
_prefs.adc_multiplier = 0.0f; // 0.0f means use default board multiplier
|
||||
_prefs.battery_reporting_enabled = 1;
|
||||
_prefs.reserved_290 = 0;
|
||||
_prefs.fan_mode = 0; // auto
|
||||
_prefs.fan_timeout_secs = 30;
|
||||
|
||||
@@ -1374,7 +1347,6 @@ void MyMesh::begin(FILESYSTEM *fs, ArchiveStorage* archive) {
|
||||
updateFloodAdvertTimer();
|
||||
|
||||
board.setAdcMultiplier(_prefs.adc_multiplier);
|
||||
board.setBatteryReporting(_prefs.battery_reporting_enabled);
|
||||
#if defined(TBEAM_1W)
|
||||
auto& tbeam1w_board = static_cast<TBeam1WBoard&>(board);
|
||||
tbeam1w_board.setFanPostTxHoldMs(static_cast<uint32_t>(_prefs.fan_timeout_secs) * 1000UL);
|
||||
@@ -1399,6 +1371,18 @@ void MyMesh::sendFloodScoped(const TransportKey& scope, mesh::Packet* pkt, uint3
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t MyMesh::getBatteryMilliVolts(bool force_refresh) {
|
||||
constexpr unsigned long kBatterySampleIntervalMs = 60000UL;
|
||||
|
||||
if (force_refresh || !_battery_sample_valid || next_battery_sample_ms == 0 || millisHasNowPassed(next_battery_sample_ms)) {
|
||||
_battery_mv_cache = board.getBattMilliVolts();
|
||||
_battery_sample_valid = true;
|
||||
next_battery_sample_ms = millis() + kBatterySampleIntervalMs;
|
||||
}
|
||||
|
||||
return _battery_mv_cache;
|
||||
}
|
||||
|
||||
void MyMesh::applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) {
|
||||
set_radio_at = futureMillis(2000); // give CLI reply some time to be sent back, before applying temp radio params
|
||||
pending_freq = freq;
|
||||
@@ -1534,7 +1518,13 @@ void MyMesh::removeNeighbor(const uint8_t *pubkey, int key_len) {
|
||||
}
|
||||
|
||||
void MyMesh::formatStatsReply(char *reply, size_t reply_size) {
|
||||
StatsFormatHelper::formatCoreStats(reply, reply_size, board, *_ms, _err_flags, _mgr);
|
||||
snprintf(reply,
|
||||
reply_size,
|
||||
"{\"battery_mv\":%u,\"uptime_secs\":%u,\"errors\":%u,\"queue_len\":%u}",
|
||||
getBatteryMilliVolts(true),
|
||||
_ms->getMillis() / 1000,
|
||||
_err_flags,
|
||||
_mgr->getOutboundTotal());
|
||||
}
|
||||
|
||||
void MyMesh::startRegionsLoad() {
|
||||
@@ -1863,13 +1853,14 @@ void MyMesh::updateStatsHistory(unsigned long now_ms) {
|
||||
#endif
|
||||
if (next_history_sample_ms == 0 || millisHasNowPassed(next_history_sample_ms)) {
|
||||
if (!live_stats_headroom_low) {
|
||||
WebSensorSnapshot sensor_snapshot = collectWebSensorSnapshot(board, sensors);
|
||||
const uint16_t battery_mv = getBatteryMilliVolts();
|
||||
WebSensorSnapshot sensor_snapshot = collectWebSensorSnapshot(board, sensors, battery_mv);
|
||||
HistorySample sample{};
|
||||
sample.epoch_secs = getRTCClock()->getCurrentTime();
|
||||
sample.uptime_secs = static_cast<uint32_t>(uptime_millis / 1000);
|
||||
sample.packets_sent = radio_driver.getPacketsSent();
|
||||
sample.packets_recv = radio_driver.getPacketsRecv();
|
||||
sample.battery_mv = board.getBattMilliVolts();
|
||||
sample.battery_mv = battery_mv;
|
||||
sample.queue_len = static_cast<uint16_t>(_mgr->getOutboundTotal());
|
||||
sample.error_flags = _err_flags;
|
||||
sample.recv_errors = static_cast<uint16_t>(min<uint32_t>(radio_driver.getPacketsRecvErrors(), 0xFFFF));
|
||||
@@ -2488,7 +2479,9 @@ bool MyMesh::formatWebStatsSummaryJson(char* reply, size_t reply_size) {
|
||||
wifi_signal[sizeof(wifi_signal) - 1] = 0;
|
||||
#endif
|
||||
|
||||
const uint16_t battery_mv = getBatteryMilliVolts(true);
|
||||
const int battery_pct = board.getBatteryPercent();
|
||||
const WebSensorSnapshot sensor_snapshot = collectWebSensorSnapshot(board, sensors, battery_mv);
|
||||
const bool archive_available = (_archive != nullptr) && _archive->isMounted();
|
||||
#ifdef WITH_MQTT_UPLINK
|
||||
const bool mqtt_connected = mqtt.isAnyBrokerConnected();
|
||||
@@ -2544,7 +2537,7 @@ bool MyMesh::formatWebStatsSummaryJson(char* reply, size_t reply_size) {
|
||||
archive_type,
|
||||
static_cast<unsigned long long>(_archive != nullptr ? _archive->getTotalBytes() : 0),
|
||||
static_cast<unsigned long long>(_archive != nullptr ? _archive->getUsedBytes() : 0),
|
||||
board.getBattMilliVolts(),
|
||||
battery_mv,
|
||||
battery_pct,
|
||||
static_cast<unsigned long>(uptime_millis / 1000),
|
||||
_err_flags,
|
||||
@@ -2594,7 +2587,7 @@ bool MyMesh::formatWebStatsSummaryJson(char* reply, size_t reply_size) {
|
||||
}
|
||||
|
||||
offset += snprintf(&reply[offset], reply_size - offset, ",");
|
||||
if (!appendJsonSensors(reply, reply_size, offset)) {
|
||||
if (!appendJsonSensors(reply, reply_size, offset, sensor_snapshot)) {
|
||||
return false;
|
||||
}
|
||||
offset += snprintf(&reply[offset], reply_size - offset, ",");
|
||||
@@ -2634,10 +2627,8 @@ bool MyMesh::formatWebStatsSeriesJson(const char* series, char* reply, size_t re
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MyMesh::appendJsonSensors(char* reply, size_t reply_size, size_t& offset) const {
|
||||
bool MyMesh::appendJsonSensors(char* reply, size_t reply_size, size_t& offset, const WebSensorSnapshot& snapshot) const {
|
||||
#if defined(ESP_PLATFORM) && WITH_WEB_PANEL
|
||||
WebSensorSnapshot snapshot = collectWebSensorSnapshot(board, sensors);
|
||||
|
||||
bool needs_comma = false;
|
||||
const int open_written = snprintf(&reply[offset], reply_size - offset, "\"sensors\":{");
|
||||
if (open_written < 0 || static_cast<size_t>(open_written) >= (reply_size - offset)) {
|
||||
@@ -2776,7 +2767,7 @@ void MyMesh::loop() {
|
||||
#endif
|
||||
#ifdef WITH_MQTT_UPLINK
|
||||
MQTTStatusSnapshot mqtt_status{};
|
||||
mqtt_status.battery_mv = static_cast<int>(board.getBattMilliVolts());
|
||||
mqtt_status.battery_mv = static_cast<int>(getBatteryMilliVolts());
|
||||
mqtt_status.uptime_secs = static_cast<uint32_t>(uptime_millis / 1000);
|
||||
mqtt_status.error_flags = _err_flags;
|
||||
mqtt_status.queue_len = static_cast<uint16_t>(_mgr->getOutboundTotal());
|
||||
|
||||
@@ -65,6 +65,41 @@ struct RepeaterStats {
|
||||
uint32_t n_recv_errors;
|
||||
};
|
||||
|
||||
struct WebSensorSnapshot {
|
||||
bool has_battery = false;
|
||||
uint16_t battery_mv = 0;
|
||||
|
||||
bool has_supply_voltage = false;
|
||||
float supply_voltage_v = NAN;
|
||||
|
||||
bool has_sensor_temp = false;
|
||||
float sensor_temp_c = NAN;
|
||||
|
||||
bool has_mcu_temp = false;
|
||||
float mcu_temp_c = NAN;
|
||||
|
||||
bool has_humidity = false;
|
||||
float humidity_pct = NAN;
|
||||
|
||||
bool has_pressure = false;
|
||||
float pressure_hpa = NAN;
|
||||
|
||||
bool has_pressure_altitude = false;
|
||||
float pressure_altitude_m = NAN;
|
||||
|
||||
bool has_gps = false;
|
||||
bool gps_enabled = false;
|
||||
bool gps_fix = false;
|
||||
bool has_gps_lat = false;
|
||||
float gps_lat = NAN;
|
||||
bool has_gps_lon = false;
|
||||
float gps_lon = NAN;
|
||||
bool has_gps_altitude = false;
|
||||
float gps_altitude_m = NAN;
|
||||
bool has_satellites = false;
|
||||
long satellites = 0;
|
||||
};
|
||||
|
||||
#ifndef MAX_CLIENTS
|
||||
#define MAX_CLIENTS 32
|
||||
#endif
|
||||
@@ -94,10 +129,13 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks, public WebPanelComm
|
||||
uint32_t last_millis;
|
||||
uint64_t uptime_millis;
|
||||
unsigned long next_archive_neighbours_flush_ms;
|
||||
unsigned long next_battery_sample_ms;
|
||||
unsigned long next_history_sample_ms;
|
||||
unsigned long next_local_advert, next_flood_advert;
|
||||
bool _logging;
|
||||
bool _archive_neighbours_dirty;
|
||||
bool _battery_sample_valid;
|
||||
uint16_t _battery_mv_cache;
|
||||
NodePrefs _prefs;
|
||||
ClientACL acl;
|
||||
CommonCLI _cli;
|
||||
@@ -159,7 +197,8 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks, public WebPanelComm
|
||||
void recordStatsEvent(uint8_t type, int16_t value = 0);
|
||||
bool appendJsonEvents(char* reply, size_t reply_size, size_t& offset) const;
|
||||
bool appendJsonNeighbours(char* reply, size_t reply_size, size_t& offset) const;
|
||||
bool appendJsonSensors(char* reply, size_t reply_size, size_t& offset) const;
|
||||
bool appendJsonSensors(char* reply, size_t reply_size, size_t& offset, const WebSensorSnapshot& snapshot) const;
|
||||
uint16_t getBatteryMilliVolts(bool force_refresh = false);
|
||||
uint8_t handleLoginReq(const mesh::Identity& sender, const uint8_t* secret, uint32_t sender_timestamp, const uint8_t* data, bool is_flood);
|
||||
uint8_t handleAnonRegionsReq(const mesh::Identity& sender, uint32_t sender_timestamp, const uint8_t* data);
|
||||
uint8_t handleAnonOwnerReq(const mesh::Identity& sender, uint32_t sender_timestamp, const uint8_t* data);
|
||||
|
||||
@@ -652,8 +652,7 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
||||
_prefs.gps_enabled = 0;
|
||||
_prefs.gps_interval = 0;
|
||||
_prefs.advert_loc_policy = ADVERT_LOC_PREFS;
|
||||
_prefs.battery_reporting_enabled = 1;
|
||||
|
||||
_prefs.reserved_290 = 0;
|
||||
next_post_idx = 0;
|
||||
next_client_idx = 0;
|
||||
next_push = 0;
|
||||
@@ -699,7 +698,6 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
||||
updateFloodAdvertTimer();
|
||||
|
||||
board.setAdcMultiplier(_prefs.adc_multiplier);
|
||||
board.setBatteryReporting(_prefs.battery_reporting_enabled);
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
applyGpsPrefs();
|
||||
|
||||
@@ -731,7 +731,7 @@ SensorMesh::SensorMesh(mesh::MainBoard& board, mesh::Radio& radio, mesh::Millise
|
||||
_prefs.gps_enabled = 0;
|
||||
_prefs.gps_interval = 0;
|
||||
_prefs.advert_loc_policy = ADVERT_LOC_PREFS;
|
||||
_prefs.battery_reporting_enabled = 1;
|
||||
_prefs.reserved_290 = 0;
|
||||
memset(default_scope.key, 0, sizeof(default_scope.key));
|
||||
}
|
||||
|
||||
@@ -771,7 +771,6 @@ void SensorMesh::begin(FILESYSTEM* fs) {
|
||||
updateFloodAdvertTimer();
|
||||
|
||||
board.setAdcMultiplier(_prefs.adc_multiplier);
|
||||
board.setBatteryReporting(_prefs.battery_reporting_enabled);
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
applyGpsPrefs();
|
||||
|
||||
@@ -401,3 +401,27 @@ releases:
|
||||
area: docs
|
||||
text: "Updated the web panel, API, and custom CLI docs to cover the environment summary/trends, stats persistence behaviour, and existing T-Beam 1W fan controls."
|
||||
breaking_changes: []
|
||||
|
||||
- track: repeater-mqtt
|
||||
version: "1.3.9"
|
||||
tag: "repeater-mqtt-eastmesh-v1.3.9"
|
||||
date: "2026-04-22"
|
||||
previous_version: "1.3.8"
|
||||
summary: "Reduced unnecessary repeater battery polling by removing hot-loop MQTT sampling and reusing throttled battery reads across stats and web status paths."
|
||||
changes:
|
||||
- type: fixed
|
||||
area: mqtt
|
||||
text: "Stopped rebuilding the MQTT status battery reading from a fresh ADC sample on every repeater loop iteration and switched that path to a throttled cached value instead."
|
||||
- type: changed
|
||||
area: stats
|
||||
text: "Reused a single battery sample across the web stats history and summary builders so one logical stats operation no longer performs multiple immediate battery reads."
|
||||
- type: fixed
|
||||
area: board-support
|
||||
text: "Reduced Heltec V3 battery-sense activity while MQTT and web features are active, while still keeping explicit status and telemetry requests on a fresh reading path."
|
||||
- type: changed
|
||||
area: board-support
|
||||
text: "Removed the obsolete battery reporting toggle path and its stale CLI documentation now that repeater battery sampling is handled correctly without a board-level reporting disable switch."
|
||||
- type: docs
|
||||
area: docs
|
||||
text: "Updated the custom CLI docs to note that repeater MQTT background battery sampling is now rate-limited while explicit status and telemetry requests still refresh immediately."
|
||||
breaking_changes: []
|
||||
|
||||
@@ -44,9 +44,6 @@ namespace mesh {
|
||||
class MainBoard {
|
||||
public:
|
||||
virtual uint16_t getBattMilliVolts() = 0;
|
||||
virtual bool supportsBatteryReporting() const { return false; }
|
||||
virtual bool setBatteryReporting(bool enabled) { (void)enabled; return false; }
|
||||
virtual bool isBatteryReportingEnabled() const { return true; }
|
||||
virtual int getBatteryPercent() { return -1; }
|
||||
virtual bool isCharging() { return false; }
|
||||
virtual bool isVbusPresent() { return false; }
|
||||
|
||||
@@ -87,8 +87,8 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
file.read((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162
|
||||
file.read((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166
|
||||
file.read((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170
|
||||
if (file.available() >= (int)sizeof(_prefs->battery_reporting_enabled)) {
|
||||
file.read((uint8_t *)&_prefs->battery_reporting_enabled, sizeof(_prefs->battery_reporting_enabled)); // 290
|
||||
if (file.available() >= (int)sizeof(_prefs->reserved_290)) {
|
||||
file.read((uint8_t *)&_prefs->reserved_290, sizeof(_prefs->reserved_290)); // 290 reserved
|
||||
}
|
||||
if (file.available() >= (int)sizeof(_prefs->rx_boosted_gain)) {
|
||||
file.read((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 291
|
||||
@@ -123,7 +123,6 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
_prefs->bridge_channel = constrain(_prefs->bridge_channel, 0, 14);
|
||||
|
||||
_prefs->powersaving_enabled = constrain(_prefs->powersaving_enabled, 0, 1);
|
||||
_prefs->battery_reporting_enabled = constrain(_prefs->battery_reporting_enabled, 0, 1);
|
||||
|
||||
_prefs->gps_enabled = constrain(_prefs->gps_enabled, 0, 1);
|
||||
_prefs->advert_loc_policy = constrain(_prefs->advert_loc_policy, 0, 2);
|
||||
@@ -192,7 +191,7 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
|
||||
file.write((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162
|
||||
file.write((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166
|
||||
file.write((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170
|
||||
file.write((uint8_t *)&_prefs->battery_reporting_enabled, sizeof(_prefs->battery_reporting_enabled)); // 290
|
||||
file.write((uint8_t *)&_prefs->reserved_290, sizeof(_prefs->reserved_290)); // 290 reserved
|
||||
file.write((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 291
|
||||
file.write((uint8_t *)&_prefs->fan_mode, sizeof(_prefs->fan_mode)); // 292
|
||||
file.write((uint8_t *)&_prefs->fan_timeout_secs, sizeof(_prefs->fan_timeout_secs)); // 293
|
||||
|
||||
@@ -58,7 +58,7 @@ struct NodePrefs { // persisted to file
|
||||
uint32_t discovery_mod_timestamp;
|
||||
float adc_multiplier;
|
||||
char owner_info[120];
|
||||
uint8_t battery_reporting_enabled; // boolean
|
||||
uint8_t reserved_290; // reserved to preserve on-disk prefs layout
|
||||
uint8_t rx_boosted_gain; // power settings
|
||||
uint8_t path_hash_mode; // which path mode to use when sending
|
||||
uint8_t loop_detect;
|
||||
|
||||
@@ -22,13 +22,11 @@
|
||||
class HeltecV3Board : public ESP32Board {
|
||||
private:
|
||||
bool adc_active_state;
|
||||
bool battery_reporting_enabled;
|
||||
|
||||
public:
|
||||
RefCountedDigitalPin periph_power;
|
||||
|
||||
HeltecV3Board() : adc_active_state(false),
|
||||
battery_reporting_enabled(true),
|
||||
periph_power(PIN_VEXT_EN) { }
|
||||
|
||||
void begin() {
|
||||
@@ -83,10 +81,6 @@ public:
|
||||
}
|
||||
|
||||
uint16_t getBattMilliVolts() override {
|
||||
if (!battery_reporting_enabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
analogReadResolution(10);
|
||||
digitalWrite(PIN_ADC_CTRL, adc_active_state);
|
||||
|
||||
@@ -109,19 +103,6 @@ public:
|
||||
return mv;
|
||||
}
|
||||
|
||||
bool supportsBatteryReporting() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool setBatteryReporting(bool enabled) override {
|
||||
battery_reporting_enabled = enabled;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isBatteryReportingEnabled() const override {
|
||||
return battery_reporting_enabled;
|
||||
}
|
||||
|
||||
const char* getManufacturerName() const override {
|
||||
return "Heltec V3";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user