mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-08-28 11:34:58 +00:00
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:
+230
-5
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user