telemetry EUP beacon update

This commit is contained in:
Ricardo Guzman (Richonguzman)
2026-02-24 07:55:32 -03:00
parent 09e06d36e8
commit db4582db13
4 changed files with 56 additions and 52 deletions

View File

@@ -1,17 +1,17 @@
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU /* Copyright (C) 2025 Ricardo Guzman - CA2RXU
* *
* This file is part of LoRa APRS iGate. * This file is part of LoRa APRS iGate.
* *
* LoRa APRS iGate is free software: you can redistribute it and/or modify * LoRa APRS iGate is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* LoRa APRS iGate is distributed in the hope that it will be useful, * LoRa APRS iGate is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>. * along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
*/ */
@@ -27,7 +27,8 @@ namespace TELEMETRY_Utils {
void sendEquationsUnitsParameters(); void sendEquationsUnitsParameters();
String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType); String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType);
String generateEncodedTelemetry(); String generateEncodedTelemetry();
void checkEUPInterval();
} }
#endif #endif

View File

@@ -40,6 +40,7 @@ std::vector<LastHeardStation> lastHeardObjects;
struct OutputPacketBuffer { struct OutputPacketBuffer {
String packet; String packet;
bool isBeacon; bool isBeacon;
OutputPacketBuffer(const String& p, bool b) : packet(p), isBeacon(b) {}
}; };
std::vector<OutputPacketBuffer> outputPacketBuffer; std::vector<OutputPacketBuffer> outputPacketBuffer;
@@ -57,19 +58,18 @@ namespace STATION_Utils {
std::vector<String> loadCallsignList(const String& list) { std::vector<String> loadCallsignList(const String& list) {
std::vector<String> loadedList; std::vector<String> loadedList;
int start = 0;
int listLength = list.length();
String callsigns = list; while (start < listLength) {
callsigns.trim(); while (start < listLength && list[start] == ' ') start++; // avoid blank spaces
if (start >= listLength) break;
while (callsigns.length() > 0) { // != "" int end = start;
int spaceIndex = callsigns.indexOf(" "); while (end < listLength && list[end] != ' ') end++; // find another blank space or reach listLength
if (spaceIndex == -1) { // No more spaces, add the last part
loadedList.push_back(callsigns); loadedList.emplace_back(list.substring(start, end));
break; start = end + 1; // keep on searching if listLength not reached
}
loadedList.push_back(callsigns.substring(0, spaceIndex));
callsigns = callsigns.substring(spaceIndex + 1);
callsigns.trim(); // Trim in case of multiple spaces
} }
return loadedList; return loadedList;
} }
@@ -126,36 +126,33 @@ namespace STATION_Utils {
} }
void deleteNotHeard() { void deleteNotHeard() {
std::vector<LastHeardStation> lastHeardStation_temp; uint32_t currentTime = millis();
for (int i = 0; i < lastHeardStations.size(); i++) { uint32_t timeout = Config.rememberStationTime * 60UL * 1000UL;
if (millis() - lastHeardStations[i].lastHeardTime < Config.rememberStationTime * 60 * 1000) {
lastHeardStation_temp.push_back(lastHeardStations[i]); for (int i = lastHeardStations.size() - 1; i >= 0; i--) {
if (currentTime - lastHeardStations[i].lastHeardTime >= timeout) {
lastHeardStations.erase(lastHeardStations.begin() + i);
} }
} }
lastHeardStations.clear();
for (int j = 0; j < lastHeardStation_temp.size(); j++) {
lastHeardStations.push_back(lastHeardStation_temp[j]);
}
lastHeardStation_temp.clear();
} }
void updateLastHeard(const String& station) { void updateLastHeard(const String& station) {
deleteNotHeard(); deleteNotHeard();
bool stationHeard = false; uint32_t currentTime = millis();
for (int i = 0; i < lastHeardStations.size(); i++) { for (size_t i = 0; i < lastHeardStations.size(); i++) {
if (lastHeardStations[i].station == station) { if (lastHeardStations[i].station == station) {
lastHeardStations[i].lastHeardTime = millis(); lastHeardStations[i].lastHeardTime = currentTime;
stationHeard = true; Utils::showActiveStations();
break; return;
} }
} }
if (!stationHeard) lastHeardStations.emplace_back(LastHeardStation{millis(), station}); lastHeardStations.emplace_back(LastHeardStation{currentTime, station});
Utils::showActiveStations(); Utils::showActiveStations();
} }
bool wasHeard(const String& station) { bool wasHeard(const String& station) {
deleteNotHeard(); deleteNotHeard();
for (int i = 0; i < lastHeardStations.size(); i++) { for (size_t i = 0; i < lastHeardStations.size(); i++) {
if (lastHeardStations[i].station == station) { if (lastHeardStations[i].station == station) {
Utils::println(" ---> Listened Station"); Utils::println(" ---> Listened Station");
return true; return true;
@@ -184,9 +181,9 @@ namespace STATION_Utils {
} }
bool isIn25SegHashBuffer(const String& station, const String& textMessage) { bool isIn25SegHashBuffer(const String& station, const String& textMessage) {
uint32_t newHash = makeHash(station, textMessage);
uint32_t currentTime = millis();
clean25SegHashBuffer(); clean25SegHashBuffer();
uint32_t newHash = makeHash(station, textMessage);
uint32_t currentTime = millis();
for (int i = 0; i < packet25SegBuffer.size(); i++) { for (int i = 0; i < packet25SegBuffer.size(); i++) {
if (packet25SegBuffer[i].hash == newHash) return true; if (packet25SegBuffer[i].hash == newHash) return true;
} }
@@ -243,11 +240,7 @@ namespace STATION_Utils {
} }
void addToOutputPacketBuffer(const String& packet, bool flag) { void addToOutputPacketBuffer(const String& packet, bool flag) {
OutputPacketBuffer entry; outputPacketBuffer.emplace_back(OutputPacketBuffer{packet, flag});
entry.packet = packet;
entry.isBeacon = flag;
outputPacketBuffer.push_back(entry);
} }
} }

View File

@@ -1,17 +1,17 @@
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU /* Copyright (C) 2025 Ricardo Guzman - CA2RXU
* *
* This file is part of LoRa APRS iGate. * This file is part of LoRa APRS iGate.
* *
* LoRa APRS iGate is free software: you can redistribute it and/or modify * LoRa APRS iGate is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* LoRa APRS iGate is distributed in the hope that it will be useful, * LoRa APRS iGate is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>. * along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
*/ */
@@ -29,10 +29,11 @@
#include "display.h" #include "display.h"
extern Configuration Config; extern Configuration Config;
extern bool sendStartTelemetry;
int telemetryCounter = random(1,999); int telemetryCounter = random(1,999);
uint32_t telemetryEUPTime = 0;
bool sendEUP = false; // Equations Units Parameters
namespace TELEMETRY_Utils { namespace TELEMETRY_Utils {
@@ -89,7 +90,7 @@ namespace TELEMETRY_Utils {
sendBaseTelemetryPacket("EQNS.", getEquationCoefficients()); sendBaseTelemetryPacket("EQNS.", getEquationCoefficients());
sendBaseTelemetryPacket("UNIT.", getUnitLabels()); sendBaseTelemetryPacket("UNIT.", getUnitLabels());
sendBaseTelemetryPacket("PARM.", getParameterNames()); sendBaseTelemetryPacket("PARM.", getParameterNames());
sendStartTelemetry = false; sendEUP = false;
} }
String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType) { String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType) {
@@ -106,7 +107,7 @@ namespace TELEMETRY_Utils {
case 3: tempValue = (value * 8); break; // Pressure case 3: tempValue = (value * 8); break; // Pressure
default: tempValue = value; break; default: tempValue = value; break;
} }
} }
int firstByte = tempValue / 91; int firstByte = tempValue / 91;
tempValue -= firstByte * 91; tempValue -= firstByte * 91;
@@ -127,4 +128,11 @@ namespace TELEMETRY_Utils {
return telemetry; return telemetry;
} }
void checkEUPInterval() {
if (telemetryEUPTime == 0 || millis() - telemetryEUPTime > 24UL * 60UL * 60UL * 1000UL) {
sendEUP = true;
telemetryEUPTime = millis();
}
}
} }

View File

@@ -58,11 +58,12 @@ extern bool backupDigiMode;
extern bool shouldSleepLowVoltage; extern bool shouldSleepLowVoltage;
extern bool transmitFlag; extern bool transmitFlag;
extern bool passcodeValid; extern bool passcodeValid;
extern bool sendEUP; // Equations Units Parameters
extern std::vector<LastHeardStation> lastHeardStations; extern std::vector<LastHeardStation> lastHeardStations;
bool statusAfterBoot = true; bool statusAfterBoot = true;
bool sendStartTelemetry = true;
bool beaconUpdate = false; bool beaconUpdate = false;
uint32_t lastBeaconTx = 0; uint32_t lastBeaconTx = 0;
uint32_t lastScreenOn = millis(); uint32_t lastScreenOn = millis();
@@ -157,7 +158,8 @@ namespace Utils {
if (beaconUpdate) { if (beaconUpdate) {
if (!Config.display.alwaysOn && Config.display.timeout != 0) displayToggle(true); if (!Config.display.alwaysOn && Config.display.timeout != 0) displayToggle(true);
if (sendStartTelemetry && TELEMETRY_Utils::checkEUPInterval();
if (sendEUP &&
Config.battery.sendVoltageAsTelemetry && Config.battery.sendVoltageAsTelemetry &&
!Config.wxsensor.active && !Config.wxsensor.active &&
(Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage) && (Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage) &&