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
*
*
* This file is part of LoRa APRS iGate.
*
*
* 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
* 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.
*
*
* LoRa APRS iGate is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* 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/>.
*/
@ -27,7 +27,8 @@ namespace TELEMETRY_Utils {
void sendEquationsUnitsParameters();
String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType);
String generateEncodedTelemetry();
void checkEUPInterval();
}
#endif

View file

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

View file

@ -1,17 +1,17 @@
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
*
*
* This file is part of LoRa APRS iGate.
*
*
* 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
* 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.
*
*
* LoRa APRS iGate is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* 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/>.
*/
@ -29,10 +29,11 @@
#include "display.h"
extern Configuration Config;
extern bool sendStartTelemetry;
extern Configuration Config;
int telemetryCounter = random(1,999);
int telemetryCounter = random(1,999);
uint32_t telemetryEUPTime = 0;
bool sendEUP = false; // Equations Units Parameters
namespace TELEMETRY_Utils {
@ -89,7 +90,7 @@ namespace TELEMETRY_Utils {
sendBaseTelemetryPacket("EQNS.", getEquationCoefficients());
sendBaseTelemetryPacket("UNIT.", getUnitLabels());
sendBaseTelemetryPacket("PARM.", getParameterNames());
sendStartTelemetry = false;
sendEUP = false;
}
String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType) {
@ -106,7 +107,7 @@ namespace TELEMETRY_Utils {
case 3: tempValue = (value * 8); break; // Pressure
default: tempValue = value; break;
}
}
}
int firstByte = tempValue / 91;
tempValue -= firstByte * 91;
@ -127,4 +128,11 @@ namespace TELEMETRY_Utils {
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 transmitFlag;
extern bool passcodeValid;
extern bool sendEUP; // Equations Units Parameters
extern std::vector<LastHeardStation> lastHeardStations;
bool statusAfterBoot = true;
bool sendStartTelemetry = true;
bool beaconUpdate = false;
uint32_t lastBeaconTx = 0;
uint32_t lastScreenOn = millis();
@ -157,7 +158,8 @@ namespace Utils {
if (beaconUpdate) {
if (!Config.display.alwaysOn && Config.display.timeout != 0) displayToggle(true);
if (sendStartTelemetry &&
TELEMETRY_Utils::checkEUPInterval();
if (sendEUP &&
Config.battery.sendVoltageAsTelemetry &&
!Config.wxsensor.active &&
(Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage) &&