2023-06-11 02:17:10 +02:00
# include <ESPAsyncWebServer.h>
# include <AsyncElegantOTA.h>
# include <AsyncTCP.h>
2023-06-12 01:33:16 +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-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
2023-06-11 02:11:20 +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-06-04 20:18:30 +02:00
2023-06-12 07:31:18 +02:00
namespace Utils {
2023-06-04 20:18:30 +02:00
2023-06-04 20:54:11 +02:00
void processStatus ( ) {
2023-06-08 06:44:13 +02:00
String status = Config . callsign + " >APLRG1 " ;
if ( stationMode = = 1 | | stationMode = = 2 ) {
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 ( " \n Starting 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 ;
2023-06-08 05:55:31 +02:00
if ( stationMode = = 3 | | stationMode = = 4 ) {
2023-06-19 06:52:40 +02:00
thirdLine = " << DigiRepeater >> " ;
2023-06-17 17:10:44 +02:00
}
2023-06-18 16:56:53 +02:00
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-06-08 05:55: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 ) ;
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-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 ) ;
seventhLine = " listening... " ;
2023-06-09 14:34:34 +02:00
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 ) ;
2023-06-08 23:09:05 +02:00
if ( stationMode = = 4 ) {
LoRa_Utils : : changeFreqRx ( ) ;
}
2023-06-08 05:55:31 +02:00
}
lastBeaconTx = millis ( ) ;
lastScreenOn = millis ( ) ;
2023-07-06 07:01:10 +02:00
beaconUpdate = false ;
2023-06-18 00:28:40 +02:00
2023-06-08 05:55:31 +02:00
}
2023-06-19 07:39:20 +02:00
if ( statusAfterBoot ) {
2023-06-08 23:09:05 +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-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-06-09 14:34:34 +02:00
if ( stationMode = = 1 | | stationMode = = 2 ) {
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-06-11 02:11:20 +02:00
void startOTAServer ( ) {
if ( stationMode = = 1 | | stationMode = = 2 ) {
server . on ( " / " , HTTP_GET , [ ] ( AsyncWebServerRequest * request ) {
2023-07-16 22:37:52 +02:00
request - > send ( 200 , " text/plain " , " Hi " + Config . callsign + " , \n \n this is your (Richonguzman/CD2RXU) LoRa iGate , version " + versionDate + " . \n \n To update your firmware or filesystem go to: http:// " + getLocalIP ( ) . substring ( getLocalIP ( ) . indexOf ( " : " ) + 3 ) + " /update \n \n \n 73! " ) ;
2023-06-11 02:11:20 +02:00
} ) ;
AsyncElegantOTA . begin ( & server ) ;
server . begin ( ) ;
2023-06-18 00:28:40 +02:00
Serial . println ( " init : OTA Server ... done! " ) ;
2023-06-11 02:11:20 +02:00
}
}
2023-06-04 20:18:30 +02:00
}