kopia lustrzana https://github.com/dl9rdz/rdz_ttgo_sonde
Merge branch 'dl9rdz:devel' into devel
commit
3b51a903d6
|
@ -11,7 +11,8 @@ It also supports feeding data to external applications using WiFi (NOT bluetooth
|
||||||
- AXUDP (for aprsmap application by oe5dxl, among others)
|
- AXUDP (for aprsmap application by oe5dxl, among others)
|
||||||
- KISS TNC (aprs format, mainly useful for APRSdroid app)
|
- KISS TNC (aprs format, mainly useful for APRSdroid app)
|
||||||
- MQTT
|
- MQTT
|
||||||
- SondeHub tracker (experimental)
|
- SondeHub tracker
|
||||||
|
- Chasemapper UDP (experimental)
|
||||||
|
|
||||||
|
|
||||||
Please consult the Wiki at https://github.com/dl9rdz/rdz_ttgo_sonde/wiki/Supported-boards
|
Please consult the Wiki at https://github.com/dl9rdz/rdz_ttgo_sonde/wiki/Supported-boards
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
#include "src/aprs.h"
|
#include "src/aprs.h"
|
||||||
#include "src/ShFreqImport.h"
|
#include "src/ShFreqImport.h"
|
||||||
#include "src/RS41.h"
|
#include "src/RS41.h"
|
||||||
|
#if FEATURE_CHASEMAPPER
|
||||||
|
#include "src/Chasemapper.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if FEATURE_MQTT
|
#if FEATURE_MQTT
|
||||||
#include "src/mqtt.h"
|
#include "src/mqtt.h"
|
||||||
|
@ -537,7 +540,7 @@ const char *createLiveJson() {
|
||||||
strcpy(ptr, "{");
|
strcpy(ptr, "{");
|
||||||
|
|
||||||
SondeInfo *s = &sonde.sondeList[sonde.currentSonde];
|
SondeInfo *s = &sonde.sondeList[sonde.currentSonde];
|
||||||
sprintf(ptr + strlen(ptr), "\"rssi\": %d, \"sonde\": {\"vframe\": %d, \"time\": %d,\"id\": \"%s\", \"freq\": %3.3f, \"type\": \"%s\","
|
sprintf(ptr + strlen(ptr), "\"sonde\": {\"rssi\": %d, \"vframe\": %d, \"time\": %d,\"id\": \"%s\", \"freq\": %3.3f, \"type\": \"%s\","
|
||||||
"\"lat\": %.6f, \"lon\": %.6f, \"alt\": %.0f, \"speed\": %.1f, \"dir\": %.0f, \"climb\": %.1f, \"launchsite\": \"%s\", \"res\": %d }",
|
"\"lat\": %.6f, \"lon\": %.6f, \"alt\": %.0f, \"speed\": %.1f, \"dir\": %.0f, \"climb\": %.1f, \"launchsite\": \"%s\", \"res\": %d }",
|
||||||
s->rssi, s->vframe, s->time, s->id, s->freq, sondeTypeStr[s->type], s->lat, s->lon, s->alt, s->hs, s->dir, s->vs, s->launchsite, s->rxStat[0]);
|
s->rssi, s->vframe, s->time, s->id, s->freq, sondeTypeStr[s->type], s->lat, s->lon, s->alt, s->hs, s->dir, s->vs, s->launchsite, s->rxStat[0]);
|
||||||
|
|
||||||
|
@ -738,7 +741,12 @@ struct st_configitems config_list[] = {
|
||||||
{"tcp.port", 0, &sonde.config.tcpfeed.port},
|
{"tcp.port", 0, &sonde.config.tcpfeed.port},
|
||||||
{"tcp.idformat", -2, &sonde.config.tcpfeed.idformat},
|
{"tcp.idformat", -2, &sonde.config.tcpfeed.idformat},
|
||||||
{"tcp.highrate", 0, &sonde.config.tcpfeed.highrate},
|
{"tcp.highrate", 0, &sonde.config.tcpfeed.highrate},
|
||||||
|
#if FEATURE_CHASEMAPPER
|
||||||
|
/* Chasemapper settings */
|
||||||
|
{"cm.active", -3, &sonde.config.cm.active},
|
||||||
|
{"cm.host", 63, &sonde.config.cm.host},
|
||||||
|
{"cm.port", 0, &sonde.config.cm.port},
|
||||||
|
#endif
|
||||||
#if FEATURE_MQTT
|
#if FEATURE_MQTT
|
||||||
/* MQTT */
|
/* MQTT */
|
||||||
{"mqtt.active", 0, &sonde.config.mqtt.active},
|
{"mqtt.active", 0, &sonde.config.mqtt.active},
|
||||||
|
@ -2514,6 +2522,11 @@ void loopDecoder() {
|
||||||
Serial.print("sending: "); Serial.println(raw);
|
Serial.print("sending: "); Serial.println(raw);
|
||||||
tncclient.write(raw, rawlen);
|
tncclient.write(raw, rawlen);
|
||||||
}
|
}
|
||||||
|
#if FEATURE_CHASEMAPPER
|
||||||
|
if (sonde.config.cm.active) {
|
||||||
|
Chasemapper::send(udp, s);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#if FEATURE_SONDEHUB
|
#if FEATURE_SONDEHUB
|
||||||
if (sonde.config.sondehub.active) {
|
if (sonde.config.sondehub.active) {
|
||||||
|
|
|
@ -54,6 +54,10 @@ var cfgs = [
|
||||||
[ "mqtt.username", "MQTT username"],
|
[ "mqtt.username", "MQTT username"],
|
||||||
[ "mqtt.password", "MQTT password"],
|
[ "mqtt.password", "MQTT password"],
|
||||||
[ "mqtt.prefix", "MQTT prefix"],
|
[ "mqtt.prefix", "MQTT prefix"],
|
||||||
|
[ "", "Chasemapper settings"],
|
||||||
|
[ "cm.active", "Chasemapper active (0=disabled, 1=active)"],
|
||||||
|
[ "cm.host", "Chasemapper UDP host"],
|
||||||
|
[ "cm.port", "Chasemapper UDP port"],
|
||||||
[ "", "SondeHub settings"],
|
[ "", "SondeHub settings"],
|
||||||
[ "sondehub.active", "SondeHub reporting (0=disabled, 1=active)"],
|
[ "sondehub.active", "SondeHub reporting (0=disabled, 1=active)"],
|
||||||
[ "sondehub.chase", "SondeHub location reporting (0=off, 1=fixed, 2=chase/GPS, 3=auto)"],
|
[ "sondehub.chase", "SondeHub location reporting (0=off, 1=fixed, 2=chase/GPS, 3=auto)"],
|
||||||
|
|
|
@ -46,11 +46,12 @@ $(document).ready(function(){
|
||||||
var reddot = '<span class="ldot rbg"></span>';
|
var reddot = '<span class="ldot rbg"></span>';
|
||||||
var yellowdot = '<span class="ldot ybg"></span>';
|
var yellowdot = '<span class="ldot ybg"></span>';
|
||||||
var greendot = '<span class="ldot gbg"></span>';
|
var greendot = '<span class="ldot gbg"></span>';
|
||||||
|
var lastframe = 0;
|
||||||
|
|
||||||
$('#map .leaflet-control-container').append(L.DomUtil.create('div', 'leaflet-top leaflet-center leaflet-header'));
|
$('#map .leaflet-control-container').append(L.DomUtil.create('div', 'leaflet-top leaflet-center leaflet-header'));
|
||||||
var header = '';
|
var header = '';
|
||||||
header += '<div id="sonde_main"><b>rdzTTGOSonde LiveMap</b><br />🎈 <b><span id="sonde_id"></span> - <span id="sonde_freq"></span> MHz - <span id="sonde_type"></span></b></div>';
|
header += '<div id="sonde_main"><b>rdzTTGOSonde LiveMap</b><br />🎈 <b><span id="sonde_id"></span> - <span id="sonde_freq"></span> MHz - <span id="sonde_type"></span></b></div>';
|
||||||
header += '<div id="sonde_detail"><span id="sonde_alt"></span>m | <span id="sonde_climb"></span>m/s | <span id="sonde_speed"></span>km/h</div>';
|
header += '<div id="sonde_detail"><span id="sonde_alt"></span>m | <span id="sonde_climb"></span>m/s | <span id="sonde_speed"></span>km/h | <span id="sonde_dir"></span>°<br /><span id="sonde_time"></span> | -<span id="sonde_rssi"></span>dBm</div>';
|
||||||
header += '<div id="sonde_status"><span id="sonde_statbar"></span></div>';
|
header += '<div id="sonde_status"><span id="sonde_statbar"></span></div>';
|
||||||
header += '<div id="settings"><br /><b>Prediction-Settings</b><br />';
|
header += '<div id="settings"><br /><b>Prediction-Settings</b><br />';
|
||||||
|
|
||||||
|
@ -74,16 +75,19 @@ headtxt = function(data,stat) {
|
||||||
var staticon = (stat == '1')?greendot:yellowdot;
|
var staticon = (stat == '1')?greendot:yellowdot;
|
||||||
statbar = staticon + statbar;
|
statbar = staticon + statbar;
|
||||||
if ((statbar.length) > 10*greendot.length) { statbar = statbar.substring(0,10*greendot.length); }
|
if ((statbar.length) > 10*greendot.length) { statbar = statbar.substring(0,10*greendot.length); }
|
||||||
//if (data.lat == '0.000000') { return false; }
|
if (data.id && data.vframe != lastframe ) {
|
||||||
if (data.res == 0) {
|
lastframe = data.vframe;
|
||||||
$('#sonde_id').html(data.id);
|
$('#sonde_id').html(data.id);
|
||||||
$('#sonde_alt').html(data.alt);
|
$('#sonde_alt').html(data.alt);
|
||||||
$('#sonde_climb').html(data.climb);
|
$('#sonde_climb').html(data.climb);
|
||||||
$('#sonde_speed').html( mr(data.speed * 3.6 * 10) / 10 );
|
$('#sonde_speed').html( mr(data.speed * 3.6 * 10) / 10 );
|
||||||
|
$('#sonde_dir').html(data.dir);
|
||||||
|
$('#sonde_time').html(new Date(data.time * 1000).toISOString());
|
||||||
|
$('#sonde_rssi').html(data.rssi / 2 );
|
||||||
$('#sonde_detail').show();
|
$('#sonde_detail').show();
|
||||||
} else {
|
} else {
|
||||||
$('#sonde_id').html(data.launchsite.trim());
|
$('#sonde_id').html(data.launchsite.trim());
|
||||||
$('#sonde_detail').hide();
|
// $('#sonde_detail').hide();
|
||||||
}
|
}
|
||||||
$('#sonde_freq').html(data.freq);
|
$('#sonde_freq').html(data.freq);
|
||||||
$('#sonde_type').html(data.type);
|
$('#sonde_type').html(data.type);
|
||||||
|
@ -159,7 +163,7 @@ headtxt = function(data,stat) {
|
||||||
//console.log(data);
|
//console.log(data);
|
||||||
if (data.id) {
|
if (data.id) {
|
||||||
// data.res: 0: ok 1: no rx (timeout), 2: crc err, >2 some other error
|
// data.res: 0: ok 1: no rx (timeout), 2: crc err, >2 some other error
|
||||||
if ((data.lat != '0.000000' && data.lon != '0.000000') && (data.res==0)) { //JSON.stringify(data) != JSON.stringify(last_data)) ) {
|
if ((data.lat != '0.000000' && data.lon != '0.000000') && (lastframe != 0)) { //JSON.stringify(data) != JSON.stringify(last_data)) ) {
|
||||||
var location = [data.lat,data.lon,data.alt];
|
var location = [data.lat,data.lon,data.alt];
|
||||||
if (!marker) {
|
if (!marker) {
|
||||||
map.setView(location, 14);
|
map.setView(location, 14);
|
||||||
|
@ -180,10 +184,13 @@ headtxt = function(data,stat) {
|
||||||
}
|
}
|
||||||
dots.push(location);
|
dots.push(location);
|
||||||
line.setLatLngs(dots);
|
line.setLatLngs(dots);
|
||||||
|
}
|
||||||
|
if (data.res == 0) {
|
||||||
storage_write(data);
|
storage_write(data);
|
||||||
$('#status').html(greendot);
|
$('#status').html(greendot);
|
||||||
stat = 1;
|
stat = 1;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
$('#status').html(yellowdot);
|
$('#status').html(yellowdot);
|
||||||
stat = 0;
|
stat = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
/* data feed to sondehubv2 */
|
/* data feed to sondehubv2 */
|
||||||
/* needs about 4k4 code, 200b data, 200b stack, 200b heap */
|
/* needs about 4k4 code, 200b data, 200b stack, 200b heap */
|
||||||
#define FEATURE_SONDEHUB 1
|
#define FEATURE_SONDEHUB 1
|
||||||
|
#define FEATURE_CHASEMAPPER 1
|
||||||
#define FEATURE_MQTT 1
|
#define FEATURE_MQTT 1
|
||||||
|
|
||||||
#define FEATURE_RS92 1
|
#define FEATURE_RS92 1
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include "Chasemapper.h"
|
||||||
|
|
||||||
|
extern const char *sondeTypeStrSH[];
|
||||||
|
|
||||||
|
int Chasemapper::send(WiFiUDP &udp, SondeInfo *si) {
|
||||||
|
char buf[1024];
|
||||||
|
struct tm tim;
|
||||||
|
time_t t = si->time;
|
||||||
|
gmtime_r(&t, &tim);
|
||||||
|
uint8_t realtype = si->type;
|
||||||
|
if (TYPE_IS_METEO(realtype)) {
|
||||||
|
realtype = si->subtype == 1 ? STYPE_M10 : STYPE_M20;
|
||||||
|
}
|
||||||
|
sprintf(buf, "{ \"type\": \"PAYLOAD_SUMMARY\","
|
||||||
|
"\"callsign\": \"%s\","
|
||||||
|
"\"latitude\": %g,"
|
||||||
|
"\"longitude\": %g,"
|
||||||
|
"\"altitude\": %d,"
|
||||||
|
"\"speed\": %d,"
|
||||||
|
"\"heading\": %d,"
|
||||||
|
"\"time\": \"%02d:%02d:%02d\","
|
||||||
|
"\"model\": \"%s\","
|
||||||
|
"\"freq\": \"%.3f MHz\","
|
||||||
|
"\"temp\": %g }",
|
||||||
|
si->ser,
|
||||||
|
si->lat,
|
||||||
|
si->lon,
|
||||||
|
(int)si->alt,
|
||||||
|
(int)(si->hs * 1.9438445), // m/s into knots
|
||||||
|
(int)si->dir,
|
||||||
|
tim.tm_hour, tim.tm_min, tim.tm_sec,
|
||||||
|
sondeTypeStrSH[realtype],
|
||||||
|
si->freq,
|
||||||
|
si->temperature);
|
||||||
|
Serial.printf("Sending chasemapper json: %s\n", buf);
|
||||||
|
udp.beginPacket(sonde.config.cm.host, sonde.config.cm.port);
|
||||||
|
udp.write((const uint8_t *)buf, strlen(buf));
|
||||||
|
udp.endPacket();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef _CHASEMAPPER_H
|
||||||
|
#define _CHASEMAPPER_H
|
||||||
|
|
||||||
|
#include "Sonde.h"
|
||||||
|
//#include <WiFi.h>
|
||||||
|
#include <WiFiUdp.h>
|
||||||
|
|
||||||
|
class Chasemapper {
|
||||||
|
public:
|
||||||
|
static int send(WiFiUDP &udb, SondeInfo *si);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -3,6 +3,7 @@
|
||||||
#define Sonde_h
|
#define Sonde_h
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
enum DbgLevel { DEBUG_OFF=0, DEBUG_INFO=1, DEBUG_SPARSER=16, DEBUG_DISPLAY=8 }; // to be extended for configuring serial debug output
|
enum DbgLevel { DEBUG_OFF=0, DEBUG_INFO=1, DEBUG_SPARSER=16, DEBUG_DISPLAY=8 }; // to be extended for configuring serial debug output
|
||||||
extern uint8_t debug;
|
extern uint8_t debug;
|
||||||
|
@ -103,7 +104,7 @@ typedef struct st_sondeinfo {
|
||||||
uint32_t viewStart; // millis() timestamp of viewinf this sonde with current display
|
uint32_t viewStart; // millis() timestamp of viewinf this sonde with current display
|
||||||
int8_t lastState; // -1: disabled; 0: norx; 1: rx
|
int8_t lastState; // -1: disabled; 0: norx; 1: rx
|
||||||
// shut down timers, currently only for RS41; -1=disabled
|
// shut down timers, currently only for RS41; -1=disabled
|
||||||
int16_t launchKT, burstKT, countKT;
|
uint16_t launchKT, burstKT, countKT;
|
||||||
uint16_t crefKT; // frame number in which countKT was last sent
|
uint16_t crefKT; // frame number in which countKT was last sent
|
||||||
// sonde specific extra data, NULL if unused or not yet initialized, currently used for RS41 subframe data (calibration)
|
// sonde specific extra data, NULL if unused or not yet initialized, currently used for RS41 subframe data (calibration)
|
||||||
void *extra;
|
void *extra;
|
||||||
|
@ -187,6 +188,12 @@ struct st_mqtt {
|
||||||
char prefix[64];
|
char prefix[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct st_cm {
|
||||||
|
int active;
|
||||||
|
char host[64];
|
||||||
|
int port;
|
||||||
|
};
|
||||||
|
|
||||||
struct st_sondehub {
|
struct st_sondehub {
|
||||||
int active;
|
int active;
|
||||||
int chase;
|
int chase;
|
||||||
|
@ -260,6 +267,7 @@ typedef struct st_rdzconfig {
|
||||||
struct st_kisstnc kisstnc; // target for KISS TNC (via TCP, mainly for APRSdroid)
|
struct st_kisstnc kisstnc; // target for KISS TNC (via TCP, mainly for APRSdroid)
|
||||||
struct st_mqtt mqtt;
|
struct st_mqtt mqtt;
|
||||||
struct st_sondehub sondehub;
|
struct st_sondehub sondehub;
|
||||||
|
struct st_cm cm;
|
||||||
} RDZConfig;
|
} RDZConfig;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const char *version_name = "rdzTTGOsonde";
|
const char *version_name = "rdzTTGOsonde";
|
||||||
const char *version_id = "devel20210920";
|
const char *version_id = "devel20210921";
|
||||||
const int SPIFFS_MAJOR=2;
|
const int SPIFFS_MAJOR=2;
|
||||||
const int SPIFFS_MINOR=16;
|
const int SPIFFS_MINOR=16;
|
||||||
|
|
Ładowanie…
Reference in New Issue