add V_batt in status, gps fix, pin check in config form

This commit is contained in:
Hansi, dl9rdz 2024-08-18 16:01:52 +00:00
parent 9c75680a9b
commit cf781c991c
10 changed files with 131 additions and 20 deletions

View File

@ -312,11 +312,16 @@ void setupChannelList() {
}
const char *HTMLHEAD = "<!DOCTYPE html><html><head> <meta charset=\"UTF-8\"> <link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\">";
void HTMLBODY(char *ptr, const char *which) {
void HTMLBODY_OS(char *ptr, const char *which, const char *onsubmit) {
strcat(ptr, "<body><form class=\"wrapper\" action=\"");
strcat(ptr, which);
if(onsubmit) {
strcat(ptr, "\" onsubmit=\"");
strcat(ptr, onsubmit);
}
strcat(ptr, "\" method=\"post\"><div class=\"content\">");
}
void HTMLBODY(char *ptr, const char *which) { HTMLBODY_OS(ptr, which, NULL); }
void HTMLBODYEND(char *ptr) {
strcat(ptr, "</div></form></body></html>");
}
@ -737,7 +742,7 @@ const char *createConfigForm() {
char *ptr = message;
strcpy(ptr, HTMLHEAD);
strcat(ptr, "<script src=\"rdz.js\"></script></head>");
HTMLBODY(ptr, "config.html");
HTMLBODY_OS(ptr, "config.html", "return checkForDuplicates()");
strcat(ptr, "<div id=\"cfgtab\"></div>");
strcat(ptr, "<script src=\"cfg.js\"></script>");
strcat(ptr, "<script>\n");

View File

@ -95,7 +95,7 @@ var cfgs = [
[ "power_pout", "Power control port"],
[ "led_pout", "LED output port"],
[ "gps_rxd", "GPS RXD pin (-1 to disable)"],
[ "gps_txd", "GPS TXD pin (not really needed)"],
[ "gps_txd", "GPS TXD pin (optional, only for GSP reset)"],
[ "batt_adc", "Battery measurement pin"],
[ "sx1278_ss", "SX1278 SS"],
[ "sx1278_miso", "SX1278 MISO"],
@ -103,6 +103,72 @@ var cfgs = [
[ "sx1278_sck", "SX1278 SCK"],
];
var tocheck = ["sd.cs", "sd.miso", "sd.mosi", "sd.clk", "oled_sda", "oled_scl", "oled_rst", "tft_rs", "tft_cs", "tft_spifreq", "button_pin", "button2_pin",
"led_pout", "gps_rxd", "gps_txd", "batt_adc", "sx1278_ss", "sx1278_miso", "sx1278_mosi", "sx1278_sck"];
var alloweddups = [ ["sd.mosi", "oled_sda"], ["sd.clk", "oled_scl" ] ];
function isAllowedDup(nameA, nameB) {
for (var i = 0; i < alloweddups.length; i++) {
var pair = alloweddups[i];
if ((pair[0] === nameA && pair[1] === nameB) || (pair[0] === nameB && pair[1] === nameA)) {
return true;
}
}
return false;
}
// Function to check for duplicate pins
function checkForDuplicates() {
// Create an object to store values and their associated descriptions and names
var valuesMap = {};
var duplicates = [];
// Iterate through the tocheck array
for (var i = 0; i < tocheck.length; i++) {
var inputName = tocheck[i];
var inputValue = parseInt(document.getElementsByName(inputName)[0].value, 10);
// Skip empty values or values that are -1
if (isNaN(inputValue) || inputValue === -1) {
continue;
}
var cfg = cfgs.find(item => item[0] === inputName);
var descriptionB = cfg ? cfg[1] : "";
// Check if the value is already in the map
if (valuesMap[inputValue]) {
var existingEntry = valuesMap[inputValue];
var nameA = existingEntry.name;
var descriptionA = existingEntry.description;
// Check if the duplicate is allowed
if (!isAllowedDup(nameA, inputName)) {
duplicates.push({ value: inputValue, descA: descriptionA, descB: descriptionB });
}
} else {
// Otherwise, store the value with its description and name
valuesMap[inputValue] = { name: inputName, description: descriptionB };
}
}
// If duplicates were found, show the warning popup
if (duplicates.length > 0) {
var message = "Duplicated PIN assignments found:\n";
for (var j = 0; j < duplicates.length; j++) {
message += "Pin " + duplicates[j].value + " in '" + duplicates[j].descA + "' and '" + duplicates[j].descB + "'\n";
}
// Show a confirm popup to let the user decide whether to submit the form
if (!confirm(message + "\nDo you want to submit the form anyway?")) {
// If the user chooses to cancel, prevent the form submission
return false;
}
}
// Allow form submission
return true;
}
function mkcfg(id, key, label, value) {
var s = "<tr style=\"visibility: collapse;\" class=\"cfgpanel\"><td>" + label + "</td><td><input name=\"" + key + "\" type=\"text\" value=\"" + value + "\"/></td></tr>\n";
return s;

View File

@ -100,15 +100,15 @@ ephftp=gssc.esa.int/gnss/data/daily/
axudp.active=1
axudp.host=192.168.42.20
axudp.port=9002
axudp.symbol=/O
axudp.highrate=1
axudp.ratelimit=1
#-------------------------------#
# connect to some aprs server
#-------------------------------#
tcp.active=0
tcp.host=radiosondy.info
tcp.port=14590
tcp.symbol=/O
tcp.host=radiosondy.info:14590
#tcp.host2=wettersonde.net:14590
# Currently this is fixed...
# tcp.symbol=/O
tcp.highrate=20
# send beacon (possibly with different call or SSID)
tcp.chase=0
@ -121,7 +121,7 @@ tcp.comment=
# data not sanitized / quality checked, outliers not filtered out
mqtt.active=0
mqtt.id=rdz_sonde_server
mqtt.ip=192.168.1.5
mqtt.host=192.168.1.5
mqtt.port=1883
mqtt.username=
mqtt.password=
@ -139,10 +139,10 @@ sondehub.email=
#-------------------------------#
# Sondehub freq import settings
#-------------------------------#
shfimp.active=0
shfimp.interval=60
shfimp.maxdist=150
shfimp.maxage=6
sondehub.fiactive=0
sondehub.fiinterval=60
sondehub.fimaxdist=150
sondehub.fimaxage=6
#-------------------------------#
# EOF
#-------------------------------#

View File

@ -120,6 +120,9 @@ void Sonde::defaultConfig() {
config.norx_timeout = 20;
config.screenfile = 1;
config.tft_spifreq = SPI_DEFAULT_FREQ;
// TFT RS and CS not used for LCD, if TFT detected this will be changed below
config.tft_rs = -1;
config.tft_cs = -1;
if(initlevels[16]==0) {
config.oled_sda = 4;
config.oled_scl = 15;

View File

@ -142,7 +142,7 @@ void ConnSDCard::updateStation( PosInfo *pi ) {
}
String ConnSDCard::getStatus() {
if(sonde.config.sd.cs == -1) { return String("Disabled"); }
if(sonde.config.sd.cs == -1) { return String("disabled"); }
if(!initok) { return String("SD card init failed"); }
uint8_t cardType = SD.cardType();

View File

@ -78,6 +78,8 @@ void ConnSondehub::netsetup() {
// each second, if good decode: sondehub_send_data
// each second, if no good decode: sondehub_finish_data
void ConnSondehub::updateSonde( SondeInfo *si ) {
if (!sonde.config.sondehub.active)
return;
Serial.println("SH: updateSonde called");
sondehub_client_fsm();
@ -91,6 +93,8 @@ void ConnSondehub::updateSonde( SondeInfo *si ) {
void ConnSondehub::updateStation( PosInfo *pi ) {
if (!sonde.config.sondehub.active)
return;
Serial.println("SH: updateStation called");
sondehub_client_fsm();
// Currently, internal reply_handler uses gpsInfo global variable instead of this pi
@ -714,13 +718,16 @@ void ConnSondehub::sondehub_send_last() {
String ConnSondehub::getStatus() {
char info[1200];
time_t now;
if(sonde.config.sondehub.active==0) {
strcpy(info, "disabled");
} else {
time(&now);
if(shStart==0) now=-1;
snprintf(info, 1200, "State: %s. Last upload start: %ld s ago<br>Last reply: ",
state2str(shclient_state), (uint32_t)(now-shStart));
int n = strlen(info);
escapeJson(info+n, rs_msg, 1200-n);
}
return String(info);
}

View File

@ -3,6 +3,7 @@
#include <WiFi.h>
#include "geteph.h"
#include "pmu.h"
extern uint32_t netup_time;
extern char eph_nowstr[];
@ -27,6 +28,20 @@ String ConnSystem::getName() {
extern WiFiClient rdzclient;
extern PMU *pmu;
static void appendBatt(char *buf, int maxlen) {
float batt;
if(!pmu) {
if(sonde.config.batt_adc<0) return;
batt = (float)(analogRead(sonde.config.batt_adc)) / 4095 * 2 * 3.3 * 1.1;
} else {
batt = pmu->getBattVoltage() * 0.001;
}
int p = strlen(buf);
snprintf(buf+p, maxlen-p, ", Batt: %.2fV", batt);
}
String ConnSystem::getStatus() {
/* Special connector for obtaining system status.... */
// uptime
@ -50,11 +65,18 @@ String ConnSystem::getStatus() {
snprintf(buf, 1024, "Autodetect info: Fingerprint %d (", sonde.fingerprint);
int p = strlen(buf);
escapeJson(buf+p, fpstr, 1024-p);
strlcat(buf, ")<br>Uptime: ", 1024);
char nowstr[30];
time_t now;
struct tm timeinfo;
time(&now);
gmtime_r(&now, &timeinfo);
strftime(nowstr, 30, "%Y-%m-%dT%H:%M:%S", &timeinfo);
p = strlen(buf);
snprintf(buf+p, 1024-p, ")<br>%s, Uptime: ", nowstr);
appendUptime(buf, 1024, uptime);
strlcat(buf, ", WiFi uptime: ", 1024);
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);
if(ephstate == EPH_GOOD) {

View File

@ -50,6 +50,7 @@ static MicroNMEA nmea(buffer, sizeof(buffer));
template<typename T>
//void unkHandler(const MicroNMEA& nmea) {
void unkHandler(T nmea) {
//Serial.println(nmea.getSentence());
if (strcmp(nmea.getMessageID(), "VTG") == 0) {
const char *s = nmea.getSentence();
while (*s && *s != ',') s++;
@ -216,7 +217,7 @@ void initGPS() {
delay(1000);
dumpGPS();
LittleFS.remove("/GPSRESET");
} else if (testfile) {
} else {
Serial.println("GPS reset file: not found/isdir");
testfile.close();
Serial2.begin(9600, SERIAL_8N1, sonde.config.gps_rxd, sonde.config.gps_txd);

View File

@ -1,4 +1,4 @@
const char *version_name = "rdzTTGOsonde";
const char *version_id = "dev20240815";
const char *version_id = "dev20240817";
const int SPIFFS_MAJOR=3;
const int SPIFFS_MINOR=1;
const int SPIFFS_MINOR=2;

View File

@ -41,3 +41,10 @@ env.AddPostAction("$PROGPATH",
"xtensa-esp32-elf-ld", "-T", "fontlink.ld", "--oformat=binary", "-o", "$BUILD_DIR/fonts.bin", "$BUILD_DIR/src/src/fonts/fonts.cpp.o" ]),
"Building $BUILD_DIR/fonts.bin"))
env.AddCustomTarget(
"uploadfonts",
"$BUILD_DIR/${PROGNAME}.bin",
"scripts/uploadfonts.py $BUILD_DIR/fonts.bin $PARTITIONS_TABLE_CSV"
)