Compare commits

...

8 Commits

Author SHA1 Message Date
Chris Kuethe edd492629a
Merge 03e095b0b2 into 15c5c83604 2025-01-10 19:44:54 +00:00
Chris Kuethe 03e095b0b2 MQTT Last Will and Testament
Register a message with the MQTT broker to publish if the client
loses connection. Also publish online/offline status - all to a
`status` topic.

avoid global variable
2025-01-10 11:43:11 -08:00
Hansi, dl9rdz 15c5c83604 update eph string 2025-01-09 19:14:14 +00:00
Piter-NS 985e79aa8f
Update style.css (#504)
Changes the background color when you hover over a row, making it easier to find the parameter you are changing.

Changes the font color in the .system-info class for p elements and for table headers in the dark style.
2025-01-09 19:13:47 +00:00
Chris Kuethe 36c8cb08b6
Make the firmware build without RS92 (#500)
No one's flying any around here and I thought I might disable it.
2025-01-09 19:12:49 +00:00
Chris Kuethe d814117a12
Make RSSI conversion in sonde2json runtime selectable (#506)
This allows the MQTT reporter to log RSSI in dBm, while not
confusing existing clients like rdzwx-go
2025-01-09 19:00:26 +00:00
Chris Kuethe 24bc2b9a1c
Correct representation of RSSI (#505)
SemTech data sheet says that in FSK mode,
"Actual signal power is –RssiAvg/2 (dBm)"

(resisted the impulse to fix spacing while I was there)
2025-01-08 22:22:51 +00:00
Hansi, dl9rdz a3502c8c89 remove possible startup crash cause 2025-01-08 10:02:03 +00:00
9 changed files with 64 additions and 16 deletions

View File

@ -70,6 +70,10 @@ h2.external-links {
}
.cfgpanel {
}
.cfgpanel:hover td, .cfgpanel:active td{
background-color: #808080 !important;
color: white;
}
th.cfg {
padding:5pt
@ -419,6 +423,12 @@ h1{
h2{
color: white;
}
.system-info p {
color: #bdbdbd;
}
.status-table th {
color: black;
}
table, th, td, .save, a.active {
color: white;
border: 1px solid grey;

View File

@ -34,7 +34,7 @@ const char *manufacturer_string[]={"Graw", "Vaisala", "Vaisala", "Meteomodem", "
// tiny library printf does not support $ parameters, so remove....
// for now, only urls with the right order of parameters are supported, this maybe will change in the future again.
//const char *DEFEPH="gssc.esa.int/gnss/data/daily/%1$04d/brdc/brdc%2$03d0.%3$02dn.gz";
const char *DEFEPH="gssc.esa.int/gnss/data/daily/%04d/brdc/brdc%03d0.%02dn.gz";
const char *DEFEPH="gssc.esa.int/cddis/gnss/data/daily/%04d/brdc/brdc%03d0.%02dn.gz";
int fingerprintValue[]={ 17, 31, 64, 4, 55, 48, 23, 128+23, 119, 128+119, 95, 79, -1 };
const char *fingerprintText[]={

View File

@ -37,7 +37,6 @@ TimerHandle_t mqttReconnectTimer;
extern t_wifi_state wifi_state;
char time_str[32];
/* Global initalization (on TTGO startup) */
void MQTT::init() {
}
@ -70,10 +69,16 @@ void MQTT::netsetup() {
if (strlen(sonde.config.mqtt.password) > 0) {
mqttClient.setCredentials(sonde.config.mqtt.username, sonde.config.mqtt.password);
}
char lwt[128];
snprintf(lwt, sizeof(lwt), "%sstatus", sonde.config.mqtt.prefix);
mqttClient.setWill(lwt, MQTT_QOS, MQTT_RETAIN_TRUE, "lost connection");
MQTT::connectToMqtt();
}
void MQTT::netshutdown() {
publishLwt("offline");
mqttClient.disconnect(false); // nice shutdown....
delay(200);
mqttClient.disconnect(true); // force
@ -91,6 +96,7 @@ void MQTT::updateStation( PosInfo *pi ) {
unsigned long now = millis();
if ( (lastMqttUptime == 0) || (now - lastMqttUptime >= sonde.config.mqtt.report_interval) ) {
MQTT::connectToMqtt();
publishLwt("online");
publishUptime();
publishPmuInfo();
publishGps();
@ -106,6 +112,12 @@ int MQTT::mqttGate(uint flag){
return ((sonde.config.mqtt.active & flag) && mqttClient.connected());
}
void MQTT::publishLwt(const char *message) {
char lwt[128];
snprintf(lwt, sizeof(lwt), "%sstatus", sonde.config.mqtt.prefix);
mqttClient.publish(lwt, MQTT_QOS, MQTT_RETAIN_TRUE, message);
}
int MQTT::connectToMqtt() {
if(mqttClient.connected())
return 1;
@ -115,6 +127,7 @@ int MQTT::connectToMqtt() {
return 0;
LOG_D(TAG, "MQTT not connected, connecting....");
mqttClient.connect();
publishLwt("online");
return 1;
}
@ -160,7 +173,7 @@ void MQTT::publishUptime()
LOG_D(TAG, "publishUptime: sending %s\n", payload);
char topic[128];
snprintf(topic, 128, "%s%s", sonde.config.mqtt.prefix, "uptime");
mqttClient.publish(topic, 1, 1, payload);
mqttClient.publish(topic, MQTT_QOS, MQTT_RETAIN_TRUE, payload);
}
void MQTT::publishPmuInfo()
@ -187,7 +200,7 @@ void MQTT::publishPmuInfo()
char topic[128];
snprintf(topic, sizeof(topic), "%s%s", sonde.config.mqtt.prefix, "pmu");
mqttClient.publish(topic, 1, 1, payload);
mqttClient.publish(topic, MQTT_QOS, MQTT_RETAIN_TRUE, payload);
}
@ -209,7 +222,7 @@ void MQTT::publishGps()
char topic[128];
snprintf(topic, sizeof(topic), "%s%s", sonde.config.mqtt.prefix, "gps");
mqttClient.publish(topic, 1, 1, payload);
mqttClient.publish(topic, MQTT_QOS, MQTT_RETAIN_TRUE, payload);
}
@ -225,7 +238,7 @@ void MQTT::publishPeak(double pf, int rssi)
char topic[128];
snprintf(topic, sizeof(topic), "%s%s", sonde.config.mqtt.prefix, "spectrum");
mqttClient.publish(topic, 1, /* retain */ false, payload);
mqttClient.publish(topic, MQTT_QOS_NONE, MQTT_RETAIN_FALSE, payload);
}
// What's the scanner looking at?
@ -243,7 +256,7 @@ void MQTT::publishQRG(int num, const char* type, char* launchsite, float mhz)
char topic[128];
snprintf(topic, sizeof(topic), "%s%s", sonde.config.mqtt.prefix, "qrg");
mqttClient.publish(topic, 1, /*retain*/ false, payload);
mqttClient.publish(topic, MQTT_QOS_NONE, MQTT_RETAIN_FALSE, payload);
}
@ -257,7 +270,7 @@ void MQTT::publishDebug(char *debugmsg)
snprintf(payload, 256, "{\"msg\": %s}", debugmsg);
char topic[128];
snprintf(topic, sizeof(topic), "%s%s", sonde.config.mqtt.prefix, "debug");
mqttClient.publish(topic, 1, /*retain*/ false, payload);
mqttClient.publish(topic, MQTT_QOS_NONE, MQTT_RETAIN_FALSE, payload);
}
void MQTT::publishPacket(SondeInfo *si)
@ -269,7 +282,7 @@ void MQTT::publishPacket(SondeInfo *si)
char payload[1024];
payload[0] = '{';
int n = sonde2json(payload+1, 1023, si);
int n = sonde2json(payload+1, 1023, si, true);
if(n<0) {
// ERROR
LOG_E(TAG, "publishPacket: sonde2json failed, string too long");
@ -279,7 +292,7 @@ void MQTT::publishPacket(SondeInfo *si)
char topic[128];
snprintf(topic, 128, "%s%s", sonde.config.mqtt.prefix, "packet");
LOG_D(TAG, "publishPacket: %s\n", payload);
mqttClient.publish(topic, 1, 1, payload);
mqttClient.publish(topic, MQTT_QOS, MQTT_RETAIN_TRUE, payload);
}
String MQTT::getStatus() {

View File

@ -17,6 +17,11 @@
#define MQTT_SEND_DEBUG 0x80
#define MQTT_SEND_ANY (MQTT_SEND_UPTIME|MQTT_SEND_SONDE|MQTT_SEND_PMU|MQTT_SEND_GPS|MQTT_SEND_RFINFO|MQTT_SEND_DEBUG)
#define MQTT_QOS_NONE 0
#define MQTT_QOS 1
#define MQTT_RETAIN_TRUE true
#define MQTT_RETAIN_FALSE false
class MQTT : public Conn
{
public:
@ -62,6 +67,7 @@ public:
void publishUptime();
void publishPmuInfo();
void publishGps();
void publishLwt(const char *message);
void timeFormat();
int mqttGate(uint flag);
int connectToMqtt();

View File

@ -83,11 +83,15 @@ String ConnSystem::getStatus() {
appendUptime(buf, 1024, uptime - netup_time);
appendBatt(buf, 1024);
p = strlen(buf);
snprintf(buf+p, 1024-p, " <br> rdzwxGO app: %sconnected<br>RS92 RINEX eph state: %s", rdzclient.connected()?"":"not ", rs92);
snprintf(buf+p, 1024-p, " <br> rdzwxGO app: %sconnected<br>", rdzclient.connected()?"":"not ");
#if FEATURE_RS92
p = strlen(buf);
snprintf(buf+p, 1024-p, "RS92 RINEX eph state: %s", rdzclient.connected()?"":"not ", rs92);
if(ephstate == EPH_GOOD) {
p = strlen(buf);
snprintf(buf+p, 1024-p, "[%s]", eph_nowstr);
}
#endif
// get DNS info, debug info...
String s = WiFi.dnsIP(0).toString();
strlcat(buf, "<br>DNS: ", 1024);

View File

@ -33,10 +33,17 @@ int float2json(char **buf, int *maxlen, const char *fmt, float value) {
// - MQTT
// - rdzJSON (for Android app)
// - Web map
int sonde2json(char *buf, int maxlen, SondeInfo *si)
int sonde2json(char *buf, int maxlen, SondeInfo *si, bool rssi_as_dbm)
{
SondeData *s = &(si->d);
int n;
float rssi_conversion = 1.0;
// this allows callers to get the raw reading and convert it themselves (mobile app)
// or to request the conversion to be done internally for the benefit of downstream
// consumers (mqtt subsystem, and anything else that calls this function)
if (rssi_as_dbm)
rssi_conversion = -0.5;
n = float2json(&buf, &maxlen, "\"lat\": %.5f,", s->lat);
if(n<0) return -1;
@ -69,7 +76,7 @@ int sonde2json(char *buf, int maxlen, SondeInfo *si)
"\"time\": %u,"
"\"sats\": %d,"
"\"freq\": %.2f,"
"\"rssi\": %d,"
"\"rssi\": %.1f,"
"\"afc\": %d,"
"\"launchKT\": %d,"
"\"burstKT\": %d,"
@ -85,7 +92,7 @@ int sonde2json(char *buf, int maxlen, SondeInfo *si)
s->time,
s->sats,
si->freq,
si->rssi,
si->rssi * rssi_conversion,
si->afc,
s->launchKT,
s->burstKT,

View File

@ -3,6 +3,6 @@
#include "Sonde.h"
int sonde2json(char *buf, int maxlen, SondeInfo *si);
int sonde2json(char *buf, int maxlen, SondeInfo *si, bool rssi_as_dbm=false);
#endif

View File

@ -6,7 +6,9 @@
#include <WiFi.h>
#include <WiFiUdp.h>
#if USE_BAD_DEBUGGING_CODE
extern WiFiUDP udp;
#endif
extern boolean connected;
@ -57,10 +59,12 @@ void Logger::sendImprov(int type, int len, const char *data) {
buf[9+len+1] = '\n';
buf[9+len+2] = 0;
Serial.write(buf, 9+len+2);
#if USE_BAD_DEBUGGING_CODE
udp.beginPacket("192.168.1.3", 12345);
udp.write((const uint8_t *)"Reply:",6);
udp.write((const uint8_t *)buf, 9+len+2);
udp.endPacket();
#endif
}
void Logger::sendImprovResult(int replyto, const char *strings[]) {
@ -89,10 +93,12 @@ void Logger::sendImprovResult(int replyto, const char *strings[]) {
buf[i++] = '\n';
buf[i++] = 0;
Serial.write(buf, i-1);
#if USE_BAD_DEBUGGING_CODE
udp.beginPacket("192.168.1.3", 12345);
udp.write((const uint8_t *)"Reply:",6);
udp.write((const uint8_t *)buf, i-1);
udp.endPacket();
#endif
}
int cmdlen = 0;
@ -131,9 +137,11 @@ void Logger::handleImprov() {
while(Serial.available()) {
cmd[cmdlen] = Serial.read();
if(cmd[cmdlen] == '\n') { // check if command
#if USE_BAD_DEBUGGING_CODE
udp.beginPacket("192.168.1.3", 12345);
udp.write((const uint8_t *)cmd, cmdlen+1);
udp.endPacket();
#endif
if(strncmp(cmd, "IMPROV", 6)==0) { // we have a command
// TODO: CHeck CRC
if(cmd[7]==0x03 && cmd[9]==0x03) { // RPC, get info

View File

@ -1,4 +1,4 @@
const char *version_name = "rdzTTGOsonde";
const char *version_id = "dev20241229";
const char *version_id = "dev20250108";
const int FS_MAJOR=3;
const int FS_MINOR=3;