kopia lustrzana https://github.com/dl9rdz/rdz_ttgo_sonde
mqtt initial implementation
rodzic
5bc751d261
commit
dcd93dfe97
|
@ -22,6 +22,11 @@ before_install:
|
|||
- wget https://github.com/lewisxhe/AXP202X_Library/archive/v1.0.zip
|
||||
- unzip v1.0.zip
|
||||
- sudo mv AXP202X_Library-1.0 /usr/local/share/arduino/libraries/
|
||||
|
||||
- wget https://github.com/dx168b/async-mqtt-client/archive/master.zip
|
||||
- unzip master.zip
|
||||
- sudo mv async-mqtt-client-master /usr/local/share/arduino/libraries/
|
||||
|
||||
# Trying to get rid of mDNS warnings (1000s of them...)
|
||||
# as suggested by https://forum.arduino.cc/index.php?topic=469428.0
|
||||
# Arduino IDE adds a lot of noise caused by network traffic, trying to firewall it off
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "geteph.h"
|
||||
#include "rs92gps.h"
|
||||
|
||||
#include "mqtt.h"
|
||||
|
||||
#ifdef TTGO_V2
|
||||
// platformio currently fails to build with board v2 so ve override v1 pins instead
|
||||
#define OLED_SDA 4
|
||||
|
@ -57,6 +59,10 @@ WiFiClient client;
|
|||
WiFiServer tncserver(14580);
|
||||
WiFiClient tncclient;
|
||||
|
||||
unsigned long lastMqttUptime = 0;
|
||||
boolean mqttEnabled;
|
||||
MQTT mqttclient;
|
||||
|
||||
boolean forceReloadScreenConfig = false;
|
||||
|
||||
enum KeyPress { KP_NONE = 0, KP_SHORT, KP_DOUBLE, KP_MID, KP_LONG };
|
||||
|
@ -468,6 +474,16 @@ struct st_configitems config_list[] = {
|
|||
{"tcp.port", "APRS TCP Port", 0, &sonde.config.tcpfeed.port},
|
||||
{"tcp.idformat", "DFM ID Format", -2, &sonde.config.tcpfeed.idformat},
|
||||
{"tcp.highrate", "Rate limit", 0, &sonde.config.tcpfeed.highrate},
|
||||
|
||||
/* MQTT */
|
||||
{"mqtt.active", "MQTT Active (needs reboot)", 0, &sonde.config.mqtt.active},
|
||||
{"mqtt.id", "MQTT client ID", 63, &sonde.config.mqtt.id},
|
||||
{"mqtt.host", "MQTT server IP address", 63, &sonde.config.mqtt.host},
|
||||
{"mqtt.port", "MQTT Port", 0, &sonde.config.mqtt.port},
|
||||
{"mqtt.username", "MQTT Username", 63, &sonde.config.mqtt.username},
|
||||
{"mqtt.password", "MQTT Password", 63, &sonde.config.mqtt.password},
|
||||
{"mqtt.prefix", "MQTT Prefix", 63, &sonde.config.mqtt.prefix},
|
||||
|
||||
/* Hardware dependeing settings */
|
||||
{"", "Hardware configuration (requires reboot)", -5, NULL},
|
||||
{"disptype", "Display type (0=OLED/SSD1306, 1=TFT/ILI9225, 2=OLED/SH1106)", 0, &sonde.config.disptype},
|
||||
|
@ -487,6 +503,7 @@ struct st_configitems config_list[] = {
|
|||
{"gps_rxd", "GPS RXD pin (-1 to disable)", 0, &sonde.config.gps_rxd},
|
||||
{"gps_txd", "GPS TXD pin (not really needed)", 0, &sonde.config.gps_txd},
|
||||
{"mdnsname", "mDNS name", 14, &sonde.config.mdnsname},
|
||||
|
||||
};
|
||||
const static int N_CONFIG = (sizeof(config_list) / sizeof(struct st_configitems));
|
||||
|
||||
|
@ -1691,6 +1708,7 @@ void loopDecoder() {
|
|||
//Send a packet with position information
|
||||
// first check if ID and position lat+lonis ok
|
||||
SondeInfo *s = &sonde.sondeList[rxtask.receiveSonde];
|
||||
|
||||
if (s->validID && ((s->validPos & 0x03) == 0x03)) {
|
||||
const char *str = aprs_senddata(s, sonde.config.call, sonde.config.udpfeed.symbol);
|
||||
if (connected) {
|
||||
|
@ -1710,6 +1728,13 @@ void loopDecoder() {
|
|||
tncclient.write(raw, rawlen);
|
||||
}
|
||||
}
|
||||
|
||||
// send to MQTT if enabled
|
||||
if (connected && mqttEnabled) {
|
||||
Serial.println("Sending sonde info via MQTT");
|
||||
mqttclient.publishPacket(s);
|
||||
}
|
||||
|
||||
// also send to web socket
|
||||
//TODO
|
||||
}
|
||||
|
@ -1795,6 +1820,7 @@ String translateEncryptionType(wifi_auth_mode_t encryptionType) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void enableNetwork(bool enable) {
|
||||
if (enable) {
|
||||
MDNS.begin(sonde.config.mdnsname);
|
||||
|
@ -1804,6 +1830,12 @@ void enableNetwork(bool enable) {
|
|||
if (sonde.config.kisstnc.active) {
|
||||
tncserver.begin();
|
||||
}
|
||||
|
||||
if (sonde.config.mqtt.active && strlen(sonde.config.mqtt.host) > 0) {
|
||||
mqttEnabled = true;
|
||||
mqttclient.init(sonde.config.mqtt.host, sonde.config.mqtt.port, sonde.config.mqtt.id, sonde.config.mqtt.username, sonde.config.mqtt.password, sonde.config.mqtt.prefix);
|
||||
}
|
||||
|
||||
connected = true;
|
||||
} else {
|
||||
MDNS.end();
|
||||
|
@ -2367,5 +2399,12 @@ void loop() {
|
|||
sonde.updateDisplay();
|
||||
lastDisplay = currentDisplay;
|
||||
}
|
||||
|
||||
int now = millis();
|
||||
if (mqttEnabled && (lastMqttUptime == 0 || (lastMqttUptime + 60000 < now) || (lastMqttUptime > now))) {
|
||||
mqttclient.publishUptime();
|
||||
lastMqttUptime = now;
|
||||
}
|
||||
|
||||
Serial.printf("Unused stack: %d\n", uxTaskGetStackHighWaterMark(0));
|
||||
}
|
||||
|
|
|
@ -96,5 +96,16 @@ tcp.symbol=/O
|
|||
tcp.highrate=20
|
||||
tcp.idformat=0
|
||||
#-------------------------------#
|
||||
# mqtt settings
|
||||
#-------------------------------#
|
||||
# data not sanitized / quality checked, outliers not filtered out
|
||||
mqtt.active=0
|
||||
mqtt.id=rdz_sonde_server
|
||||
mqtt.ip=/0
|
||||
mqtt.port=1883
|
||||
mqtt.username=/0
|
||||
mqtt.password=/0
|
||||
mqtt.prefix=rdz_sonde_server/
|
||||
#-------------------------------#
|
||||
# EOF
|
||||
#-------------------------------#
|
||||
|
|
3
Setup.md
3
Setup.md
|
@ -49,6 +49,9 @@ of your Arduino IDE, and rename main folder to AsyncTCP
|
|||
From https://github.com/lewisxhe/AXP202X_Library select "Download ZIP", extract to the libraries
|
||||
folder of your Arduino IDE, and rename main folder to AXP202X_Library-1.0
|
||||
|
||||
From https://github.com/dx168b/async-mqtt-client select "Download ZIP", extract to the libraries
|
||||
folder of your Arduino IDE, and rename main folder to async-mqtt-client
|
||||
|
||||
## Additional libraries, part 3
|
||||
|
||||
Copy the SX1278FSK, SondeLib and fonts folders from libraries of this project to your Arduino IDE's libraries
|
||||
|
|
|
@ -189,6 +189,13 @@ void Sonde::defaultConfig() {
|
|||
config.tcpfeed.highrate = 10;
|
||||
config.tcpfeed.idformat = ID_DFMDXL;
|
||||
config.kisstnc.active = 0;
|
||||
|
||||
config.mqtt.active = 0;
|
||||
strcpy(config.mqtt.id, "rdz_sonde_server");
|
||||
config.mqtt.port = 1883;
|
||||
strcpy(config.mqtt.username, "/0");
|
||||
strcpy(config.mqtt.password, "/0");
|
||||
strcpy(config.mqtt.prefix, "rdz_sonde_server/");
|
||||
}
|
||||
|
||||
void Sonde::setConfig(const char *cfg) {
|
||||
|
@ -314,6 +321,22 @@ void Sonde::setConfig(const char *cfg) {
|
|||
config.tcpfeed.highrate = atoi(val);
|
||||
} else if(strcmp(cfg,"tcp.idformat")==0) {
|
||||
config.tcpfeed.idformat = atoi(val);
|
||||
|
||||
} else if(strcmp(cfg,"mqtt.active")==0) {
|
||||
config.mqtt.active = atoi(val)>0;
|
||||
} else if(strcmp(cfg,"mqtt.id")==0) {
|
||||
strncpy(config.mqtt.id, val, 63);
|
||||
} else if(strcmp(cfg,"mqtt.host")==0) {
|
||||
strncpy(config.mqtt.host, val, 63);
|
||||
} else if(strcmp(cfg,"mqtt.port")==0) {
|
||||
config.mqtt.port = atoi(val);
|
||||
} else if(strcmp(cfg,"mqtt.username")==0) {
|
||||
strncpy(config.mqtt.username, val, 63);
|
||||
} else if(strcmp(cfg,"mqtt.password")==0) {
|
||||
strncpy(config.mqtt.password, val, 63);
|
||||
} else if(strcmp(cfg,"mqtt.prefix")==0) {
|
||||
strncpy(config.mqtt.prefix, val, 63);
|
||||
|
||||
} else {
|
||||
Serial.printf("Invalid config option '%s'=%s \n", cfg, val);
|
||||
}
|
||||
|
|
|
@ -144,6 +144,15 @@ struct st_kisstnc {
|
|||
int idformat;
|
||||
};
|
||||
|
||||
struct st_mqtt {
|
||||
bool active;
|
||||
char id[64];
|
||||
char host[64];
|
||||
int port;
|
||||
char username[64];
|
||||
char password[64];
|
||||
char prefix[64];
|
||||
};
|
||||
|
||||
typedef struct st_rdzconfig {
|
||||
// hardware configuration
|
||||
|
@ -188,6 +197,7 @@ typedef struct st_rdzconfig {
|
|||
struct st_feedinfo udpfeed; // target for AXUDP messages
|
||||
struct st_feedinfo tcpfeed; // target for APRS-IS TCP connections
|
||||
struct st_kisstnc kisstnc; // target for KISS TNC (via TCP, mainly for APRSdroid)
|
||||
struct st_mqtt mqtt;
|
||||
} RDZConfig;
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
#include <Arduino.h>
|
||||
#include "mqtt.h"
|
||||
#include <WiFi.h>
|
||||
#include <AsyncMqttClient.h>
|
||||
|
||||
void mqttCallback(char* topic, byte* payload, unsigned int length) {
|
||||
Serial.print("Message arrived [");
|
||||
Serial.print(topic);
|
||||
Serial.print("] ");
|
||||
for (int i=0;i<length;i++) {
|
||||
Serial.print((char)payload[i]);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void MQTT::init(const char* ip, uint16_t port, const char* id, const char *username, const char *password, const char *prefix)
|
||||
{
|
||||
this->ip = this->ip.fromString(ip);
|
||||
this->port = port;
|
||||
this->username = username;
|
||||
this->password = password;
|
||||
this->prefix = prefix;
|
||||
|
||||
char buffer[20];
|
||||
snprintf(buffer, 20, "%s%d", id, random(0, 1000));
|
||||
this->id = buffer;
|
||||
|
||||
Serial.println("[MQTT] pubsub client");
|
||||
mqttClient.setServer(ip, port);
|
||||
if (strlen(password) > 0) {
|
||||
mqttClient.setCredentials(username, password);
|
||||
}
|
||||
mqttClient.connect();
|
||||
|
||||
//mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, connectToMqtt);
|
||||
}
|
||||
|
||||
void MQTT::connectToMqtt() {
|
||||
Serial.println("Connecting to MQTT...");
|
||||
mqttClient.connect();
|
||||
}
|
||||
|
||||
void MQTT::publishUptime()
|
||||
{
|
||||
Serial.println("[MQTT] writing");
|
||||
char payload[12];
|
||||
snprintf(payload, 12, "%lu", millis());
|
||||
char topic[128];
|
||||
snprintf(topic, 128, "%s%s", this->prefix, "uptime");
|
||||
mqttClient.publish(topic, 1, 1, payload);
|
||||
}
|
||||
|
||||
void MQTT::publishPacket(SondeInfo *s)
|
||||
{
|
||||
char payload[1024];
|
||||
snprintf(payload, 1024, "{"
|
||||
"\"active\": %d,"
|
||||
"\"freq\": %.2f,"
|
||||
"\"id\": \"%s\","
|
||||
"\"ser\": \"%s\","
|
||||
"\"validId\": %d,"
|
||||
"\"launchsite\": \"%s\","
|
||||
"\"lat\": %.5f,"
|
||||
"\"lon\": %.5f,"
|
||||
"\"alt\": %.1f,"
|
||||
"\"vs\": %.1f,"
|
||||
"\"hs\": %.1f,"
|
||||
"\"dir\": %.1f,"
|
||||
"\"sats\": %d,"
|
||||
"\"validPos\": %d,"
|
||||
"\"time\": %d,"
|
||||
"\"sec\": %d,"
|
||||
"\"frame\": %d,"
|
||||
"\"validTime\": %d,"
|
||||
"\"rssi\": %d,"
|
||||
"\"afc\": %d,"
|
||||
"\"rxStat\": \"%s\","
|
||||
"\"rxStart\": %d,"
|
||||
"\"norxStart\": %d,"
|
||||
"\"viewStart\": %d,"
|
||||
"\"lastState\": %d,"
|
||||
"\"launchKT\": %d,"
|
||||
"\"burstKT\": %d,"
|
||||
"\"countKT\": %d,"
|
||||
"\"crefKT\": %d,"
|
||||
"}",
|
||||
(int)s->active,
|
||||
s->freq,
|
||||
s->id,
|
||||
s->ser,
|
||||
(int)s->validID,
|
||||
s->launchsite,
|
||||
s->lat,
|
||||
s->lon,
|
||||
s->alt,
|
||||
s->vs,
|
||||
s->hs,
|
||||
s->dir,
|
||||
s->sats,
|
||||
s->validPos,
|
||||
s->time,
|
||||
s->sec,
|
||||
s->frame,
|
||||
(int)s->validTime,
|
||||
s->rssi,
|
||||
s->afc,
|
||||
s->rxStat,
|
||||
s->rxStart,
|
||||
s->norxStart,
|
||||
s->viewStart,
|
||||
s->lastState,
|
||||
s->launchKT,
|
||||
s->burstKT,
|
||||
s->countKT,
|
||||
s->crefKT
|
||||
);
|
||||
|
||||
char topic[128];
|
||||
snprintf(topic, 128, "%s%s", this->prefix, "packet");
|
||||
mqttClient.publish(topic, 1, 1, payload);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef MQTT_h
|
||||
#define MQTT_h
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <AsyncMqttClient.h>
|
||||
#include "Sonde.h"
|
||||
|
||||
class MQTT
|
||||
{
|
||||
public:
|
||||
WiFiClient mqttWifiClient;
|
||||
AsyncMqttClient mqttClient;
|
||||
TimerHandle_t mqttReconnectTimer;
|
||||
IPAddress ip;
|
||||
uint16_t port;
|
||||
const char *id;
|
||||
const char *username;
|
||||
const char *password;
|
||||
const char *prefix;
|
||||
|
||||
void init(const char *ip, uint16_t port, const char *id, const char *username, const char *password, const char *prefix);
|
||||
void publishPacket(SondeInfo *s);
|
||||
void publishUptime();
|
||||
private:
|
||||
void connectToMqtt();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -24,18 +24,10 @@ lib_deps_external =
|
|||
stevemarple/MicroNMEA @ ^2.0.3
|
||||
nkawu/TFT 22 ILI9225 @ ^1.4.4
|
||||
me-no-dev/ESP Async WebServer @ ^1.2.3
|
||||
|
||||
[env:ttgo-lora32-v1]
|
||||
platform = espressif32
|
||||
board = ttgo-lora32-v1
|
||||
framework = arduino
|
||||
monitor_speed = 115200
|
||||
lib_deps =
|
||||
${extra.lib_deps_builtin}
|
||||
${extra.lib_deps_external}
|
||||
|
||||
[env:ttgo-lora32-v2]
|
||||
platform = espressif32
|
||||
https://github.com/dx168b/async-mqtt-client
|
||||
|
||||
[env:ttgo-lora32]
|
||||
platform = espressif32@1.12.4
|
||||
board = ttgo-lora32-v1
|
||||
framework = arduino
|
||||
monitor_speed = 115200
|
||||
|
|
Ładowanie…
Reference in New Issue