mirror of
https://github.com/richonguzman/LoRa_APRS_iGate.git
synced 2026-03-28 16:52:33 +01:00
telemetry EUP beacon update
This commit is contained in:
@@ -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
|
||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -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) &&
|
||||||
|
|||||||
Reference in New Issue
Block a user