mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-10-23 13:22:22 +00:00
refactor(mqtt): migrate observer settings to MQTTPrefs structure
Refactored the handling of observer-related settings by moving them from NodePrefs to a new MQTTPrefs structure. This change centralizes MQTT, WiFi, timezone, SNMP, and alert configurations, improving code organization and maintainability. The new structure allows for better separation of concerns and prepares the codebase for future enhancements.
This commit is contained in:
1 parent
9535f243af
commit
2eb41baeda
14 files changed
+372
-561
No files matched your search
@@ -951,21 +951,8 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
_prefs.agc_reset_interval = 7; // 28 seconds (secs/4) — prevents AGC drift on long-running observers
|
||||
#endif
|
||||
_prefs.radio_watchdog_minutes = 5; // 5 minutes default
|
||||
|
||||
// Alert channel defaults — disabled by default, and the channel is left
|
||||
// unconfigured so a freshly-flashed observer never broadcasts on the
|
||||
// well-known Public hashtag. Operators must explicitly pick a private
|
||||
// key (`set alert.psk`) or a hashtag (`set alert.hashtag`) before alerts
|
||||
// can fire. The sender prefix on outgoing alert messages is always the
|
||||
// node name (`set name ...`), so there's no separate `alert.name`.
|
||||
_prefs.alert_enabled = 0;
|
||||
_prefs.alert_psk_hex[0] = '\0';
|
||||
_prefs.alert_hashtag[0] = '\0';
|
||||
_prefs.alert_region[0] = '\0'; // empty = use default_scope
|
||||
_prefs.alert_wifi_minutes = 30; // 30 minutes
|
||||
_prefs.alert_mqtt_minutes = 240; // 4 hours
|
||||
_prefs.alert_min_interval_min = 60; // re-arm window: 1 hour
|
||||
// Observer defaults (radio_watchdog, alert.*, snmp.*) moved to applyMQTTDefaults()
|
||||
// in MQTTDefaults.h — they live in /mqtt_prefs now, not NodePrefs.
|
||||
|
||||
// bridge defaults
|
||||
_prefs.bridge_enabled = 1; // enabled
|
||||
@@ -976,21 +963,12 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
||||
|
||||
StrHelper::strncpy(_prefs.bridge_secret, "LVSITANOS", sizeof(_prefs.bridge_secret));
|
||||
|
||||
// SNMP defaults
|
||||
_prefs.snmp_enabled = 0;
|
||||
StrHelper::strncpy(_prefs.snmp_community, "public", sizeof(_prefs.snmp_community));
|
||||
|
||||
// GPS defaults
|
||||
_prefs.gps_enabled = 0;
|
||||
_prefs.gps_interval = 0;
|
||||
_prefs.advert_loc_policy = ADVERT_LOC_PREFS;
|
||||
|
||||
// MQTT slot/IATA/timezone defaults come from /mqtt_prefs via loadPrefs (see MQTTDefaults.h)
|
||||
_prefs.mqtt_origin[0] = '\0';
|
||||
|
||||
// WiFi defaults (user-configured via CLI; placeholders until set)
|
||||
StrHelper::strncpy(_prefs.wifi_ssid, "ssid_here", sizeof(_prefs.wifi_ssid));
|
||||
StrHelper::strncpy(_prefs.wifi_password, "password_here", sizeof(_prefs.wifi_password));
|
||||
// MQTT/WiFi/timezone/radio_watchdog defaults live in /mqtt_prefs now (see applyMQTTDefaults).
|
||||
|
||||
_prefs.adc_multiplier = 0.0f; // 0.0f means use default board multiplier
|
||||
|
||||
@@ -1042,7 +1020,7 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
||||
if (_prefs.bridge_enabled) {
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
// Defer construction to avoid static init crashes on ESP32 classic
|
||||
bridge = new MQTTBridge(&_prefs, _mgr, getRTCClock(), &self_id);
|
||||
bridge = new MQTTBridge(&_prefs, _cli.getObserverPrefs(), _mgr, getRTCClock(), &self_id);
|
||||
#endif
|
||||
if (bridge) {
|
||||
// Set device public key for MQTT topics
|
||||
@@ -1065,7 +1043,7 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
||||
// Set stats sources for automatic stats collection
|
||||
bridge->setStatsSources(this, _radio, _cli.getBoard(), _ms);
|
||||
#ifdef WITH_SNMP
|
||||
if (_prefs.snmp_enabled) {
|
||||
if (_cli.getObserverPrefs()->snmp_enabled) {
|
||||
_snmp_agent.setNodeName(_prefs.node_name);
|
||||
_snmp_agent.setFirmwareVersion(getFirmwareVer());
|
||||
bridge->setSNMPAgent(&_snmp_agent);
|
||||
@@ -1082,8 +1060,8 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
||||
// Passing `this` as the callbacks lets the reporter resolve a TransportKey
|
||||
// scope (alert.region override, falling back to default_scope) so alert
|
||||
// floods ride the same scope as adverts/channel messages.
|
||||
_alerter.begin(&_prefs, this, this);
|
||||
#if defined(WITH_MQTT_BRIDGE)
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
_alerter.begin(&_prefs, _cli.getObserverPrefs(), this, this);
|
||||
_alerter.setBridge(bridge);
|
||||
#endif
|
||||
|
||||
@@ -1118,12 +1096,15 @@ bool MyMesh::resolveAlertScope(TransportKey& dest) {
|
||||
// RegionMap so the operator can name a region that doesn't exist yet
|
||||
// without polluting region_map state — we just silently fall through
|
||||
// to default_scope on miss.
|
||||
if (_prefs.alert_region[0]) {
|
||||
auto r = region_map.findByNamePrefix(_prefs.alert_region);
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
const char* alert_region = _cli.getObserverPrefs()->alert_region;
|
||||
if (alert_region[0]) {
|
||||
auto r = region_map.findByNamePrefix(alert_region);
|
||||
if (r && region_map.getTransportKeysFor(*r, &dest, 1) > 0 && !dest.isNull()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!default_scope.isNull()) {
|
||||
dest = default_scope;
|
||||
return true;
|
||||
@@ -1473,7 +1454,9 @@ void MyMesh::loop() {
|
||||
uptime_millis += now - last_millis;
|
||||
last_millis = now;
|
||||
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
_alerter.onLoop(now);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_SNMP
|
||||
// Push radio stats to SNMP agent every 2 seconds
|
||||
|
||||
@@ -132,7 +132,9 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
|
||||
#ifdef WITH_SNMP
|
||||
MeshSNMPAgent _snmp_agent;
|
||||
#endif
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
AlertReporter _alerter;
|
||||
#endif
|
||||
|
||||
void putNeighbour(const mesh::Identity& id, uint32_t timestamp, float snr);
|
||||
uint8_t handleLoginReq(const mesh::Identity& sender, const uint8_t* secret, uint32_t sender_timestamp, const uint8_t* data, bool is_flood);
|
||||
@@ -168,9 +170,11 @@ protected:
|
||||
int getAGCResetInterval() const override {
|
||||
return ((int)_prefs.agc_reset_interval) * 4000; // milliseconds
|
||||
}
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
uint32_t getRadioWatchdogMillis() const override {
|
||||
return ((uint32_t)_prefs.radio_watchdog_minutes) * 60000UL;
|
||||
return ((uint32_t)_cli.getObserverPrefs()->radio_watchdog_minutes) * 60000UL;
|
||||
}
|
||||
#endif
|
||||
uint8_t getExtraAckTransmitCount() const override {
|
||||
return _prefs.multi_acks;
|
||||
}
|
||||
@@ -215,8 +219,10 @@ public:
|
||||
// CommonCLICallbacks
|
||||
void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) override;
|
||||
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
void onAlertConfigChanged() override { _alerter.onConfigChanged(); }
|
||||
bool sendAlertText(const char* text) override { return _alerter.sendText(text); }
|
||||
#endif
|
||||
bool resolveAlertScope(TransportKey& dest) override;
|
||||
bool formatFileSystem() override;
|
||||
void sendSelfAdvertisement(int delay_millis, bool flood) override;
|
||||
@@ -253,7 +259,7 @@ public:
|
||||
void setBridgeState(bool enable) override {
|
||||
if (!bridge) {
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
bridge = new MQTTBridge(&_prefs, _mgr, getRTCClock(), &self_id);
|
||||
bridge = new MQTTBridge(&_prefs, _cli.getObserverPrefs(), _mgr, getRTCClock(), &self_id);
|
||||
#endif
|
||||
if (!bridge) return;
|
||||
}
|
||||
@@ -303,8 +309,12 @@ public:
|
||||
}
|
||||
|
||||
void restartBridgeSlot(int slot) override {
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
if (!bridge || !bridge->isRunning()) return;
|
||||
bridge->setSlotPreset(slot, _prefs.mqtt_slot_preset[slot]);
|
||||
bridge->setSlotPreset(slot, _cli.getObserverPrefs()->mqtt_slot_preset[slot]);
|
||||
#else
|
||||
(void)slot;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Schedule the pull-OTA flash to run from loop() in ~2.5 s, leaving time for the
|
||||
|
||||
@@ -681,15 +681,8 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
||||
_prefs.gps_interval = 0;
|
||||
_prefs.advert_loc_policy = ADVERT_LOC_PREFS;
|
||||
|
||||
// Alert channel defaults (same as repeater; off by default and unconfigured).
|
||||
// Operator must pick `set alert.psk` or `set alert.hashtag` before alerts fire.
|
||||
_prefs.alert_enabled = 0;
|
||||
_prefs.alert_psk_hex[0] = '\0';
|
||||
_prefs.alert_hashtag[0] = '\0';
|
||||
_prefs.alert_region[0] = '\0';
|
||||
_prefs.alert_wifi_minutes = 30;
|
||||
_prefs.alert_mqtt_minutes = 240;
|
||||
_prefs.alert_min_interval_min = 60;
|
||||
// Observer defaults (alert.*, etc.) moved to applyMQTTDefaults() — they live
|
||||
// in /mqtt_prefs now, not NodePrefs.
|
||||
|
||||
// bridge defaults (same as repeater)
|
||||
_prefs.bridge_enabled = 1; // enabled
|
||||
@@ -698,12 +691,7 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
||||
_prefs.bridge_baud = 115200; // baud rate
|
||||
_prefs.bridge_channel = 1; // channel 1
|
||||
|
||||
// MQTT slot/IATA/timezone defaults come from /mqtt_prefs via loadPrefs (see MQTTDefaults.h)
|
||||
_prefs.mqtt_origin[0] = '\0';
|
||||
|
||||
// WiFi defaults (user-configured via CLI; placeholders until set)
|
||||
StrHelper::strncpy(_prefs.wifi_ssid, "ssid_here", sizeof(_prefs.wifi_ssid));
|
||||
StrHelper::strncpy(_prefs.wifi_password, "password_here", sizeof(_prefs.wifi_password));
|
||||
// MQTT/WiFi/timezone defaults live in /mqtt_prefs now (see applyMQTTDefaults).
|
||||
|
||||
next_post_idx = 0;
|
||||
next_client_idx = 0;
|
||||
@@ -757,7 +745,7 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
if (_prefs.bridge_enabled) {
|
||||
// Defer construction to avoid static init crashes on ESP32 classic
|
||||
bridge = new MQTTBridge(&_prefs, _mgr, getRTCClock(), &self_id);
|
||||
bridge = new MQTTBridge(&_prefs, _cli.getObserverPrefs(), _mgr, getRTCClock(), &self_id);
|
||||
if (bridge) {
|
||||
// Set device public key for MQTT topics
|
||||
char device_id[65];
|
||||
@@ -787,8 +775,8 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
||||
// Passing `this` as the callbacks lets the reporter resolve a TransportKey
|
||||
// scope (alert.region override, falling back to default_scope) so alert
|
||||
// floods ride the same scope as adverts/channel messages.
|
||||
_alerter.begin(&_prefs, this, this);
|
||||
#if defined(WITH_MQTT_BRIDGE)
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
_alerter.begin(&_prefs, _cli.getObserverPrefs(), this, this);
|
||||
_alerter.setBridge(bridge);
|
||||
#endif
|
||||
}
|
||||
@@ -806,12 +794,15 @@ void MyMesh::sendFloodScoped(const TransportKey& scope, mesh::Packet* pkt, uint3
|
||||
|
||||
bool MyMesh::resolveAlertScope(TransportKey& dest) {
|
||||
// Same resolution policy as simple_repeater: alert.region > default_scope.
|
||||
if (_prefs.alert_region[0]) {
|
||||
auto r = region_map.findByNamePrefix(_prefs.alert_region);
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
const char* alert_region = _cli.getObserverPrefs()->alert_region;
|
||||
if (alert_region[0]) {
|
||||
auto r = region_map.findByNamePrefix(alert_region);
|
||||
if (r && region_map.getTransportKeysFor(*r, &dest, 1) > 0 && !dest.isNull()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!default_scope.isNull()) {
|
||||
dest = default_scope;
|
||||
return true;
|
||||
@@ -1131,5 +1122,7 @@ void MyMesh::loop() {
|
||||
uptime_millis += now - last_millis;
|
||||
last_millis = now;
|
||||
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
_alerter.onLoop(now);
|
||||
#endif
|
||||
}
|
||||
@@ -126,7 +126,9 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
MQTTBridge* bridge;
|
||||
#endif
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
AlertReporter _alerter;
|
||||
#endif
|
||||
|
||||
void addPost(ClientInfo* client, const char* postData);
|
||||
void pushPostToClient(ClientInfo* client, PostInfo& post);
|
||||
@@ -201,8 +203,10 @@ public:
|
||||
// CommonCLICallbacks
|
||||
void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) override;
|
||||
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
void onAlertConfigChanged() override { _alerter.onConfigChanged(); }
|
||||
bool sendAlertText(const char* text) override { return _alerter.sendText(text); }
|
||||
#endif
|
||||
bool resolveAlertScope(TransportKey& dest) override;
|
||||
bool formatFileSystem() override;
|
||||
void sendSelfAdvertisement(int delay_millis, bool flood) override;
|
||||
@@ -241,7 +245,7 @@ public:
|
||||
void setBridgeState(bool enable) override {
|
||||
if (!bridge) {
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
bridge = new MQTTBridge(&_prefs, _mgr, getRTCClock(), &self_id);
|
||||
bridge = new MQTTBridge(&_prefs, _cli.getObserverPrefs(), _mgr, getRTCClock(), &self_id);
|
||||
#endif
|
||||
if (!bridge) return;
|
||||
}
|
||||
@@ -289,8 +293,12 @@ public:
|
||||
}
|
||||
|
||||
void restartBridgeSlot(int slot) override {
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
if (!bridge || !bridge->isRunning()) return;
|
||||
bridge->setSlotPreset(slot, _prefs.mqtt_slot_preset[slot]);
|
||||
bridge->setSlotPreset(slot, _cli.getObserverPrefs()->mqtt_slot_preset[slot]);
|
||||
#else
|
||||
(void)slot;
|
||||
#endif
|
||||
}
|
||||
|
||||
int getQueueSize() override {
|
||||
|
||||
Reference in new issue
Block a user