LoRa_APRS_iGate/src/utils.cpp

332 lines
13 KiB
C++
Raw Normal View History

2023-06-11 02:17:10 +02:00
#include <ESPAsyncWebServer.h>
#include <AsyncElegantOTA.h>
#include <AsyncTCP.h>
2023-08-30 00:09:51 +02:00
#include <SPIFFS.h>
2023-06-04 20:54:11 +02:00
#include <WiFi.h>
2023-06-06 17:21:59 +02:00
#include "configuration.h"
2023-06-18 00:28:40 +02:00
#include "station_utils.h"
2023-07-06 07:01:10 +02:00
#include "battery_utils.h"
2023-07-30 23:12:50 +02:00
#include "aprs_is_utils.h"
2023-06-13 05:36:39 +02:00
#include "syslog_utils.h"
2023-06-10 02:20:39 +02:00
#include "pins_config.h"
2023-06-07 23:25:50 +02:00
#include "wifi_utils.h"
2023-06-08 05:55:31 +02:00
#include "lora_utils.h"
2023-06-20 01:44:55 +02:00
#include "gps_utils.h"
2023-06-18 00:28:40 +02:00
#include "bme_utils.h"
2023-06-08 05:55:31 +02:00
#include "display.h"
2023-06-04 20:18:30 +02:00
#include "utils.h"
2023-06-11 02:17:10 +02:00
AsyncWebServer server(80);
2023-06-04 20:18:30 +02:00
2023-06-17 17:10:44 +02:00
extern WiFiClient espClient;
extern Configuration Config;
extern String versionDate;
extern bool statusAfterBoot;
extern String firstLine;
extern String secondLine;
extern String thirdLine;
extern String fourthLine;
extern String fifthLine;
extern String sixthLine;
extern String seventhLine;
extern uint32_t lastBeaconTx;
extern uint32_t lastScreenOn;
2023-07-06 07:01:10 +02:00
extern bool beaconUpdate;
2023-06-17 17:10:44 +02:00
extern int stationMode;
extern String iGateBeaconPacket;
extern std::vector<String> lastHeardStation;
2023-06-20 01:44:55 +02:00
extern int rssi;
extern float snr;
extern int freqError;
extern String distance;
2023-07-13 05:10:02 +02:00
extern String versionDate;
2023-07-31 00:21:06 +02:00
extern uint32_t lastWiFiCheck;
extern bool WiFiConnect;
2023-06-04 20:18:30 +02:00
2023-09-19 14:46:18 +02:00
String name;
String email;
//const char* PARAM_MESSAGE = "message";
2023-08-27 14:47:39 +02:00
2023-06-12 07:31:18 +02:00
namespace Utils {
2023-06-04 20:18:30 +02:00
2023-09-15 23:23:49 +02:00
void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}
2023-09-20 16:25:27 +02:00
String meassureExternalBattery() {
int16_t sample;
int sampleNum = 50;
float readingCorrection = 0.0018;
float batteryVoltage, sampleSum;
sampleSum = 0;
for (int i=0; i<sampleNum; i++) {
sample = analogRead(Config.externalVoltagePin);
sampleSum += sample;
delayMicroseconds(50);
}
batteryVoltage = ((sampleSum/sampleNum) - readingCorrection);
return "VBat=" + String(batteryVoltage,2) + ")";
}
2023-06-04 20:54:11 +02:00
void processStatus() {
2023-06-08 06:44:13 +02:00
String status = Config.callsign + ">APLRG1";
2023-07-31 05:53:59 +02:00
if (stationMode==1 || stationMode==2 || (stationMode==5 && WiFi.status() == WL_CONNECTED)) {
2023-06-08 06:44:13 +02:00
delay(1000);
2023-07-13 05:10:02 +02:00
status += ",qAC:>https://github.com/richonguzman/LoRa_APRS_iGate " + versionDate ;
2023-06-13 05:36:39 +02:00
espClient.write((status + "\n").c_str());
SYSLOG_Utils::log("APRSIS Tx", status,0,0,0);
2023-06-08 06:44:13 +02:00
} else {
delay(5000);
2023-07-13 05:10:02 +02:00
status += ":>https://github.com/richonguzman/LoRa_APRS_iGate " + versionDate;
2023-06-09 06:23:11 +02:00
if (stationMode == 4) {
2023-06-08 23:09:05 +02:00
LoRa_Utils::changeFreqTx();
}
2023-06-08 06:44:13 +02:00
LoRa_Utils::sendNewPacket("APRS", status);
2023-06-08 23:09:05 +02:00
if (stationMode == 4) {
LoRa_Utils::changeFreqRx();
}
2023-06-08 06:44:13 +02:00
}
2023-06-04 20:54:11 +02:00
statusAfterBoot = false;
2023-06-04 20:18:30 +02:00
}
2023-06-17 01:08:25 +02:00
String getLocalIP() {
2023-06-17 17:10:44 +02:00
return "IP : " + String(WiFi.localIP()[0]) + "." + String(WiFi.localIP()[1]) + "." + String(WiFi.localIP()[2]) + "." + String(WiFi.localIP()[3]);
2023-06-17 01:08:25 +02:00
}
2023-06-21 03:05:54 +02:00
void setupDisplay() {
2023-06-08 05:55:31 +02:00
setup_display();
2023-06-10 02:20:39 +02:00
digitalWrite(greenLed,HIGH);
2023-06-09 14:34:34 +02:00
Serial.println("\nStarting iGate: " + Config.callsign + " Version: " + versionDate);
2023-06-19 06:52:40 +02:00
show_display(" LoRa APRS", " ( iGate )", "", " Richonguzman", " -- CD2RXU --", "", " " + versionDate, 4000);
2023-06-10 02:20:39 +02:00
digitalWrite(greenLed,LOW);
2023-06-18 16:56:53 +02:00
firstLine = Config.callsign;
seventhLine = " listening...";
2023-06-11 00:41:40 +02:00
}
2023-06-19 06:52:40 +02:00
void activeStations() {
fourthLine = "Stations (" + String(Config.rememberStationTime) + "min) = ";
if (lastHeardStation.size() < 10) {
fourthLine += " ";
}
fourthLine += String(lastHeardStation.size());
}
2023-06-08 05:55:31 +02:00
void checkBeaconInterval() {
uint32_t lastTx = millis() - lastBeaconTx;
2023-07-06 07:01:10 +02:00
String beaconPacket;
2023-07-31 00:57:31 +02:00
if (lastTx >= Config.beaconInterval*60*1000) {
2023-07-06 07:01:10 +02:00
beaconUpdate = true;
2023-06-08 05:55:31 +02:00
}
2023-07-06 07:01:10 +02:00
if (beaconUpdate) {
2023-06-08 05:55:31 +02:00
display_toggle(true);
Serial.println("---- Sending iGate Beacon ----");
2023-06-19 06:52:40 +02:00
STATION_Utils::deleteNotHeard();
activeStations();
2023-07-06 07:08:01 +02:00
if (Config.bme.active) {
beaconPacket = iGateBeaconPacket.substring(0,iGateBeaconPacket.indexOf(":=")+20) + "_" + BME_Utils::readDataSensor() + iGateBeaconPacket.substring(iGateBeaconPacket.indexOf(":=")+21) + " + WX";
} else {
beaconPacket = iGateBeaconPacket;
}
if (Config.sendBatteryVoltage) {
beaconPacket += " (Batt=" + String(BATTERY_Utils::checkVoltages(),2) + "V)";
}
2023-06-08 23:09:05 +02:00
if (stationMode==1 || stationMode==2) {
2023-06-11 17:12:09 +02:00
thirdLine = getLocalIP();
2023-06-19 06:52:40 +02:00
if (!Config.bme.active) {
fifthLine = "";
2023-06-17 17:10:44 +02:00
}
sixthLine = "";
2023-06-18 16:56:53 +02:00
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING iGate BEACON", 1000);
2023-07-16 23:02:30 +02:00
if (Config.sendBatteryVoltage) {
sixthLine = " (Batt=" + String(BATTERY_Utils::checkVoltages(),2) + "V)";
2023-07-16 23:02:30 +02:00
}
2023-06-18 16:56:53 +02:00
seventhLine = " listening...";
2023-07-06 07:01:10 +02:00
espClient.write((beaconPacket + "\n").c_str());
2023-06-18 16:56:53 +02:00
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
2023-06-08 23:09:05 +02:00
} else if (stationMode==3 || stationMode==4) {
2023-06-19 06:52:40 +02:00
String Rx = String(Config.loramodule.digirepeaterRxFreq);
String Tx = String(Config.loramodule.digirepeaterTxFreq);
if (stationMode==3) {
secondLine = "Rx:" + String(Tx.substring(0,3)) + "." + String(Tx.substring(3,6));
} else {
secondLine = "Rx:" + String(Rx.substring(0,3)) + "." + String(Rx.substring(3,6));
}
secondLine += " Tx:" + String(Tx.substring(0,3)) + "." + String(Tx.substring(3,6));
2023-07-30 23:12:50 +02:00
thirdLine = "<< DigiRepeater >>";
2023-06-17 17:10:44 +02:00
fifthLine = "";
sixthLine = "";
2023-06-18 16:56:53 +02:00
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING iGate BEACON", 0);
2023-07-16 23:02:30 +02:00
if (Config.sendBatteryVoltage) {
sixthLine = " (Batt=" + String(BATTERY_Utils::checkVoltages(),2) + "V)";
2023-07-16 23:02:30 +02:00
}
2023-06-18 16:56:53 +02:00
seventhLine = " listening...";
if (stationMode==4) {
2023-06-08 23:09:05 +02:00
LoRa_Utils::changeFreqTx();
}
2023-07-06 07:01:10 +02:00
LoRa_Utils::sendNewPacket("APRS", beaconPacket);
if (stationMode==4) {
2023-06-08 23:09:05 +02:00
LoRa_Utils::changeFreqRx();
}
} else if (stationMode==5) {
2023-07-31 00:21:06 +02:00
if (!Config.bme.active) {
fifthLine = "";
}
sixthLine = "";
2023-07-30 23:12:50 +02:00
if (WiFi.status() == WL_CONNECTED && espClient.connected()) {
APRS_IS_Utils::checkStatus();
thirdLine = getLocalIP();
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING iGate BEACON", 1000);
if (Config.sendBatteryVoltage) {
sixthLine = " (Batt=" + String(BATTERY_Utils::checkVoltages(),2) + "V)";
}
seventhLine = " listening...";
espClient.write((beaconPacket + "\n").c_str());
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
} else {
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING iGate BEACON", 0);
if (Config.sendBatteryVoltage) {
sixthLine = " (Batt=" + String(BATTERY_Utils::checkVoltages(),2) + "V)";
}
seventhLine = " listening...";
LoRa_Utils::sendNewPacket("APRS", beaconPacket);
}
2023-06-08 05:55:31 +02:00
}
lastBeaconTx = millis();
lastScreenOn = millis();
2023-07-06 07:01:10 +02:00
beaconUpdate = false;
2023-06-08 05:55:31 +02:00
}
2023-06-19 07:39:20 +02:00
if (statusAfterBoot) {
2023-07-31 00:57:31 +02:00
processStatus();
2023-06-19 07:39:20 +02:00
}
2023-06-08 05:55:31 +02:00
}
void checkDisplayInterval() {
uint32_t lastDisplayTime = millis() - lastScreenOn;
if (!Config.display.alwaysOn) {
if (lastDisplayTime >= Config.display.timeout*1000) {
display_toggle(false);
}
}
}
2023-07-31 00:21:06 +02:00
void checkWiFiInterval() {
uint32_t WiFiCheck = millis() - lastWiFiCheck;
2023-07-31 05:53:59 +02:00
if (WiFi.status() != WL_CONNECTED && WiFiCheck >= 15*60*1000) {
2023-07-31 00:21:06 +02:00
WiFiConnect = true;
}
if (WiFiConnect) {
Serial.println("\nConnecting to WiFi ...");
2023-07-31 00:57:31 +02:00
WIFI_Utils::startWiFi();
2023-07-31 00:21:06 +02:00
lastWiFiCheck = millis();
WiFiConnect = false;
}
}
2023-06-08 23:09:05 +02:00
void validateDigiFreqs() {
if (stationMode == 4) {
if (abs(Config.loramodule.digirepeaterTxFreq - Config.loramodule.digirepeaterRxFreq) < 125000) {
Serial.println("Tx Freq less than 125kHz from Rx Freq ---> NOT VALID, check 'data/igate_conf.json'");
show_display("Tx Freq is less than ", "125kHz from Rx Freq", "change it on : /data/", "igate_conf.json", 0);
while (1);
}
}
}
2023-06-17 17:10:44 +02:00
void typeOfPacket(String packet, String packetType) {
String sender;
2023-07-31 00:21:06 +02:00
if (stationMode==1 || stationMode==2 || (stationMode==5 && WiFi.status() == WL_CONNECTED)) {
2023-06-17 17:10:44 +02:00
if (packetType == "LoRa-APRS") {
2023-06-18 16:56:53 +02:00
fifthLine = "LoRa Rx ----> APRS-IS";
2023-06-17 17:10:44 +02:00
} else if (packetType == "APRS-LoRa") {
2023-06-18 16:56:53 +02:00
fifthLine = "APRS-IS ----> LoRa Tx";
2023-06-17 17:10:44 +02:00
}
sender = packet.substring(0,packet.indexOf(">"));
2023-06-09 14:34:34 +02:00
} else {
2023-06-19 06:52:40 +02:00
fifthLine = "LoRa Rx ----> LoRa Tx";
2023-06-17 17:10:44 +02:00
sender = packet.substring(3,packet.indexOf(">"));
}
for (int i=sender.length();i<9;i++) {
sender += " ";
2023-06-09 14:34:34 +02:00
}
2023-06-09 07:12:13 +02:00
if (packet.indexOf("::") >= 10) {
2023-06-17 17:10:44 +02:00
if (packetType == "APRS-LoRa") {
String addresseeAndMessage = packet.substring(packet.indexOf("::")+2);
String addressee = addresseeAndMessage.substring(0, addresseeAndMessage.indexOf(":"));
addressee.trim();
2023-06-19 07:39:20 +02:00
sixthLine = sender + " > " + addressee;
2023-06-17 17:10:44 +02:00
} else {
2023-06-19 07:39:20 +02:00
sixthLine = sender + "> MESSAGE";
2023-06-17 17:10:44 +02:00
}
2023-06-20 01:44:55 +02:00
seventhLine = "RSSI:" + String(rssi) + "dBm SNR: " + String(snr) + "dBm";
2023-06-09 07:12:13 +02:00
} else if (packet.indexOf(":>") >= 10) {
2023-06-18 16:56:53 +02:00
sixthLine = sender + "> NEW STATUS";
2023-06-20 01:44:55 +02:00
seventhLine = "RSSI:" + String(rssi) + "dBm SNR: " + String(snr) + "dBm";
2023-06-09 07:12:13 +02:00
} else if (packet.indexOf(":!") >= 10 || packet.indexOf(":=") >= 10) {
2023-06-18 16:56:53 +02:00
sixthLine = sender + "> GPS BEACON";
2023-06-20 01:44:55 +02:00
GPS_Utils::getDistance(packet);
2023-06-20 05:06:41 +02:00
seventhLine = "RSSI:" + String(rssi) + "dBm";
if (rssi <= -100) {
2023-06-20 01:44:55 +02:00
seventhLine += " ";
2023-06-20 05:06:41 +02:00
} else {
2023-06-20 01:44:55 +02:00
seventhLine += " ";
}
2023-06-20 05:06:41 +02:00
if (distance.indexOf(".") == 1) {
seventhLine += " ";
}
2023-06-20 01:44:55 +02:00
seventhLine += "D:" + distance + "km";
2023-07-05 13:50:33 +02:00
} else if (packet.indexOf(":T#") >= 10 && packet.indexOf(":=/") == -1) {
sixthLine = sender + "> TELEMETRY";
seventhLine = "RSSI:" + String(rssi) + "dBm SNR: " + String(snr) + "dBm";
2023-06-09 07:12:13 +02:00
} else {
2023-06-18 16:56:53 +02:00
sixthLine = sender + "> ??????????";
2023-06-20 01:44:55 +02:00
seventhLine = "RSSI:" + String(rssi) + "dBm SNR: " + String(snr) + "dBm";
2023-06-09 07:12:13 +02:00
}
}
2023-08-29 05:21:20 +02:00
void startServer() {
2023-07-31 00:57:31 +02:00
if (stationMode==1 || stationMode==2 || (stationMode==5 && WiFi.status() == WL_CONNECTED)) {
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
2023-08-27 14:47:39 +02:00
request->send(200, "text/plain", "Hi " + Config.callsign + ", \n\nthis is your (Richonguzman/CD2RXU) LoRa iGate , version " + versionDate + ".\n\nTo update your firmware or filesystem go to: http://" + getLocalIP().substring(getLocalIP().indexOf(":")+3) + "/update\n\n\n73!");
});
2023-09-03 15:05:07 +02:00
server.on("/test", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(SPIFFS, "/test_info_1.html", "text/html");//"application/json");
});
2023-08-27 14:47:39 +02:00
2023-09-15 23:23:49 +02:00
server.on("/test2", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(SPIFFS, "/test1.html", "text/html");
});
2023-08-29 04:08:00 +02:00
if (Config.ota.username != "" && Config.ota.password != "") {
AsyncElegantOTA.begin(&server, Config.ota.username.c_str(), Config.ota.password.c_str());
} else {
AsyncElegantOTA.begin(&server);
}
2023-08-31 14:17:31 +02:00
2023-09-15 23:23:49 +02:00
server.on("/process_form.php", HTTP_POST, [](AsyncWebServerRequest *request){
String message;
2023-09-19 14:46:18 +02:00
if (request->hasParam("email", true) && request->hasParam("name", true)) {
email = request->getParam("email", true)->value();
name = request->getParam("name", true)->value();
String responseMessage = "Received EMAIL: " + email + ", NAME: " + name;
// Assuming you're sending an HTTP response, for example, in an HTTP server context
request->send(200, "text/plain", responseMessage);
2023-09-15 23:23:49 +02:00
} else {
2023-09-19 14:46:18 +02:00
// Handle the case where one or both parameters are missing
request->send(400, "text/plain", "Both EMAIL and NAME parameters are required.");
2023-09-15 23:23:49 +02:00
}
});
server.onNotFound(notFound);
2023-08-31 14:17:31 +02:00
server.serveStatic("/", SPIFFS, "/");
server.begin();
2023-06-18 00:28:40 +02:00
Serial.println("init : OTA Server ... done!");
}
}
2023-06-04 20:18:30 +02:00
}