added configuration for mqtt.sever, mqtt.username, mqtt.pasword, and mqtt.port

validated primary MQTT server credentials are set before opening connection
This commit is contained in:
agessaman
2026-01-02 13:36:40 -08:00
parent ed70ceb284
commit 58b73343c1
6 changed files with 418 additions and 23 deletions
+230 -5
View File
@@ -41,6 +41,27 @@ pio run -e Heltec_v3_repeater_bridge_mqtt
pio run -e Station_G2_repeater_bridge_mqtt
```
### Custom MQTT Server Configuration
You can configure a custom MQTT server using build flags in `platformio.ini`:
```ini
[env:Heltec_v3_repeater_bridge_mqtt]
build_flags =
${Heltec_lora32_v3.build_flags}
-D WITH_MQTT_BRIDGE=1
-D MQTT_SERVER='"your-mqtt-broker.com"'
-D MQTT_PORT=1883
-D MQTT_USERNAME='"your-username"'
-D MQTT_PASSWORD='"your-password"'
```
**Build Flags:**
- `MQTT_SERVER` - MQTT broker hostname
- `MQTT_PORT` - MQTT broker port (default: 1883)
- `MQTT_USERNAME` - MQTT username
- `MQTT_PASSWORD` - MQTT password
## Default Configuration
The MQTT bridge comes with the following defaults:
@@ -71,6 +92,10 @@ The MQTT bridge comes with the following defaults:
- `get mqtt.raw` - Get raw message setting (on/off)
- `get mqtt.tx` - Get TX message setting (on/off)
- `get mqtt.interval` - Get status publish interval (ms)
- `get mqtt.server` - Get MQTT server hostname
- `get mqtt.port` - Get MQTT server port
- `get mqtt.username` - Get MQTT username
- `get mqtt.password` - Get MQTT password
- `get mqtt.analyzer.us` - Get US Let's Mesh Analyzer server setting (on/off)
- `get mqtt.analyzer.eu` - Get EU Let's Mesh Analyzer server setting (on/off)
@@ -82,6 +107,10 @@ The MQTT bridge comes with the following defaults:
- `set mqtt.raw on|off` - Enable/disable raw messages
- `set mqtt.tx on|off` - Enable/disable TX packet messages
- `set mqtt.interval <ms>` - Set status publish interval (1000-3600000 ms)
- `set mqtt.server <hostname>` - Set MQTT server hostname
- `set mqtt.port <port>` - Set MQTT server port (1-65535)
- `set mqtt.username <username>` - Set MQTT username
- `set mqtt.password <password>` - Set MQTT password
- `set mqtt.analyzer.us on|off` - Enable/disable US Let's Mesh Analyzer server
- `set mqtt.analyzer.eu on|off` - Enable/disable EU Let's Mesh Analyzer server
@@ -235,14 +264,210 @@ Minimal raw packet data for map integration.
- US Server: `mqtt-us-v1.letsmesh.net:443` (WebSocket with TLS)
- EU Server: `mqtt-eu-v1.letsmesh.net:443` (WebSocket with TLS)
## First-Time Setup
### Prerequisites
- MeshCore device with MQTT bridge firmware flashed
- WiFi network credentials
- MQTT broker (optional - default broker is provided)
- LoRa-capable device for configuration (repeater console)
- MeshCore network access
### Step 1: Initial Boot and Network Connection
1. **Flash the firmware** to your device using PlatformIO or the build script
2. **Deploy the device** in your mesh network location
3. **Ensure WiFi connectivity** - the device will automatically connect to WiFi if credentials are pre-configured
4. **Verify mesh network access** - device should be discoverable by other mesh nodes
### Step 2: Connect via LoRa Repeater Console
Use a MeshCore companion device to configure the Repeater's MQTT bridge.
1. **Connect to the mesh** using your companion
2. **Locate the MQTT bridge device** in your contacts
3. **Log into your Repeater** using the default password (password) or whatever you configured via serial console
3. **Tap on the repeater console** on your repeater's settings
4. **Send configuration commands** via LoRa to the MQTT bridge device
### Step 3: Configure WiFi Connection
The device needs internet connectivity to publish to MQTT brokers.
**Via LoRa Repeater Console:**
```
# Set your WiFi credentials
set wifi.ssid "YourWiFiNetwork"
set wifi.pwd "YourWiFiPassword"
# Verify WiFi settings
get wifi.ssid
get wifi.pwd
```
### Step 4: Configure Device Identity
Set up your device's identity for MQTT topics and status messages.
**Via LoRa Repeater Console:**
```
# Set IATA code for topic structure (e.g., airport code)
set mqtt.iata "SEA"
# Verify settings (origin is set automatically to device name)
get mqtt.origin
get mqtt.iata
```
### Step 5: Configure Timezone
Set your local timezone for accurate timestamps.
**Via LoRa Repeater Console:**
```
# Set timezone (choose one method)
set timezone "America/Los_Angeles" # IANA format
set timezone "PDT" # Abbreviation
set timezone "UTC-8" # UTC offset
# Verify timezone
get timezone
```
### Step 6: Configure MQTT Settings
Customize which messages to publish and how often.
**Via LoRa Repeater Console:**
```
# Configure MQTT server (optional - uses defaults if not set)
set mqtt.server "your-mqtt-broker.com"
set mqtt.port 1883
set mqtt.username "your-username"
set mqtt.password "your-password"
# Enable/disable message types
set mqtt.status on # Device status messages
set mqtt.packets on # Packet data messages
set mqtt.raw off # Raw packet data (optional)
set mqtt.tx off # Transmitted packets (optional)
# Set status publish interval (default: 5 minutes)
set mqtt.interval 300000
# Verify settings
get mqtt.server
get mqtt.port
get mqtt.username
get mqtt.status
get mqtt.packets
get mqtt.interval
```
### Step 7: Verify MQTT Broker Connection
Check that the device can connect to MQTT brokers.
**Via LoRa Repeater Console:**
```
# Check bridge status
get bridge.enabled
# If disabled, enable it
set bridge.enabled on
# Check MQTT analyzer servers (optional)
get mqtt.analyzer.us
get mqtt.analyzer.eu
```
### Step 8: Monitor MQTT Messages
Once configured, the device will automatically publish messages to MQTT brokers.
**Default MQTT Broker**: `meshtastic.pugetmesh.org:1883`
- Username: `meshdev`
- Password: `large4cats`
**Topic Structure**:
- Status: `meshcore/{IATA}/{DEVICE_PUBLIC_KEY}/status`
- Packets: `meshcore/{IATA}/{DEVICE_PUBLIC_KEY}/packets`
- Raw: `meshcore/{IATA}/{DEVICE_PUBLIC_KEY}/raw`
**Example Topics**:
- `meshcore/SEA/7E7662676F7F0850A8A355BAAFBFC1EB7B4174C340442D7D7161C9474A2C9400/status`
- `meshcore/SEA/7E7662676F7F0850A8A355BAAFBFC1EB7B4174C340442D7D7161C9474A2C9400/packets`
### Step 9: Troubleshooting
#### Device Won't Connect to WiFi
**Via LoRa Repeater Console:**
```
# Check WiFi settings
get wifi.ssid
get wifi.pwd
# Reset WiFi settings
set wifi.ssid ""
set wifi.pwd ""
# Reconfigure with correct credentials
set wifi.ssid "YourWiFiNetwork"
set wifi.pwd "YourWiFiPassword"
```
#### No MQTT Messages Appearing
**Via LoRa Repeater Console:**
```
# Check bridge status
get bridge.enabled
# Check message types
get mqtt.status
get mqtt.packets
# Check device identity (origin is set automatically)
get mqtt.origin
get mqtt.iata
# Enable bridge if needed
set bridge.enabled on
```
#### Timezone Issues
**Via LoRa Repeater Console:**
```
# Check current timezone
get timezone
# Try different timezone formats
set timezone "America/New_York" # IANA format
set timezone "EST" # Abbreviation
set timezone "UTC-5" # UTC offset
```
#### LoRa Configuration Issues
- **Device not responding**: Ensure both devices are on the same mesh network
- **Commands not working**: Check that the target device is reachable via LoRa
- **No response to get commands**: Verify the device is powered and in range
### Step 10: Advanced Configuration (Optional)
#### Custom MQTT Broker
If you want to use your own MQTT broker instead of the default:
```
# Note: Custom broker configuration requires code modification
# The default broker is: meshtastic.pugetmesh.org:1883
# Username: meshdev, Password: large4cats
```
#### Let's Mesh Analyzer Servers
The device automatically connects to Let's Mesh Analyzer servers for additional monitoring:
- **US Server**: `mqtt-us-v1.letsmesh.net:443` (WebSocket with TLS)
- **EU Server**: `mqtt-eu-v1.letsmesh.net:443` (WebSocket with TLS)
These are enabled by default and use JWT authentication with your device's Ed25519 keys.
## Testing
1. Flash the MQTT bridge firmware to your device
2. Connect to the device via serial console
3. Configure WiFi connection: `set wifi.ssid "YourSSID"` and `set wifi.pwd "YourPassword"`
4. Configure timezone: `set timezone "America/Los_Angeles"`
5. Check MQTT settings: `get mqtt.origin`
6. Monitor MQTT broker for incoming messages
2. Follow the first-time setup instructions above
3. Monitor MQTT broker for incoming messages
4. Verify message formats match the JSON schemas in this document
## Dependencies
+54 -6
View File
@@ -3,6 +3,9 @@
#include "TxtDataHelpers.h"
#include "AdvertDataHelpers.h"
#include <RTClib.h>
#ifdef WITH_MQTT_BRIDGE
#include "bridges/MQTTBridge.h"
#endif
// Believe it or not, this std C function is busted on some platforms!
static uint32_t _atoi(const char* sp) {
@@ -117,9 +120,15 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
file.read((uint8_t *)&_prefs->timezone_string, sizeof(_prefs->timezone_string)); // 305
file.read((uint8_t *)&_prefs->timezone_offset, sizeof(_prefs->timezone_offset)); // 337
// MQTT server settings
file.read((uint8_t *)&_prefs->mqtt_server, sizeof(_prefs->mqtt_server)); // 340
file.read((uint8_t *)&_prefs->mqtt_port, sizeof(_prefs->mqtt_port)); // 341
file.read((uint8_t *)&_prefs->mqtt_username, sizeof(_prefs->mqtt_username)); // 342
file.read((uint8_t *)&_prefs->mqtt_password, sizeof(_prefs->mqtt_password)); // 343
// Let's Mesh Analyzer settings
file.read((uint8_t *)&_prefs->mqtt_analyzer_us_enabled, sizeof(_prefs->mqtt_analyzer_us_enabled)); // 338
file.read((uint8_t *)&_prefs->mqtt_analyzer_eu_enabled, sizeof(_prefs->mqtt_analyzer_eu_enabled)); // 339
file.read((uint8_t *)&_prefs->mqtt_analyzer_us_enabled, sizeof(_prefs->mqtt_analyzer_us_enabled)); // 344
file.read((uint8_t *)&_prefs->mqtt_analyzer_eu_enabled, sizeof(_prefs->mqtt_analyzer_eu_enabled)); // 345
// 209
>>>>>>> 6f42dc3 (Implement Let's Mesh Analyzer integration in MQTT Bridge)
@@ -246,9 +255,15 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
file.write((uint8_t *)&_prefs->timezone_string, sizeof(_prefs->timezone_string)); // 305
file.write((uint8_t *)&_prefs->timezone_offset, sizeof(_prefs->timezone_offset)); // 337
// MQTT server settings
file.write((uint8_t *)&_prefs->mqtt_server, sizeof(_prefs->mqtt_server)); // 340
file.write((uint8_t *)&_prefs->mqtt_port, sizeof(_prefs->mqtt_port)); // 341
file.write((uint8_t *)&_prefs->mqtt_username, sizeof(_prefs->mqtt_username)); // 342
file.write((uint8_t *)&_prefs->mqtt_password, sizeof(_prefs->mqtt_password)); // 343
// Let's Mesh Analyzer settings
file.write((uint8_t *)&_prefs->mqtt_analyzer_us_enabled, sizeof(_prefs->mqtt_analyzer_us_enabled)); // 338
file.write((uint8_t *)&_prefs->mqtt_analyzer_eu_enabled, sizeof(_prefs->mqtt_analyzer_eu_enabled)); // 339
file.write((uint8_t *)&_prefs->mqtt_analyzer_us_enabled, sizeof(_prefs->mqtt_analyzer_us_enabled)); // 344
file.write((uint8_t *)&_prefs->mqtt_analyzer_eu_enabled, sizeof(_prefs->mqtt_analyzer_eu_enabled)); // 345
// 209
>>>>>>> 6f42dc3 (Implement Let's Mesh Analyzer integration in MQTT Bridge)
@@ -453,6 +468,14 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
sprintf(reply, "> %s", _prefs->mqtt_tx_enabled ? "on" : "off");
} else if (memcmp(config, "mqtt.interval", 13) == 0) {
sprintf(reply, "> %d", (uint32_t)_prefs->mqtt_status_interval);
} else if (memcmp(config, "mqtt.server", 11) == 0) {
sprintf(reply, "> %s", _prefs->mqtt_server);
} else if (memcmp(config, "mqtt.port", 9) == 0) {
sprintf(reply, "> %d", _prefs->mqtt_port);
} else if (memcmp(config, "mqtt.username", 13) == 0) {
sprintf(reply, "> %s", _prefs->mqtt_username);
} else if (memcmp(config, "mqtt.password", 13) == 0) {
sprintf(reply, "> %s", _prefs->mqtt_password);
} else if (memcmp(config, "wifi.ssid", 9) == 0) {
sprintf(reply, "> %s", _prefs->wifi_ssid);
} else if (memcmp(config, "wifi.pwd", 8) == 0) {
@@ -461,10 +484,14 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
sprintf(reply, "> %s", _prefs->timezone_string);
} else if (memcmp(config, "timezone.offset", 15) == 0) {
sprintf(reply, "> %d", _prefs->timezone_offset);
} else if (memcmp(config, "mqtt.analyzer.us", 16) == 0) {
} else if (memcmp(config, "mqtt.analyzer.us", 17) == 0) {
sprintf(reply, "> %s", _prefs->mqtt_analyzer_us_enabled ? "on" : "off");
} else if (memcmp(config, "mqtt.analyzer.eu", 16) == 0) {
} else if (memcmp(config, "mqtt.analyzer.eu", 17) == 0) {
sprintf(reply, "> %s", _prefs->mqtt_analyzer_eu_enabled ? "on" : "off");
} else if (memcmp(config, "mqtt.config.valid", 17) == 0) {
// Check if MQTT configuration is valid using static method
bool valid = MQTTBridge::isConfigValid(_prefs);
sprintf(reply, "> %s", valid ? "valid" : "invalid");
#endif
} else {
sprintf(reply, "??: %s", config);
@@ -713,6 +740,27 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
} else {
strcpy(reply, "Error: timezone offset must be between -12 and +14");
}
} else if (memcmp(config, "mqtt.server ", 12) == 0) {
StrHelper::strncpy(_prefs->mqtt_server, &config[12], sizeof(_prefs->mqtt_server));
savePrefs();
strcpy(reply, "OK");
} else if (memcmp(config, "mqtt.port ", 10) == 0) {
int port = atoi(&config[10]);
if (port > 0 && port <= 65535) {
_prefs->mqtt_port = port;
savePrefs();
strcpy(reply, "OK");
} else {
strcpy(reply, "Error: port must be between 1 and 65535");
}
} else if (memcmp(config, "mqtt.username ", 14) == 0) {
StrHelper::strncpy(_prefs->mqtt_username, &config[14], sizeof(_prefs->mqtt_username));
savePrefs();
strcpy(reply, "OK");
} else if (memcmp(config, "mqtt.password ", 14) == 0) {
StrHelper::strncpy(_prefs->mqtt_password, &config[14], sizeof(_prefs->mqtt_password));
savePrefs();
strcpy(reply, "OK");
} else if (memcmp(config, "mqtt.analyzer.us ", 17) == 0) {
_prefs->mqtt_analyzer_us_enabled = memcmp(&config[17], "on", 2) == 0;
savePrefs();
+104 -12
View File
@@ -15,7 +15,7 @@ MQTTBridge::MQTTBridge(NodePrefs *prefs, mesh::PacketManager *mgr, mesh::RTCCloc
_ntp_client(_ntp_udp, "pool.ntp.org", 0, 60000), _last_ntp_sync(0), _ntp_synced(false),
_timezone(nullptr), _last_raw_len(0), _last_snr(0), _last_rssi(0), _last_raw_timestamp(0),
_analyzer_us_enabled(false), _analyzer_eu_enabled(false), _identity(identity),
_analyzer_us_client(nullptr), _analyzer_eu_client(nullptr) {
_analyzer_us_client(nullptr), _analyzer_eu_client(nullptr), _config_valid(false) {
// Initialize default values
strncpy(_origin, "MeshCore-Repeater", sizeof(_origin) - 1);
@@ -29,6 +29,26 @@ MQTTBridge::MQTTBridge(NodePrefs *prefs, mesh::PacketManager *mgr, mesh::RTCCloc
_raw_enabled = false;
_tx_enabled = false; // Disable TX packets by default
// Initialize MQTT server settings with defaults
strncpy(_prefs->mqtt_server, "your-mqtt-broker.com", sizeof(_prefs->mqtt_server) - 1);
_prefs->mqtt_port = 1883;
strncpy(_prefs->mqtt_username, "your-username", sizeof(_prefs->mqtt_username) - 1);
strncpy(_prefs->mqtt_password, "your-password", sizeof(_prefs->mqtt_password) - 1);
// Override with build flags if defined
#ifdef MQTT_SERVER
strncpy(_prefs->mqtt_server, MQTT_SERVER, sizeof(_prefs->mqtt_server) - 1);
#endif
#ifdef MQTT_PORT
_prefs->mqtt_port = MQTT_PORT;
#endif
#ifdef MQTT_USERNAME
strncpy(_prefs->mqtt_username, MQTT_USERNAME, sizeof(_prefs->mqtt_username) - 1);
#endif
#ifdef MQTT_PASSWORD
strncpy(_prefs->mqtt_password, MQTT_PASSWORD, sizeof(_prefs->mqtt_password) - 1);
#endif
// Initialize packet queue
memset(_packet_queue, 0, sizeof(_packet_queue));
@@ -39,6 +59,15 @@ MQTTBridge::MQTTBridge(NodePrefs *prefs, mesh::PacketManager *mgr, mesh::RTCCloc
void MQTTBridge::begin() {
MQTT_DEBUG_PRINTLN("Initializing MQTT Bridge...");
// Validate configuration once and store the result
_config_valid = isMQTTConfigValid();
if (!_config_valid) {
MQTT_DEBUG_PRINTLN("MQTT Bridge initialization skipped - configuration not valid");
return;
}
MQTT_DEBUG_PRINTLN("MQTT configuration is valid - proceeding with initialization");
// Update origin and IATA from preferences
strncpy(_origin, _prefs->mqtt_origin, sizeof(_origin) - 1);
_origin[sizeof(_origin) - 1] = '\0';
@@ -137,8 +166,8 @@ void MQTTBridge::begin() {
}
});
// Set default broker (meshtastic.pugetmesh.org)
setBroker(0, "meshtastic.pugetmesh.org", 1883, "meshdev", "large4cats", true);
// Set default broker from preferences or build flags
setBroker(0, _prefs->mqtt_server, _prefs->mqtt_port, _prefs->mqtt_username, _prefs->mqtt_password, true);
// Setup Let's Mesh Analyzer servers
setupAnalyzerServers();
@@ -191,6 +220,37 @@ void MQTTBridge::end() {
MQTT_DEBUG_PRINTLN("MQTT Bridge stopped");
}
bool MQTTBridge::isConfigValid() const {
return _config_valid;
}
bool MQTTBridge::isConfigValid(const NodePrefs* prefs) {
// Check if MQTT server is configured (not default placeholder)
if (strlen(prefs->mqtt_server) == 0 ||
strcmp(prefs->mqtt_server, "your-mqtt-broker.com") == 0) {
return false;
}
// Check if MQTT port is valid
if (prefs->mqtt_port == 0 || prefs->mqtt_port > 65535) {
return false;
}
// Check if MQTT username is configured (not default placeholder)
if (strlen(prefs->mqtt_username) == 0 ||
strcmp(prefs->mqtt_username, "your-username") == 0) {
return false;
}
// Check if MQTT password is configured (not default placeholder)
if (strlen(prefs->mqtt_password) == 0 ||
strcmp(prefs->mqtt_password, "your-password") == 0) {
return false;
}
return true;
}
void MQTTBridge::loop() {
if (!_initialized) return;
@@ -216,9 +276,9 @@ void MQTTBridge::loop() {
}
void MQTTBridge::onPacketReceived(mesh::Packet *packet) {
if (!_initialized || !_packets_enabled) {
MQTT_DEBUG_PRINTLN("Packet received but not processing - initialized: %s, packets_enabled: %s",
_initialized ? "true" : "false", _packets_enabled ? "true" : "false");
if (!_initialized || !_packets_enabled || !_config_valid) {
MQTT_DEBUG_PRINTLN("Packet received but not processing - initialized: %s, packets_enabled: %s, config_valid: %s",
_initialized ? "true" : "false", _packets_enabled ? "true" : "false", _config_valid ? "true" : "false");
return;
}
@@ -228,13 +288,45 @@ void MQTTBridge::onPacketReceived(mesh::Packet *packet) {
}
void MQTTBridge::sendPacket(mesh::Packet *packet) {
if (!_initialized || !_packets_enabled || !_tx_enabled) return;
if (!_initialized || !_packets_enabled || !_tx_enabled || !_config_valid) return;
// Queue packet for transmission (only if TX enabled)
queuePacket(packet, true);
}
bool MQTTBridge::isMQTTConfigValid() {
// Check if MQTT server is configured (not default placeholder)
if (strlen(_prefs->mqtt_server) == 0 ||
strcmp(_prefs->mqtt_server, "your-mqtt-broker.com") == 0) {
return false;
}
// Check if MQTT port is valid
if (_prefs->mqtt_port == 0 || _prefs->mqtt_port > 65535) {
return false;
}
// Check if MQTT username is configured (not default placeholder)
if (strlen(_prefs->mqtt_username) == 0 ||
strcmp(_prefs->mqtt_username, "your-username") == 0) {
return false;
}
// Check if MQTT password is configured (not default placeholder)
if (strlen(_prefs->mqtt_password) == 0 ||
strcmp(_prefs->mqtt_password, "your-password") == 0) {
return false;
}
return true;
}
void MQTTBridge::connectToBrokers() {
// Check if MQTT configuration is valid before attempting connection
if (!_config_valid) {
return;
}
// For now, connect to the first enabled broker
// TODO: Implement multi-broker support with PsychicMqttClient
for (int i = 0; i < MAX_MQTT_BROKERS_COUNT; i++) {
@@ -282,9 +374,9 @@ void MQTTBridge::connectToBrokers() {
}
void MQTTBridge::processPacketQueue() {
if (_queue_count == 0 || !isAnyBrokerConnected()) {
if (_queue_count == 0 || !isAnyBrokerConnected() || !_config_valid) {
if (_queue_count > 0) {
MQTT_DEBUG_PRINTLN("Queue has %d packets but no brokers connected", _queue_count);
MQTT_DEBUG_PRINTLN("Queue has %d packets but no brokers connected or config invalid", _queue_count);
}
return;
}
@@ -313,7 +405,7 @@ void MQTTBridge::processPacketQueue() {
}
void MQTTBridge::publishStatus() {
if (!isAnyBrokerConnected()) return;
if (!isAnyBrokerConnected() || !_config_valid) return;
char json_buffer[512];
char origin_id[65];
@@ -378,7 +470,7 @@ void MQTTBridge::publishStatus() {
}
void MQTTBridge::publishPacket(mesh::Packet* packet, bool is_tx) {
if (!packet) return;
if (!packet || !_config_valid) return;
char json_buffer[1024];
char origin_id[65];
@@ -426,7 +518,7 @@ void MQTTBridge::publishPacket(mesh::Packet* packet, bool is_tx) {
}
void MQTTBridge::publishRaw(mesh::Packet* packet) {
if (!packet) return;
if (!packet || !_config_valid) return;
char json_buffer[512];
char origin_id[65];
+19
View File
@@ -122,6 +122,9 @@ private:
PsychicMqttClient* _analyzer_us_client;
PsychicMqttClient* _analyzer_eu_client;
// Configuration validation state
bool _config_valid;
// Internal methods
void connectToBrokers();
void processPacketQueue();
@@ -134,6 +137,7 @@ private:
void setBrokerDefaults();
void syncTimeWithNTP();
Timezone* createTimezoneFromString(const char* tz_string);
bool isMQTTConfigValid();
public:
/**
@@ -164,6 +168,21 @@ public:
*/
void end() override;
/**
* Checks if MQTT configuration is valid
*
* @return true if all required MQTT settings are properly configured
*/
bool isConfigValid() const;
/**
* Static method to validate MQTT configuration from preferences
*
* @param prefs Node preferences containing MQTT settings
* @return true if all required MQTT settings are properly configured
*/
static bool isConfigValid(const NodePrefs* prefs);
/**
* Main loop handler
* - Maintains broker connections
+4
View File
@@ -122,6 +122,10 @@ build_flags =
-D CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y
# -D WIFI_SSID='"ssid"'
# -D WIFI_PWD='"password"'
# -D MQTT_SERVER='"your-mqtt-broker.com"'
# -D MQTT_PORT=1883
# -D MQTT_USERNAME='"your-username"'
# -D MQTT_PASSWORD='"your-password"'
; Use ESP32's built-in certificate bundle
build_src_filter = ${Heltec_lora32_v3.build_src_filter}
+7
View File
@@ -252,6 +252,13 @@ build_flags =
-D MQTT_DEBUG=1
-D MESH_PACKET_LOGGING=1
-D MESH_DEBUG=1
-D CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y
# -D WIFI_SSID='"ssid"'
# -D WIFI_PWD='"password"'
# -D MQTT_SERVER='"your-mqtt-broker.com"'
# -D MQTT_PORT=1883
# -D MQTT_USERNAME='"your-username"'
# -D MQTT_PASSWORD='"your-password"'
build_src_filter = ${Station_G2.build_src_filter}
+<helpers/bridges/MQTTBridge.cpp>
+<helpers/MQTTMessageBuilder.cpp>