Compare commits

..

37 Commits

Author SHA1 Message Date
richonguzman 8add599838 NTP server change fix 2025-10-15 14:31:02 -03:00
richonguzman 83ec2265c6 Rx and Tx Freq selection fix 2025-10-15 14:18:43 -03:00
richonguzman bec4f4f473 beaconOnRxFreq into beacon config 2025-10-15 10:58:30 -03:00
richonguzman 87a67cd2c9 readmeupdate otro mas 2025-10-13 13:29:56 -03:00
richonguzman 4e48b2d02d manual update 2025-10-13 13:11:51 -03:00
richonguzman 607277bfe9 readme update2 2025-10-13 12:44:47 -03:00
richonguzman c2f8596667 readme update 2025-10-13 12:44:15 -03:00
richonguzman ba7ff2a2d9 WebUI change 2025-10-13 12:38:52 -03:00
richonguzman b44eb1028d no more speed standards on index 2025-10-13 02:03:18 -03:00
richonguzman d7602268f2 changes for Rx and Tx Lora Freq 2025-10-13 02:00:05 -03:00
richonguzman 2f6f9be28e Lora Config separated for Rx and Tx 2025-10-13 01:33:41 -03:00
richonguzman 92572245cd beacon Freq on digi mod 2025-10-12 21:45:23 -03:00
richonguzman 152217e71c startup delay added 2025-10-12 14:21:51 -03:00
richonguzman d334164b6f Beacon Freq on Digi Mode 2025-10-11 18:27:06 -03:00
richonguzman 61409ce683 index correction 2025-10-11 15:57:29 -03:00
richonguzman 742a6b6477 readme update 2025-10-11 13:23:39 -03:00
richonguzman dd2fce3908 igate beacon over mqtt 2025-10-11 13:22:08 -03:00
richonguzman 90b29b66d5 callsign trim 2025-10-11 12:50:53 -03:00
richonguzman 2a86cdb0d8 Op ntp server 2025-10-11 12:40:07 -03:00
richonguzman 1abaa299e0 update readme 2025-10-10 12:44:15 -03:00
Ricardo Guzman (Richonguzman) 9cbd7c22fd Merge pull request #342 from richonguzman/richonguzman-patch-14
Update README.md
2025-10-10 12:15:18 -03:00
Ricardo Guzman (Richonguzman) e15e6def91 Update README.md 2025-10-10 12:14:56 -03:00
richonguzman 33c8be4f48 added manual for 3.1.2 2025-10-10 12:11:24 -03:00
Ricardo Guzman (Richonguzman) c2a7c26d78 Merge pull request #341 from richonguzman/richonguzman-patch-13
Update README.md
2025-10-10 12:08:41 -03:00
Ricardo Guzman (Richonguzman) 387e8a988a Update README.md 2025-10-10 12:08:28 -03:00
Ricardo Guzman (Richonguzman) 48b075a554 Merge pull request #340 from richonguzman/richonguzman-patch-12
Update README.md
2025-10-10 12:06:38 -03:00
Ricardo Guzman (Richonguzman) 7e76e43817 Update README.md 2025-10-10 12:06:25 -03:00
Ricardo Guzman (Richonguzman) 9b7b4e1838 Merge pull request #339 from richonguzman/richonguzman-patch-11
Update README.md
2025-10-10 12:04:17 -03:00
Ricardo Guzman (Richonguzman) 5b9d56843b Update README.md 2025-10-10 12:04:04 -03:00
Ricardo Guzman (Richonguzman) 30eb1023dc Merge pull request #338 from richonguzman/richonguzman-patch-10
Update README.md
2025-10-10 12:03:09 -03:00
Ricardo Guzman (Richonguzman) 1ba86af61b Update README.md 2025-10-10 12:02:54 -03:00
Ricardo Guzman (Richonguzman) 1d475bc8a2 Merge pull request #337 from richonguzman/richonguzman-patch-9
Update README.md
2025-10-10 11:58:13 -03:00
Ricardo Guzman (Richonguzman) 70f9a6fa04 Update README.md 2025-10-10 11:57:50 -03:00
Ricardo Guzman (Richonguzman) 6747511850 Merge pull request #336 from richonguzman/richonguzman-patch-8
Update README.md
2025-10-10 11:56:25 -03:00
Ricardo Guzman (Richonguzman) 96a4394e89 Update README.md 2025-10-10 11:56:10 -03:00
Ricardo Guzman (Richonguzman) 4e009bc14c Merge pull request #332 from richonguzman/richonguzman-patch-7
adding heltec wireless bridge
2025-09-29 15:52:00 -03:00
Ricardo Guzman (Richonguzman) 4c11c66a1c adding heltec wireless bridge 2025-09-29 15:51:41 -03:00
50 changed files with 648 additions and 513 deletions
+2
View File
@@ -29,6 +29,8 @@ jobs:
chip: esp32s3 chip: esp32s3
- name: heltec_wireless_stick_lite_v3_display - name: heltec_wireless_stick_lite_v3_display
chip: esp32s3 chip: esp32s3
- name: heltec_wireless_bridge
chip: esp32
- name: ESP32_DIY_LoRa - name: ESP32_DIY_LoRa
chip: esp32 chip: esp32
- name: ESP32_DIY_LoRa_915 - name: ESP32_DIY_LoRa_915
+19 -23
View File
@@ -9,46 +9,38 @@ __(This iGate Firmware works with all LoRa Tracker Firmwares (specially this <a
____________________________________________________ ____________________________________________________
# <a href="https://richonguzman.github.io/lora-igate-web-flasher/installer.html" target="_blank">WEB FLASHER/INSTALLER</a>
# <a href="https://github.com/richonguzman/LoRa_APRS_iGate/blob/main/manual/LoRa_APRS_iGate_CA2RXU_Firmware_Manual.pdf" target="_blank">LoRa APRS iGate CA2RXU Firmware Manual</a>
____________________________________________________
## You can support this project to continue to grow: ## You can support this project to continue to grow:
[<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/blob/main/images/github-sponsors.png">](https://github.com/sponsors/richonguzman) [<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/blob/main/images/paypalme.png">](http://paypal.me/richonguzman) [<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/blob/main/images/github-sponsors.png">](https://github.com/sponsors/richonguzman) [<img src="https://github.com/richonguzman/LoRa_APRS_Tracker/blob/main/images/paypalme.png">](http://paypal.me/richonguzman)
<br />
# WEB FLASHER/INSTALLER is <a href="https://richonguzman.github.io/lora-igate-web-flasher/installer.html" target="_blank">here</a>
____________________________________________________ ____________________________________________________
# WIKI ## SUPPORTED BOARDS (<a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/Supported-Boards-and-Buying-Links" target="_blank">Buying links</a>).
### FAQ, BME280, TNC and more --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/00.-FAQ-(frequently-asked-questions)" target="_blank">here</a>.
### Installation Guide --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/01.-Installation-Guide" target="_blank">here</a>.
<br />
# SUPPORTED BOARDS
### Buying links --> <a href="https://github.com/richonguzman/LoRa_APRS_iGate/wiki/108.-Supported-Boards-and-Buying-Links" target="_blank">here</a>.
(NOTE: all boards with 433-868-915 MHz versions) (NOTE: all boards with 433-868-915 MHz versions)
- TTGO Lilygo LoRa32 T3S3 V1.2 and LoRa32 V2.1 (V1.6 is the same). - TTGO Lilygo LoRa32 T3S3 V1.2 and LoRa32 V2.1 (V1.6 is the same).
- TTGO T-Beam V1.0 , V1.1, V1.2 (also variations with SX1262 and SX1268 LoRa Modules). - TTGO T-Beam V1.0 , V1.1, V1.2 (also variations with SX1262 and SX1268 LoRa Modules) and Supreme V3.
- T-Deck Plus (and also regular T-Deck with/without GPS). - T-Deck Plus (and also regular T-Deck with/without GPS).
- HELTEC V2, V3, V3.2, T114, Wireless Stick, Wireless Stick Lite, HT-CT62, Wireless Tracker, Wireless Paper. - HELTEC V2, V3, V3.2, T114, Wireless Stick, Wireless Stick Lite V3/V3.2, HT-CT62, Wireless Tracker, Wireless Paper.
- RAK Wireless 4631 + 19007(19003) - RAK Wireless 4631 + 19007(or 19003)
- Faketec (NRF52840 + Heltec HTRA62(SX1262)) - Faketec V3 (NRF52840 + Heltec HTRA62(SX1262))
- QRP Labs LightGateway 1.0 and Plus 1.0. - QRP Labs LightGateway 1.0 and Plus 1.0.
- Faketec V3 (NRF52840 + Heltec HTRA62 SX1262) - ESP32 + SX1278 LoRa Module or Ebyte 400M30S (or 900M30S) 1W LoRa Module for a DIY Versions.
- ESP32 Wroom + SX1278 LoRa Module or Ebyte 400M30S (or 900M30S) 1W LoRa Module for a DIY Versions.
- ESP32C3 + Ebyte 400M30S(or 900M30S) 1W LoRa Module for another DIY version. - ESP32C3 + Ebyte 400M30S(or 900M30S) 1W LoRa Module for another DIY version.
@@ -58,8 +50,12 @@ ____________________________________________________
<br /> <br />
## Timeline (Versions): # Timeline (Versions):
- 2025-10-13 Rx and Tx Frequencies are now with fully configurable.
- 2025-10-13 Startup Delay to allow the Router/Modem to start WiFiAP before connecting.
- 2025-10-12 Choose to send Beacon on Rx or Tx frequency in Digipeater Mode.
- 2025-10-11 User defined NTP server and send beacon over MQTT added.
- 2025-10-10 Converted the Wiki into a PDF manual.
- 2025-09-26 Heltec Wireless Bridge support added. - 2025-09-26 Heltec Wireless Bridge support added.
- 2025-09-09 MQTT added (pub+sub), Status defined by Op now and many fixes more. - 2025-09-09 MQTT added (pub+sub), Status defined by Op now and many fixes more.
- 2025-06-20 Digipeaters now with updated EcoMode (Board Sleeps until packet Rx reducing current consumption to almost 10% at idle). - 2025-06-20 Digipeaters now with updated EcoMode (Board Sleeps until packet Rx reducing current consumption to almost 10% at idle).
+15 -8
View File
@@ -17,6 +17,7 @@
"path": "WIDE1-1", "path": "WIDE1-1",
"sendViaAPRSIS": false, "sendViaAPRSIS": false,
"sendViaRF": false, "sendViaRF": false,
"beaconFreq": 1,
"statusActive": false, "statusActive": false,
"statusPacket": "", "statusPacket": "",
"gpsActive": false, "gpsActive": false,
@@ -38,14 +39,17 @@
"ecoMode": 0 "ecoMode": 0
}, },
"lora": { "lora": {
"txFreq": 433775000, "rxActive": true,
"rxFreq": 433775000, "rxFreq": 433775000,
"spreadingFactor": 12, "rxSpreadingFactor": 12,
"signalBandwidth": 125000, "rxCodingRate4": 5,
"codingRate4": 5, "rxSignalBandwidth": 125000,
"power": 20,
"txActive": false, "txActive": false,
"rxActive": true "txFreq": 433775000,
"txSpreadingFactor": 12,
"txCodingRate4": 5,
"txSignalBandwidth": 125000,
"power": 20
}, },
"display": { "display": {
"alwaysOn": true, "alwaysOn": true,
@@ -86,7 +90,8 @@
"topic": "", "topic": "",
"username": "", "username": "",
"password": "", "password": "",
"port": 1883 "port": 1883,
"beaconOverMqtt": false
}, },
"ota": { "ota": {
"username": "", "username": "",
@@ -101,12 +106,14 @@
"rfOnly": true "rfOnly": true
}, },
"ntp": { "ntp": {
"server": "pool.ntp.org",
"gmtCorrection": 0.0 "gmtCorrection": 0.0
}, },
"other": { "other": {
"rememberStationTime": 30, "rememberStationTime": 30,
"backupDigiMode": false, "backupDigiMode": false,
"rebootMode": false, "rebootMode": false,
"rebootModeTime": 6 "rebootModeTime": 6,
"startupDelay": 0
} }
} }
+405 -315
View File
@@ -344,6 +344,28 @@
</button> </button>
</div> </div>
</div> </div>
<div class="col-6 mt-3">
<label
for="startupDelay"
class="form-label"
>Startup Delay<small>(To Allow Router/Modem to start WiFiAP before connection)</small></label
>
<div class="input-group">
<input
type="number"
name="startupDelay"
id="startupDelay"
placeholder="0"
class="form-control"
step="1"
min="0"
max="5"
/>
<span class="input-group-text"
>minutes</span
>
</div>
</div>
</div> </div>
</div> </div>
<hr> <hr>
@@ -545,12 +567,33 @@
</label> </label>
</div> </div>
</div> </div>
<div class="col-6 d-grid gap-2"> </div>
<button class="btn btn-primary" id="send-beacon">Send beacon now</button> <div class="row mt-3">
<div class="col-6">
<button class="btn btn-primary form-control h-100" id="send-beacon">Send beacon now</button>
</div>
<div class="col-6">
<label
for="beacon.beaconFreq"
class="form-label">
<small>(Select LoRa Beacon Frequency)</small>
</label>
<select
class="form-select form-select"
name="beacon.beaconFreq"
id="beacon.beaconFreq"
>
<option value="0">
Beacon on Rx Freq
</option>
<option value="1">
Beacon on Tx Freq
</option>
</select>
</div> </div>
</div> </div>
<div class="row mt-4"> <div class="row mt-3">
<div class="col-12"> <div class="col-6">
<label <label
for="beacon.interval" for="beacon.interval"
class="form-label" class="form-label"
@@ -626,7 +669,7 @@
</h5> </h5>
<small>Add Callsigns with space between them to Blacklist them (* wild card allowed)</small> <small>Add Callsigns with space between them to Blacklist them (* wild card allowed)</small>
</div> </div>
<div class="col-9 mt-2"> <div class="col-9">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<label <label
@@ -667,7 +710,7 @@
</h5> </h5>
<small>Define the Digipeater mode</small> <small>Define the Digipeater mode</small>
</div> </div>
<div class="col-9 mt-2"> <div class="col-9">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<label <label
@@ -706,13 +749,13 @@
id="digi.ecoMode" id="digi.ecoMode"
> >
<option value="0"> <option value="0">
OFF (Normal Mode - WiFiAP enabled) OFF (Normal Mode - WiFiAP and Serial Output enabled)
</option> </option>
<option value="1"> <option value="1">
Ultra Eco Mode (Sleep till Packet Rx (WiFiAP/WebUI & Display disabled)) Ultra Eco Mode (Sleep till Packet Rx (WiFiAP/WebUI & Display disabled))
</option> </option>
<option value="2"> <option value="2">
OFF (Normal Mode - WiFiAP disabled) OFF (Normal Mode - WiFiAP disabled but Serial Output still enabled)
</option> </option>
</select> </select>
</div> </div>
@@ -744,21 +787,6 @@
</div> </div>
<div class="col-lg-9 col-sm-12"> <div class="col-lg-9 col-sm-12">
<div class="row"> <div class="row">
<div class="col-6">
<div class="form-check form-switch">
<input
type="checkbox"
name="lora.txActive"
id="lora.txActive"
class="form-check-input"
/>
<label
for="lora.txActive"
class="form-label"
>Enable LoRa TX</label
>
</div>
</div>
<div class="col-6"> <div class="col-6">
<div class="form-check form-switch"> <div class="form-check form-switch">
<input <input
@@ -775,6 +803,40 @@
</div> </div>
</div> </div>
<div class="col-6"> <div class="col-6">
<div class="form-check form-switch">
<input
type="checkbox"
name="lora.txActive"
id="lora.txActive"
class="form-check-input"
/>
<label
for="lora.txActive"
class="form-label"
>Enable LoRa TX</label
>
</div>
</div>
<div class="col-6 mt-1">
<label
for="lora.rxFreq"
class="form-label">
Rx Frequency
</label>
<div class="input-group">
<input
type="text"
name="lora.rxFreq"
id="lora.rxFreq"
placeholder="433775000"
class="form-control"
/>
<span class="input-group-text"
>Hz
</span>
</div>
</div>
<div class="col-6 mt-1">
<label <label
for="lora.txFreq" for="lora.txFreq"
class="form-label" class="form-label"
@@ -802,136 +864,123 @@
</span> </span>
</div> </div>
</div> </div>
<div class="col-6"> <div class="col-6 mt-3">
<label <label
for="lora.rxFreq" for="lora.rxSpreadingFactor"
class="form-label">
Rx Frequency
</label>
<div class="input-group">
<input
type="text"
name="lora.rxFreq"
id="lora.rxFreq"
placeholder="433775000"
class="form-control"
/>
<span class="input-group-text"
>Hz
</span>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-12 mb-4">
<label
for="action.speed"
class="form-label" class="form-label"
>Predefined speeds >Rx Spreading Factor
</label> </label>
<select <select
class="form-select form-select" class="form-select form-select"
name="action.speed" name="lora.rxSpreadingFactor"
id="action.speed" id="lora.rxSpreadingFactor"
>
<option value="300">
BW 125khz CR 4:5 SF 12 (Slow
Standard, 300bps)
</option>
<option value="244">
BW 125khz CR 4:6 SF 12 (244bps)
</option>
<option value="209">
BW 125khz CR 4:7 SF 12 (209bps)
</option>
<option value="183">
BW 125khz CR 4:8 SF 12 (183bps)
</option>
<option value="610">
BW 125khz CR 4:8 SF 10 (610bps)
</option>
<option value="1200">
BW 125khz CR 4:7 SF 9 (Fast
Standard, 1200bps)
</option>
<option value="">
User defined
</option>
</select>
</div>
<div class="col-5">
<label
for="lora.signalBandwidth"
class="form-label"
>Bandwidth
</label>
<div class="input-group">
<select
class="form-select form-select"
name="lora.signalBandwidth"
id="lora.signalBandwidth"
required=""
>
<option value="62500" selected>
62.5 kHz
</option>
<option value="125000" selected>
125 kHz
</option>
<option value="250000">
250 kHz
</option>
<option value="500000">
500 kHz
</option>
</select>
</div>
</div>
<div class="col-7">
<label
for="lora.spreadingFactor"
class="form-label"
>Spreading Factor
</label>
<select
class="form-select form-select"
name="lora.spreadingFactor"
id="lora.spreadingFactor"
required="" required=""
> >
<option value="7"> <option value="7">SF7 - Lowest battery usage</option>
SF7 - Lowest battery usage
</option>
<option value="8">SF8</option> <option value="8">SF8</option>
<option value="9">SF9</option> <option value="9">SF9</option>
<option value="10">SF10</option> <option value="10">SF10</option>
<option value="11">SF11</option> <option value="11">SF11</option>
<option value="12" selected> <option value="12" selected>SF12 - Highest sensitivity</option>
SF12 - Highest sensitivity
</option>
</select> </select>
</div> </div>
</div> <div class="col-6 mt-3">
<div class="row mt-3">
<div class="col-6">
<label <label
for="lora.codingRate4" for="lora.txSpreadingFactor"
class="form-label"> class="form-label"
Coding Rate >Tx Spreading Factor
</label> </label>
<select <select
class="form-select form-select" class="form-select form-select"
name="lora.codingRate4" name="lora.txSpreadingFactor"
id="lora.codingRate4" id="lora.txSpreadingFactor"
required="" required=""
> >
<option value="5">5</option> <option value="7">SF7 - Lowest battery usage</option>
<option value="8">SF8</option>
<option value="9">SF9</option>
<option value="10">SF10</option>
<option value="11">SF11</option>
<option value="12" selected>SF12 - Highest sensitivity</option>
</select>
</div>
<div class="col-6 mt-3">
<label
for="lora.rxCodingRate4"
class="form-label">
Rx Coding Rate
</label>
<select
class="form-select form-select"
name="lora.rxCodingRate4"
id="lora.rxCodingRate4"
required=""
>
<option value="5" selected>5</option>
<option value="6">6</option> <option value="6">6</option>
<option value="7">7</option> <option value="7">7</option>
<option value="8">8</option> <option value="8">8</option>
</select> </select>
</div> </div>
<div class="col-6"> <div class="col-6 mt-3">
<label
for="lora.txCodingRate4"
class="form-label">
Tx Coding Rate
</label>
<select
class="form-select form-select"
name="lora.txCodingRate4"
id="lora.txCodingRate4"
required=""
>
<option value="5" selected>5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
</div>
<div class="col-6 mt-3">
<label
for="lora.rxSignalBandwidth"
class="form-label"
>Rx Signal Bandwidth
</label>
<div class="input-group">
<select
class="form-select form-select"
name="lora.rxSignalBandwidth"
id="lora.rxSignalBandwidth"
required=""
>
<option value="62500">62.5 kHz</option>
<option value="125000" selected>125 kHz</option>
<option value="250000">250 kHz</option>
<option value="500000">500 kHz</option>
</select>
</div>
</div>
<div class="col-6 mt-3">
<label
for="lora.txSignalBandwidth"
class="form-label"
>Tx Signal Bandwidth
</label>
<div class="input-group">
<select
class="form-select form-select"
name="lora.txSignalBandwidth"
id="lora.txSignalBandwidth"
required=""
>
<option value="62500">62.5 kHz</option>
<option value="125000" selected>125 kHz</option>
<option value="250000">250 kHz</option>
<option value="500000">500 kHz</option>
</select>
</div>
</div>
<div class="col-6 mt-3">
<label <label
for="lora.power" for="lora.power"
class="form-label"> class="form-label">
@@ -953,7 +1002,7 @@
>dBm</span >dBm</span
> >
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@@ -1013,7 +1062,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="row mt-2"> <div class="row mt-1">
<div class="col-6"> <div class="col-6">
<label <label
for="display.timeout" for="display.timeout"
@@ -1092,8 +1141,8 @@
Calculate voltage divider accordingly. Calculate voltage divider accordingly.
</small> </small>
</div> </div>
<div class="col-9 mt-2"> <div class="col-9">
<div class="row mt-2"> <div class="row">
<div class="col-6"> <div class="col-6">
<div class="form-check form-switch"> <div class="form-check form-switch">
<input <input
@@ -1122,7 +1171,7 @@
>(Send Voltage As Telemetry)</label >(Send Voltage As Telemetry)</label
> >
</div> </div>
<div class="form-check form-switch mt-3"> <div class="form-check form-switch">
<input <input
type="checkbox" type="checkbox"
name="battery.monitorInternalVoltage" name="battery.monitorInternalVoltage"
@@ -1274,7 +1323,7 @@
</h5> </h5>
<small>Define Wx telemetry</small> <small>Define Wx telemetry</small>
</div> </div>
<div class="col-9 mt-2"> <div class="col-9">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<div class="form-check form-switch"> <div class="form-check form-switch">
@@ -1295,7 +1344,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="row mt-3"> <div class="row mt-2">
<div class="col-6"> <div class="col-6">
<label for="wxsensor.heightCorrection" class="form-label" <label for="wxsensor.heightCorrection" class="form-label"
>Height Correction (Above Sea-Level)</label >Height Correction (Above Sea-Level)</label
@@ -1363,18 +1412,37 @@
> >
</div> </div>
<div class="col-lg-9 col-sm-12"> <div class="col-lg-9 col-sm-12">
<div class="form-check form-switch"> <div class="row">
<input <div class="col-6">
type="checkbox" <div class="form-check form-switch">
name="syslog.active" <input
id="syslog.active" type="checkbox"
class="form-check-input" name="syslog.active"
/> id="syslog.active"
<label class="form-check-input"
for="syslog.active" />
class="form-label" <label
>Enable syslog</label for="syslog.active"
> class="form-label"
>Enable syslog</label
>
</div>
</div>
<div class="col-6">
<div class="form-check form-switch">
<input
type="checkbox"
name="syslog.logBeaconOverTCPIP"
id="syslog.logBeaconOverTCPIP"
class="form-check-input"
/>
<label
for="syslog.logBeaconOverTCPIP"
class="form-label"
>Log Beacon over TCP/IP</label
>
</div>
</div>
</div> </div>
<div class="row mt-3"> <div class="row mt-3">
<div class="col-6"> <div class="col-6">
@@ -1405,21 +1473,7 @@
class="form-control" class="form-control"
/> />
</div> </div>
<div class="col-6">
<div class="form-check form-switch">
<input
type="checkbox"
name="syslog.logBeaconOverTCPIP"
id="syslog.logBeaconOverTCPIP"
class="form-check-input"
/>
<label
for="syslog.logBeaconOverTCPIP"
class="form-label"
>Log Beacon over TCP/IP</label
>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -1540,7 +1594,7 @@
</div> </div>
<div class="col-lg-9 col-sm-12"> <div class="col-lg-9 col-sm-12">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-6">
<div class="form-check form-switch"> <div class="form-check form-switch">
<input <input
type="checkbox" type="checkbox"
@@ -1555,7 +1609,24 @@
> >
</div> </div>
</div> </div>
<div class="col-12"> <div class="col-6">
<div class="form-check form-switch">
<input
type="checkbox"
name="mqtt.beaconOverMqtt"
id="mqtt.beaconOverMqtt"
class="form-check-input"
/>
<label
for="mqtt.beaconOverMqtt"
class="form-label"
>Send (also) iGate Beacon</label
>
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-6">
<label <label
for="mqtt.server" for="mqtt.server"
class="form-label" class="form-label"
@@ -1570,11 +1641,11 @@
/> />
</div> </div>
</div> </div>
<div class="col-12"> <div class="col-6">
<label <label
for="mqtt.topic" for="mqtt.topic"
class="form-label" class="form-label"
>Topic</label >Topic <small>(Default is <strong>aprs-igate</strong>)</small></label
> >
<div class="input-group"> <div class="input-group">
<input <input
@@ -1585,11 +1656,10 @@
placeholder="aprs-igate" placeholder="aprs-igate"
/> />
</div> </div>
<div class="form-text">
Default is <strong>aprs-igate</strong>
</div>
</div> </div>
<div class="col-12"> </div>
<div class="row mt-3">
<div class="col-6">
<label <label
for="mqtt.username" for="mqtt.username"
class="form-label" class="form-label"
@@ -1604,7 +1674,7 @@
/> />
</div> </div>
</div> </div>
<div class="col-12 mt-3"> <div class="col-6">
<label <label
for="mqtt.password" for="mqtt.password"
class="form-label" class="form-label"
@@ -1619,11 +1689,13 @@
/> />
</div> </div>
</div> </div>
<div class="col-12 mt-3"> </div>
<div class="row mt-3">
<div class="col-6">
<label <label
for="mqtt.port" for="mqtt.port"
class="form-label" class="form-label"
>Port</label >Port <small>(Default is <strong>1883</strong>)</small></label
> >
<div class="input-group"> <div class="input-group">
<input <input
@@ -1637,9 +1709,6 @@
min="0" min="0"
/> />
</div> </div>
<div class="form-text">
Default is <strong>1883</strong>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -1667,9 +1736,9 @@
Reboot Time Reboot Time
</h5> </h5>
</div> </div>
<div class="col-9 mt-2"> <div class="col-9">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-6">
<div class="form-check form-switch"> <div class="form-check form-switch">
<input <input
type="checkbox" type="checkbox"
@@ -1684,8 +1753,6 @@
> >
</div> </div>
</div> </div>
</div>
<div class="row mt-3">
<div class="col-6"> <div class="col-6">
<label <label
for="other.rebootModeTime" for="other.rebootModeTime"
@@ -1740,49 +1807,55 @@
WiFi Auto AP WiFi Auto AP
</h5> </h5>
<small <small
>Add your password and WiFi AP timeout to >WiFi AP will start if there is no WiFi
auto access point. Auto AP will start if connection available. Timeout will count from
there is no WiFi connection. Timeout will startup or last client disconnected.</small
count from startup or last client
disconnected.</small
> >
</div> </div>
<div class="col-lg-9 col-sm-12"> <div class="col-9">
<div class="col-12"> <div class="row">
<label <div class="col-6">
for="wifi.autoAP.password" <label
class="form-label" for="wifi.autoAP.password"
>Password</label class="form-label"
> >Password</label
<input >
type="password" <div class="input-group">
name="wifi.autoAP.password" <input
id="wifi.autoAP.password" type="password"
class="form-control" name="wifi.autoAP.password"
placeholder="1234567890" id="wifi.autoAP.password"
required="" class="form-control"
/> placeholder="1234567890"
</div> required=""
<div class="col-12 mt-3"> />
<label </div>
for="wifi.autoAP.timeout" </div>
class="form-label" <div class="col-6">
>WiFi AP timeout to search again for available WiFi's <label
<small>(in minutes)</small></label for="wifi.autoAP.timeout"
> class="form-label"
<input >WiFiAP timeout (to search again)</label
type="number" >
name="wifi.autoAP.timeout" <div class="input-group">
id="wifi.autoAP.timeout" <input
class="form-control" type="number"
placeholder="10" name="wifi.autoAP.timeout"
required="" id="wifi.autoAP.timeout"
step="1" class="form-control"
min="0" placeholder="10"
/> required=""
<div class="form-text"> step="1"
Set to <strong>0</strong> if you don't min="0"
want WiFi AP to stop. />
<span class="input-group-text"
>minutes</span
>
<div class="form-text">
Set to <strong>0</strong> if you don't
want WiFi AP to stop.
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -1813,27 +1886,29 @@
> >
</div> </div>
<div class="col-lg-9 col-sm-12"> <div class="col-lg-9 col-sm-12">
<div class="col-12"> <div class="row">
<label for="ota.username" class="form-label" <div class="col-6">
>Username</label <label for="ota.username" class="form-label"
> >Username</label
<input >
type="text" <input
name="ota.username" type="text"
id="ota.username" name="ota.username"
class="form-control" id="ota.username"
/> class="form-control"
</div> />
<div class="col-12 mt-3"> </div>
<label for="ota.password" class="form-label" <div class="col-6">
>Password</label <label for="ota.password" class="form-label"
> >Password</label
<input >
type="password" <input
name="ota.password" type="password"
id="ota.password" name="ota.password"
class="form-control" id="ota.password"
/> class="form-control"
/>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -1863,46 +1938,46 @@
> >
</div> </div>
<div class="col-lg-9 col-sm-12"> <div class="col-lg-9 col-sm-12">
<div class="row"> <div class="col-6">
<div class="col-12"> <div class="form-check form-switch">
<div class="form-check form-switch"> <input
<input type="checkbox"
type="checkbox" name="webadmin.active"
name="webadmin.active" id="webadmin.active"
id="webadmin.active" class="form-check-input"
class="form-check-input" />
/> <label
<label for="webadmin.active"
for="webadmin.active" class="form-label"
class="form-label" >Web interface authentication</label
>Web interface authentication</label >
>
</div>
</div> </div>
</div> </div>
<div class="col-12"> <div class="row">
<label for="webadmin.username" class="form-label" <div class="col-6">
>Username</label <label for="webadmin.username" class="form-label"
> >Username</label
<input >
type="text" <input
name="webadmin.username" type="text"
id="webadmin.username" name="webadmin.username"
class="form-control" id="webadmin.username"
value="admin" class="form-control"
required="" value="admin"
/> required=""
</div> />
<div class="col-12 mt-3"> </div>
<label for="webadmin.password" class="form-label" <div class="col-6">
>Password</label <label for="webadmin.password" class="form-label"
> >Password</label
<input >
type="password" <input
name="webadmin.password" type="password"
id="webadmin.password" name="webadmin.password"
class="form-control" id="webadmin.password"
/> class="form-control"
/>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -1946,21 +2021,19 @@
/> />
</div> </div>
</div> </div>
<div class="row"> <div class="col-12 mt-3">
<div class="col-12"> <div class="form-check form-switch">
<div class="form-check form-switch"> <input
<input type="checkbox"
type="checkbox" name="remoteManagement.rfOnly"
name="remoteManagement.rfOnly" id="remoteManagement.rfOnly"
id="remoteManagement.rfOnly" class="form-check-input"
class="form-check-input" />
/> <label
<label for="remoteManagement.rfOnly"
for="remoteManagement.rfOnly" class="form-label"
class="form-label" >Managers commands only via RF (not APRS-IS)</label
>Managers commands only via RF (not APRS-IS)</label >
>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -1990,26 +2063,43 @@
</small> </small>
</div> </div>
<div class="col-lg-9 col-sm-12"> <div class="col-lg-9 col-sm-12">
<div class="col-12"> <div class="row">
<label <div class="col-6">
for="ntp.gmtCorrection" <label
class="form-label" for="ntp.server"
>GMT Time Correction for accurate Local Time</label class="form-label"
> >NTP Server hostname</label
<div class="input-group">
<input
type="number"
name="ntp.gmtCorrection"
id="ntp.gmtCorrection"
placeholder="0"
class="form-control"
step="0.25"
min="-23.75"
max="23.75"
/>
<span class="input-group-text"
>hours</span
> >
<div class="input-group">
<input
type="text"
name="ntp.server"
id="ntp.server"
class="form-control"
/>
</div>
</div>
<div class="col-6">
<label
for="ntp.gmtCorrection"
class="form-label"
>GMT Time Correction Offset</label
>
<div class="input-group">
<input
type="number"
name="ntp.gmtCorrection"
id="ntp.gmtCorrection"
placeholder="0"
class="form-control"
step="0.25"
min="-23.75"
max="23.75"
/>
<span class="input-group-text"
>hours</span
>
</div>
</div> </div>
</div> </div>
</div> </div>
+31 -72
View File
@@ -95,6 +95,7 @@ function loadSettings(settings) {
networksContainer.appendChild(networkElement); networksContainer.appendChild(networkElement);
networkCount++; networkCount++;
}); });
document.getElementById("startupDelay").value = settings.startupDelay;
// APRS-IS // APRS-IS
document.getElementById("aprs_is.active").checked = settings.aprs_is.active; document.getElementById("aprs_is.active").checked = settings.aprs_is.active;
@@ -118,7 +119,11 @@ function loadSettings(settings) {
document.getElementById("beacon.interval").value = settings.beacon.interval; document.getElementById("beacon.interval").value = settings.beacon.interval;
document.getElementById("other.rememberStationTime").value = settings.other.rememberStationTime; document.getElementById("other.rememberStationTime").value = settings.other.rememberStationTime;
document.getElementById("beacon.sendViaAPRSIS").checked = settings.beacon.sendViaAPRSIS; document.getElementById("beacon.sendViaAPRSIS").checked = settings.beacon.sendViaAPRSIS;
document.getElementById("beacon.sendViaRF").checked = settings.beacon.sendViaRF; document.getElementById("beacon.sendViaRF").checked = settings.beacon.sendViaRF;
document.getElementById("beacon.beaconFreq").value = settings.beacon.beaconFreq;
BeaconingViaRFCheckbox.checked = settings.beacon.sendViaRF;
BeaconingFrequency.disabled = !BeaconingViaRFCheckbox.checked;
document.getElementById("beacon.statusActive").checked = settings.beacon.statusActive; document.getElementById("beacon.statusActive").checked = settings.beacon.statusActive;
document.getElementById("beacon.statusPacket").value = settings.beacon.statusPacket; document.getElementById("beacon.statusPacket").value = settings.beacon.statusPacket;
@@ -136,13 +141,16 @@ function loadSettings(settings) {
document.getElementById("digi.ecoMode").value = settings.digi.ecoMode; document.getElementById("digi.ecoMode").value = settings.digi.ecoMode;
// LoRa // LoRa
document.getElementById("lora.txFreq").value = settings.lora.txFreq;
document.getElementById("lora.rxFreq").value = settings.lora.rxFreq;
document.getElementById("lora.txActive").checked = settings.lora.txActive;
document.getElementById("lora.rxActive").checked = settings.lora.rxActive; document.getElementById("lora.rxActive").checked = settings.lora.rxActive;
document.getElementById("lora.spreadingFactor").value = settings.lora.spreadingFactor; document.getElementById("lora.rxFreq").value = settings.lora.rxFreq;
document.getElementById("lora.signalBandwidth").value = settings.lora.signalBandwidth; document.getElementById("lora.rxSpreadingFactor").value = settings.lora.rxSpreadingFactor;
document.getElementById("lora.codingRate4").value = settings.lora.codingRate4; document.getElementById("lora.rxCodingRate4").value = settings.lora.rxCodingRate4;
document.getElementById("lora.rxSignalBandwidth").value = settings.lora.rxSignalBandwidth;
document.getElementById("lora.txActive").checked = settings.lora.txActive;
document.getElementById("lora.txFreq").value = settings.lora.txFreq;
document.getElementById("lora.txSpreadingFactor").value = settings.lora.txSpreadingFactor;
document.getElementById("lora.txCodingRate4").value = settings.lora.txCodingRate4;
document.getElementById("lora.txSignalBandwidth").value = settings.lora.txSignalBandwidth;
document.getElementById("lora.power").value = settings.lora.power; document.getElementById("lora.power").value = settings.lora.power;
// Display // Display
@@ -207,12 +215,14 @@ function loadSettings(settings) {
document.getElementById("mqtt.username").value = settings.mqtt.username; document.getElementById("mqtt.username").value = settings.mqtt.username;
document.getElementById("mqtt.password").value = settings.mqtt.password; document.getElementById("mqtt.password").value = settings.mqtt.password;
document.getElementById("mqtt.port").value = settings.mqtt.port; document.getElementById("mqtt.port").value = settings.mqtt.port;
MqttCheckbox.checked = settings.mqtt.active; document.getElementById("mqtt.beaconOverMqtt").value = settings.mqtt.beaconOverMqtt;
MqttServer.disabled = !MqttCheckbox.check; MqttCheckbox.checked = settings.mqtt.active;
MqttTopic.disabled = !MqttCheckbox.check; MqttServer.disabled = !MqttCheckbox.check;
MqttUsername.disabled = !MqttCheckbox.check; MqttTopic.disabled = !MqttCheckbox.check;
MqttPassword.disabled = !MqttCheckbox.check; MqttUsername.disabled = !MqttCheckbox.check;
MqttPort.disabled = !MqttCheckbox.check; MqttPassword.disabled = !MqttCheckbox.check;
MqttPort.disabled = !MqttCheckbox.check;
MqttBeaconOverMqtt.disabled = !MqttCheckbox.check;
// Reboot // Reboot
document.getElementById("other.rebootMode").checked = settings.other.rebootMode; document.getElementById("other.rebootMode").checked = settings.other.rebootMode;
@@ -241,13 +251,13 @@ function loadSettings(settings) {
document.getElementById("remoteManagement.rfOnly").checked = settings.remoteManagement.rfOnly; document.getElementById("remoteManagement.rfOnly").checked = settings.remoteManagement.rfOnly;
// NTP // NTP
document.getElementById("ntp.server").value = settings.ntp.server;
document.getElementById("ntp.gmtCorrection").value = settings.ntp.gmtCorrection; document.getElementById("ntp.gmtCorrection").value = settings.ntp.gmtCorrection;
// Experimental // Experimental
document.getElementById("other.backupDigiMode").checked = settings.other.backupDigiMode; document.getElementById("other.backupDigiMode").checked = settings.other.backupDigiMode;
updateImage(); updateImage();
refreshSpeedStandard();
} }
function showToast(message) { function showToast(message) {
@@ -299,6 +309,12 @@ function updateImage() {
} }
} }
// Beaconing Switches
const BeaconingViaRFCheckbox = document.querySelector('input[name="beacon.sendViaRF"]');
const BeaconingFrequency = document.querySelector('select[name="beacon.beaconFreq"]');
BeaconingViaRFCheckbox.addEventListener("change", function() {
BeaconingFrequency.disabled = !this.checked;
});
// Status Switch // Status Switch
const StatusCheckbox = document.querySelector('input[name="beacon.statusActive"]'); const StatusCheckbox = document.querySelector('input[name="beacon.statusActive"]');
@@ -379,12 +395,14 @@ const MqttTopic = document.querySelector('input[name="mqtt.topic
const MqttUsername = document.querySelector('input[name="mqtt.username"]'); const MqttUsername = document.querySelector('input[name="mqtt.username"]');
const MqttPassword = document.querySelector('input[name="mqtt.password"]'); const MqttPassword = document.querySelector('input[name="mqtt.password"]');
const MqttPort = document.querySelector('input[name="mqtt.port"]'); const MqttPort = document.querySelector('input[name="mqtt.port"]');
const MqttBeaconOverMqtt = document.querySelector('input[name="mqtt.beaconOverMqtt"]');
MqttCheckbox.addEventListener("change", function () { MqttCheckbox.addEventListener("change", function () {
MqttServer.disabled = !this.checked; MqttServer.disabled = !this.checked;
MqttTopic.disabled = !this.checked; MqttTopic.disabled = !this.checked;
MqttUsername.disabled = !this.checked; MqttUsername.disabled = !this.checked;
MqttPassword.disabled = !this.checked; MqttPassword.disabled = !this.checked;
MqttPort.disabled = !this.checked; MqttPort.disabled = !this.checked;
MqttBeaconOverMqtt.disabled = !this.checked;
}); });
// Reboot Switches // Reboot Switches
@@ -451,65 +469,6 @@ document
updateImage(); updateImage();
}); });
const speedStandards = {
300: [125, 5, 12],
244: [125, 6, 12],
209: [125, 7, 12],
183: [125, 8, 12],
610: [125, 8, 10],
1200: [125, 7, 9],
};
function refreshSpeedStandard() {
const bw = Number(document.getElementById("lora.signalBandwidth").value);
const cr4 = Number(document.getElementById("lora.codingRate4").value);
const sf = Number(document.getElementById("lora.spreadingFactor").value);
let found = false;
for (const speed in speedStandards) {
const standard = speedStandards[speed];
if (standard[0] !== bw / 1000) continue;
if (standard[1] !== cr4) continue;
if (standard[2] !== sf) continue;
document.getElementById("action.speed").value = speed;
found = true;
break;
}
if (!found) {
document.getElementById("action.speed").value = "";
}
}
document
.getElementById("lora.signalBandwidth")
.addEventListener("focusout", refreshSpeedStandard);
document
.getElementById("lora.codingRate4")
.addEventListener("focusout", refreshSpeedStandard);
document
.getElementById("lora.spreadingFactor")
.addEventListener("focusout", refreshSpeedStandard);
document.getElementById("action.speed").addEventListener("change", function () {
const speed = document.getElementById("action.speed").value;
if (speed !== "") {
const value = speedStandards[Number(speed)];
const bw = value[0];
const cr4 = value[1];
const sf = value[2];
document.getElementById("lora.signalBandwidth").value = bw * 1000;
document.getElementById("lora.codingRate4").value = cr4;
document.getElementById("lora.spreadingFactor").value = sf;
}
});
const form = document.querySelector("form"); const form = document.querySelector("form");
Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 711 KiB

+17 -10
View File
@@ -45,12 +45,13 @@ public:
String overlay; String overlay;
String symbol; String symbol;
String path; String path;
bool sendViaRF;
bool sendViaAPRSIS; bool sendViaAPRSIS;
bool gpsActive; bool sendViaRF;
bool gpsAmbiguity; int beaconFreq;
bool statusActive; bool statusActive;
String statusPacket; String statusPacket;
bool gpsActive;
bool gpsAmbiguity;
}; };
class APRS_IS { class APRS_IS {
@@ -67,18 +68,21 @@ public:
class DIGI { class DIGI {
public: public:
int mode; int mode;
int ecoMode; // 0 = Not Active | 1 = Ultra EcoMode | 2 = Not Active (WiFi OFF, Serial ON) int ecoMode; // 0 = Not Active | 1 = Ultra EcoMode | 2 = Not Active (WiFi OFF, Serial ON)
}; };
class LoraModule { class LoraModule {
public: public:
long txFreq;
long rxFreq;
bool txActive;
bool rxActive; bool rxActive;
int spreadingFactor; long rxFreq;
long signalBandwidth; int rxSpreadingFactor;
int codingRate4; int rxCodingRate4;
long rxSignalBandwidth;
bool txActive;
long txFreq;
int txSpreadingFactor;
int txCodingRate4;
long txSignalBandwidth;
int power; int power;
}; };
@@ -140,6 +144,7 @@ public:
class NTP { class NTP {
public: public:
String server;
float gmtCorrection; float gmtCorrection;
}; };
@@ -157,6 +162,7 @@ public:
String username; String username;
String password; String password;
int port; int port;
bool beaconOverMqtt;
}; };
class Configuration { class Configuration {
@@ -166,6 +172,7 @@ public:
bool backupDigiMode; bool backupDigiMode;
bool rebootMode; bool rebootMode;
int rebootModeTime; int rebootModeTime;
int startupDelay;
String personalNote; String personalNote;
String blacklist; String blacklist;
std::vector<WiFi_AP> wifiAPs; std::vector<WiFi_AP> wifiAPs;
+1 -7
View File
@@ -23,12 +23,6 @@
#include <Arduino.h> #include <Arduino.h>
struct Packet25SegBuffer {
uint32_t receivedTime;
String station;
String payload;
};
struct LastHeardStation { struct LastHeardStation {
uint32_t lastHeardTime; uint32_t lastHeardTime;
String station; String station;
@@ -47,7 +41,7 @@ namespace STATION_Utils {
bool check25SegBuffer(const String& station, const String& textMessage); bool check25SegBuffer(const String& station, const String& textMessage);
void processOutputPacketBufferUltraEcoMode(); void processOutputPacketBufferUltraEcoMode();
void processOutputPacketBuffer(); void processOutputPacketBuffer();
void addToOutputPacketBuffer(const String& packet); void addToOutputPacketBuffer(const String& packet, bool flag = false);
} }
+2 -1
View File
@@ -35,7 +35,7 @@ namespace Utils {
void processStatus(); void processStatus();
String getLocalIP(); String getLocalIP();
void setupDisplay(); void setupDisplay();
void activeStations(); void showActiveStations();
void checkBeaconInterval(); void checkBeaconInterval();
void checkDisplayInterval(); void checkDisplayInterval();
void validateFreqs(); void validateFreqs();
@@ -46,6 +46,7 @@ namespace Utils {
void checkRebootTime(); void checkRebootTime();
void checkSleepByLowBatteryVoltage(uint8_t mode); void checkSleepByLowBatteryVoltage(uint8_t mode);
bool checkValidCallsign(const String& callsign); bool checkValidCallsign(const String& callsign);
void startupDelay();
} }
Binary file not shown.
+4 -10
View File
@@ -33,7 +33,7 @@
╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝
Ricardo Guzman - CA2RXU Ricardo Guzman - CA2RXU
https://github.com/richonguzman/LoRa_APRS_iGate https://github.com/richonguzman/LoRa_APRS_iGate
(donations : http://paypal.me/richonguzman) (donations : http://paypal.me/richonguzman)
___________________________________________________________________*/ ___________________________________________________________________*/
@@ -67,8 +67,8 @@ ___________________________________________________________________*/
#endif #endif
String versionDate = "2025-09-26"; String versionDate = "2025-10-15";
String versionNumber = "3.1.2.1"; String versionNumber = "3.1.4";
Configuration Config; Configuration Config;
WiFiClient aprsIsClient; WiFiClient aprsIsClient;
WiFiClient mqttClient; WiFiClient mqttClient;
@@ -97,7 +97,6 @@ bool modemLoggedToAPRSIS = false;
std::vector<ReceivedPacket> receivedPackets; std::vector<ReceivedPacket> receivedPackets;
String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine; String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine;
//#define STARTUP_DELAY 5 //min
void setup() { void setup() {
@@ -108,12 +107,7 @@ void setup() {
Utils::validateFreqs(); Utils::validateFreqs();
GPS_Utils::setup(); GPS_Utils::setup();
STATION_Utils::loadBlacklistAndManagers(); STATION_Utils::loadBlacklistAndManagers();
Utils::startupDelay();
#ifdef STARTUP_DELAY // (TEST) just to wait for WiFi init of Routers
displayShow("", " STARTUP DELAY ...", "", "", 0);
delay(STARTUP_DELAY * 60 * 1000);
#endif
SLEEP_Utils::setup(); SLEEP_Utils::setup();
WIFI_Utils::setup(); WIFI_Utils::setup();
NTP_Utils::setup(); NTP_Utils::setup();
+69 -35
View File
@@ -45,9 +45,13 @@ bool Configuration::writeFile() {
} }
} }
data["other"]["startupDelay"] = startupDelay;
data["wifi"]["autoAP"]["password"] = wifiAutoAP.password; data["wifi"]["autoAP"]["password"] = wifiAutoAP.password;
data["wifi"]["autoAP"]["timeout"] = wifiAutoAP.timeout; data["wifi"]["autoAP"]["timeout"] = wifiAutoAP.timeout;
callsign.trim();
callsign.toUpperCase();
data["callsign"] = callsign; data["callsign"] = callsign;
data["aprs_is"]["active"] = aprs_is.active; data["aprs_is"]["active"] = aprs_is.active;
@@ -64,9 +68,11 @@ bool Configuration::writeFile() {
data["beacon"]["longitude"] = beacon.longitude; data["beacon"]["longitude"] = beacon.longitude;
data["beacon"]["overlay"] = beacon.overlay; data["beacon"]["overlay"] = beacon.overlay;
data["beacon"]["symbol"] = beacon.symbol; data["beacon"]["symbol"] = beacon.symbol;
data["beacon"]["path"] = beacon.path;
data["beacon"]["sendViaAPRSIS"] = beacon.sendViaAPRSIS; data["beacon"]["sendViaAPRSIS"] = beacon.sendViaAPRSIS;
data["beacon"]["sendViaRF"] = beacon.sendViaRF; data["beacon"]["sendViaRF"] = beacon.sendViaRF;
data["beacon"]["path"] = beacon.path; data["beacon"]["beaconFreq"] = beacon.beaconFreq;
data["beacon"]["statusActive"] = beacon.statusActive; data["beacon"]["statusActive"] = beacon.statusActive;
data["beacon"]["statusPacket"] = beacon.statusPacket; data["beacon"]["statusPacket"] = beacon.statusPacket;
@@ -84,14 +90,17 @@ bool Configuration::writeFile() {
if (digi.ecoMode == 1) data["digi"]["ecoMode"] = 2; if (digi.ecoMode == 1) data["digi"]["ecoMode"] = 2;
#endif #endif
data["lora"]["rxFreq"] = loramodule.rxFreq;
data["lora"]["txFreq"] = loramodule.txFreq;
data["lora"]["spreadingFactor"] = loramodule.spreadingFactor;
data["lora"]["signalBandwidth"] = loramodule.signalBandwidth;
data["lora"]["codingRate4"] = loramodule.codingRate4;
data["lora"]["power"] = loramodule.power;
data["lora"]["txActive"] = loramodule.txActive;
data["lora"]["rxActive"] = loramodule.rxActive; data["lora"]["rxActive"] = loramodule.rxActive;
data["lora"]["rxFreq"] = loramodule.rxFreq;
data["lora"]["rxSpreadingFactor"] = loramodule.rxSpreadingFactor;
data["lora"]["rxCodingRate4"] = loramodule.rxCodingRate4;
data["lora"]["rxSignalBandwidth"] = loramodule.rxSignalBandwidth;
data["lora"]["txActive"] = loramodule.txActive;
data["lora"]["txFreq"] = loramodule.txFreq;
data["lora"]["txSpreadingFactor"] = loramodule.txSpreadingFactor;
data["lora"]["txCodingRate4"] = loramodule.txCodingRate4;
data["lora"]["txSignalBandwidth"] = loramodule.txSignalBandwidth;
data["lora"]["power"] = loramodule.power;
data["display"]["alwaysOn"] = display.alwaysOn; data["display"]["alwaysOn"] = display.alwaysOn;
data["display"]["timeout"] = display.timeout; data["display"]["timeout"] = display.timeout;
@@ -129,6 +138,7 @@ bool Configuration::writeFile() {
data["mqtt"]["username"] = mqtt.username; data["mqtt"]["username"] = mqtt.username;
data["mqtt"]["password"] = mqtt.password; data["mqtt"]["password"] = mqtt.password;
data["mqtt"]["port"] = mqtt.port; data["mqtt"]["port"] = mqtt.port;
data["mqtt"]["beaconOverMqtt"] = mqtt.beaconOverMqtt;
data["ota"]["username"] = ota.username; data["ota"]["username"] = ota.username;
data["ota"]["password"] = ota.password; data["ota"]["password"] = ota.password;
@@ -140,6 +150,7 @@ bool Configuration::writeFile() {
data["remoteManagement"]["managers"] = remoteManagement.managers; data["remoteManagement"]["managers"] = remoteManagement.managers;
data["remoteManagement"]["rfOnly"] = remoteManagement.rfOnly; data["remoteManagement"]["rfOnly"] = remoteManagement.rfOnly;
data["ntp"]["server"] = ntp.server;
data["ntp"]["gmtCorrection"] = ntp.gmtCorrection; data["ntp"]["gmtCorrection"] = ntp.gmtCorrection;
data["other"]["rebootMode"] = rebootMode; data["other"]["rebootMode"] = rebootMode;
@@ -181,6 +192,9 @@ bool Configuration::readFile() {
wifiAPs.push_back(wifiap); wifiAPs.push_back(wifiap);
} }
if (!data["other"].containsKey("startupDelay")) needsRewrite = true;
startupDelay = data["other"]["startupDelay"] | 0;
if (!data["wifi"]["autoAP"].containsKey("password") || if (!data["wifi"]["autoAP"].containsKey("password") ||
!data["wifi"]["autoAP"].containsKey("timeout")) needsRewrite = true; !data["wifi"]["autoAP"].containsKey("timeout")) needsRewrite = true;
wifiAutoAP.password = data["wifi"]["autoAP"]["password"] | "1234567890"; wifiAutoAP.password = data["wifi"]["autoAP"]["password"] | "1234567890";
@@ -213,6 +227,7 @@ bool Configuration::readFile() {
!data["beacon"].containsKey("path") || !data["beacon"].containsKey("path") ||
!data["beacon"].containsKey("sendViaAPRSIS") || !data["beacon"].containsKey("sendViaAPRSIS") ||
!data["beacon"].containsKey("sendViaRF") || !data["beacon"].containsKey("sendViaRF") ||
!data["beacon"].containsKey("beaconFreq") ||
!data["beacon"].containsKey("statusActive") || !data["beacon"].containsKey("statusActive") ||
!data["beacon"].containsKey("statusPacket") || !data["beacon"].containsKey("statusPacket") ||
!data["beacon"].containsKey("gpsActive") || !data["beacon"].containsKey("gpsActive") ||
@@ -226,6 +241,7 @@ bool Configuration::readFile() {
beacon.path = data["beacon"]["path"] | "WIDE1-1"; beacon.path = data["beacon"]["path"] | "WIDE1-1";
beacon.sendViaAPRSIS = data["beacon"]["sendViaAPRSIS"] | false; beacon.sendViaAPRSIS = data["beacon"]["sendViaAPRSIS"] | false;
beacon.sendViaRF = data["beacon"]["sendViaRF"] | false; beacon.sendViaRF = data["beacon"]["sendViaRF"] | false;
beacon.beaconFreq = data["beacon"]["beaconFreq"] | 1;
beacon.statusActive = data["beacon"]["statusActive"] | false; beacon.statusActive = data["beacon"]["statusActive"] | false;
beacon.statusPacket = data["beacon"]["statusPacket"] | ""; beacon.statusPacket = data["beacon"]["statusPacket"] | "";
beacon.gpsActive = data["beacon"]["gpsActive"] | false; beacon.gpsActive = data["beacon"]["gpsActive"] | false;
@@ -242,28 +258,33 @@ bool Configuration::readFile() {
digi.mode = data["digi"]["mode"] | 0; digi.mode = data["digi"]["mode"] | 0;
digi.ecoMode = data["digi"]["ecoMode"] | 0; digi.ecoMode = data["digi"]["ecoMode"] | 0;
if (digi.ecoMode == 1) shouldSleepStop = false; if (digi.ecoMode == 1) shouldSleepStop = false;
#if defined(HAS_A7670) #if defined(HAS_A7670)
if (digi.ecoMode == 1) digi.ecoMode = 2; if (digi.ecoMode == 1) digi.ecoMode = 2;
#endif #endif
if (!data["lora"].containsKey("txFreq") || if (!data["lora"].containsKey("rxActive") ||
!data["lora"].containsKey("rxFreq") || !data["lora"].containsKey("rxFreq") ||
!data["lora"].containsKey("spreadingFactor") || !data["lora"].containsKey("rxSpreadingFactor") ||
!data["lora"].containsKey("signalBandwidth") || !data["lora"].containsKey("rxCodingRate4") ||
!data["lora"].containsKey("codingRate4") || !data["lora"].containsKey("rxSignalBandwidth") ||
!data["lora"].containsKey("power") ||
!data["lora"].containsKey("txActive") || !data["lora"].containsKey("txActive") ||
!data["lora"].containsKey("rxActive")) needsRewrite = true; !data["lora"].containsKey("txFreq") ||
loramodule.txFreq = data["lora"]["txFreq"] | 433775000; !data["lora"].containsKey("txSpreadingFactor") ||
!data["lora"].containsKey("txCodingRate4") ||
!data["lora"].containsKey("txSignalBandwidth") ||
!data["lora"].containsKey("power")) needsRewrite = true;
loramodule.rxActive = data["lora"]["rxActive"] | true;
loramodule.rxFreq = data["lora"]["rxFreq"] | 433775000; loramodule.rxFreq = data["lora"]["rxFreq"] | 433775000;
loramodule.spreadingFactor = data["lora"]["spreadingFactor"] | 12; loramodule.rxSpreadingFactor = data["lora"]["rxSpreadingFactor"] | 12;
loramodule.signalBandwidth = data["lora"]["signalBandwidth"] | 125000; loramodule.rxCodingRate4 = data["lora"]["rxCodingRate4"] | 5;
loramodule.codingRate4 = data["lora"]["codingRate4"] | 5; loramodule.rxSignalBandwidth = data["lora"]["rxSignalBandwidth"] | 125000;
loramodule.power = data["lora"]["power"] | 20;
loramodule.txActive = data["lora"]["txActive"] | false; loramodule.txActive = data["lora"]["txActive"] | false;
loramodule.rxActive = data["lora"]["rxActive"] | false; loramodule.txFreq = data["lora"]["txFreq"] | 433775000;
loramodule.txSpreadingFactor = data["lora"]["txSpreadingFactor"] | 12;
loramodule.txCodingRate4 = data["lora"]["txCodingRate4"] | 5;
loramodule.txSignalBandwidth = data["lora"]["txSignalBandwidth"] | 125000;
loramodule.power = data["lora"]["power"] | 20;
if (!data["display"].containsKey("alwaysOn") || if (!data["display"].containsKey("alwaysOn") ||
!data["display"].containsKey("timeout") || !data["display"].containsKey("timeout") ||
!data["display"].containsKey("turn180")) needsRewrite = true; !data["display"].containsKey("turn180")) needsRewrite = true;
@@ -320,13 +341,15 @@ bool Configuration::readFile() {
!data["mqtt"].containsKey("topic") || !data["mqtt"].containsKey("topic") ||
!data["mqtt"].containsKey("username") || !data["mqtt"].containsKey("username") ||
!data["mqtt"].containsKey("password") || !data["mqtt"].containsKey("password") ||
!data["mqtt"].containsKey("port")) needsRewrite = true; !data["mqtt"].containsKey("port") ||
!data["mqtt"].containsKey("beaconOverMqtt")) needsRewrite = true;
mqtt.active = data["mqtt"]["active"] | false; mqtt.active = data["mqtt"]["active"] | false;
mqtt.server = data["mqtt"]["server"] | ""; mqtt.server = data["mqtt"]["server"] | "";
mqtt.topic = data["mqtt"]["topic"] | "aprs-igate"; mqtt.topic = data["mqtt"]["topic"] | "aprs-igate";
mqtt.username = data["mqtt"]["username"] | ""; mqtt.username = data["mqtt"]["username"] | "";
mqtt.password = data["mqtt"]["password"] | ""; mqtt.password = data["mqtt"]["password"] | "";
mqtt.port = data["mqtt"]["port"] | 1883; mqtt.port = data["mqtt"]["port"] | 1883;
mqtt.beaconOverMqtt = data["mqtt"]["beaconOverMqtt"] | false;
if (!data["ota"].containsKey("username") || if (!data["ota"].containsKey("username") ||
!data["ota"].containsKey("password")) needsRewrite = true; !data["ota"].containsKey("password")) needsRewrite = true;
@@ -345,7 +368,9 @@ bool Configuration::readFile() {
remoteManagement.managers = data["remoteManagement"]["managers"] | ""; remoteManagement.managers = data["remoteManagement"]["managers"] | "";
remoteManagement.rfOnly = data["remoteManagement"]["rfOnly"] | true; remoteManagement.rfOnly = data["remoteManagement"]["rfOnly"] | true;
if (!data["ntp"].containsKey("gmtCorrection")) needsRewrite = true; if (!data["ntp"].containsKey("server") ||
!data["ntp"].containsKey("gmtCorrection")) needsRewrite = true;
ntp.server = data["ntp"]["server"] | "pool.ntp.org";
ntp.gmtCorrection = data["ntp"]["gmtCorrection"] | 0.0; ntp.gmtCorrection = data["ntp"]["gmtCorrection"] | 0.0;
if (!data["other"].containsKey("rebootMode") || if (!data["other"].containsKey("rebootMode") ||
@@ -371,7 +396,7 @@ bool Configuration::readFile() {
if (needsRewrite) { if (needsRewrite) {
Serial.println("Config JSON incomplete, rewriting..."); Serial.println("Config JSON incomplete, rewriting...");
writeFile(); writeFile();
delay(500); delay(1000);
ESP.restart(); ESP.restart();
} }
Serial.println("Config read successfuly"); Serial.println("Config read successfuly");
@@ -390,6 +415,8 @@ void Configuration::setDefaultValues() {
wifiAPs.push_back(wifiap); wifiAPs.push_back(wifiap);
startupDelay = 0;
wifiAutoAP.password = "1234567890"; wifiAutoAP.password = "1234567890";
wifiAutoAP.timeout = 10; wifiAutoAP.timeout = 10;
@@ -409,10 +436,12 @@ void Configuration::setDefaultValues() {
beacon.interval = 15; beacon.interval = 15;
beacon.overlay = "L"; beacon.overlay = "L";
beacon.symbol = "a"; beacon.symbol = "a";
beacon.sendViaAPRSIS = true;
beacon.sendViaRF = false;
beacon.path = "WIDE1-1"; beacon.path = "WIDE1-1";
beacon.sendViaAPRSIS = true;
beacon.sendViaRF = false;
beacon.beaconFreq = 1;
beacon.statusActive = false; beacon.statusActive = false;
beacon.statusPacket = ""; beacon.statusPacket = "";
@@ -426,14 +455,17 @@ void Configuration::setDefaultValues() {
digi.mode = 0; digi.mode = 0;
digi.ecoMode = 0; digi.ecoMode = 0;
loramodule.txFreq = 433775000;
loramodule.rxFreq = 433775000;
loramodule.spreadingFactor = 12;
loramodule.signalBandwidth = 125000;
loramodule.codingRate4 = 5;
loramodule.power = 20;
loramodule.txActive = false;
loramodule.rxActive = true; loramodule.rxActive = true;
loramodule.rxFreq = 433775000;
loramodule.rxSpreadingFactor = 12;
loramodule.rxCodingRate4 = 5;
loramodule.rxSignalBandwidth = 125000;
loramodule.txActive = false;
loramodule.txFreq = 433775000;
loramodule.txSpreadingFactor = 12;
loramodule.txCodingRate4 = 5;
loramodule.txSignalBandwidth = 125000;
loramodule.power = 20;
display.alwaysOn = true; display.alwaysOn = true;
display.timeout = 4; display.timeout = 4;
@@ -471,6 +503,7 @@ void Configuration::setDefaultValues() {
mqtt.username = ""; mqtt.username = "";
mqtt.password = ""; mqtt.password = "";
mqtt.port = 1883; mqtt.port = 1883;
mqtt.beaconOverMqtt = false;
ota.username = ""; ota.username = "";
ota.password = ""; ota.password = "";
@@ -482,6 +515,7 @@ void Configuration::setDefaultValues() {
remoteManagement.managers = ""; remoteManagement.managers = "";
remoteManagement.rfOnly = true; remoteManagement.rfOnly = true;
ntp.server = "pool.ntp.org";
ntp.gmtCorrection = 0.0; ntp.gmtCorrection = 0.0;
rebootMode = false; rebootMode = false;
@@ -506,7 +540,7 @@ Configuration::Configuration() {
if (!exists) { if (!exists) {
setDefaultValues(); setDefaultValues();
writeFile(); writeFile();
delay(500); delay(1000);
ESP.restart(); ESP.restart();
} }
+19 -8
View File
@@ -30,6 +30,7 @@
extern Configuration Config; extern Configuration Config;
extern uint32_t lastRxTime; extern uint32_t lastRxTime;
extern bool packetIsBeacon;
extern std::vector<ReceivedPacket> receivedPackets; extern std::vector<ReceivedPacket> receivedPackets;
@@ -92,10 +93,10 @@ namespace LoRa_Utils {
#if defined(HAS_SX1278) || defined(HAS_SX1276) #if defined(HAS_SX1278) || defined(HAS_SX1276)
radio.setDio0Action(setFlag, RISING); radio.setDio0Action(setFlag, RISING);
#endif #endif
radio.setSpreadingFactor(Config.loramodule.spreadingFactor); radio.setSpreadingFactor(Config.loramodule.rxSpreadingFactor);
float signalBandwidth = Config.loramodule.signalBandwidth/1000; radio.setCodingRate(Config.loramodule.rxCodingRate4);
radio.setBandwidth(signalBandwidth); float signalBandwidth = Config.loramodule.rxSignalBandwidth/1000;
radio.setCodingRate(Config.loramodule.codingRate4); radio.setBandwidth(signalBandwidth);
radio.setCRC(true); radio.setCRC(true);
#if (defined(RADIO_RXEN) && defined(RADIO_TXEN)) // QRP Labs LightGateway has 400M22S (SX1268) #if (defined(RADIO_RXEN) && defined(RADIO_TXEN)) // QRP Labs LightGateway has 400M22S (SX1268)
@@ -128,22 +129,30 @@ namespace LoRa_Utils {
} }
void changeFreqTx() { void changeFreqTx() {
delay(500); delay(300);
float freq = (float)Config.loramodule.txFreq / 1000000; float freq = (float)Config.loramodule.txFreq / 1000000;
radio.setFrequency(freq); radio.setFrequency(freq);
radio.setSpreadingFactor(Config.loramodule.txSpreadingFactor);
radio.setCodingRate(Config.loramodule.txCodingRate4);
radio.setBandwidth(Config.loramodule.txSignalBandwidth);
} }
void changeFreqRx() { void changeFreqRx() {
delay(500); delay(300);
float freq = (float)Config.loramodule.rxFreq / 1000000; float freq = (float)Config.loramodule.rxFreq / 1000000;
radio.setFrequency(freq); radio.setFrequency(freq);
radio.setSpreadingFactor(Config.loramodule.rxSpreadingFactor);
radio.setCodingRate(Config.loramodule.rxCodingRate4);
radio.setBandwidth(Config.loramodule.rxSignalBandwidth);
} }
void sendNewPacket(const String& newPacket) { void sendNewPacket(const String& newPacket) {
if (!Config.loramodule.txActive) return; if (!Config.loramodule.txActive) return;
if (Config.loramodule.txFreq != Config.loramodule.rxFreq) { if (Config.loramodule.txFreq != Config.loramodule.rxFreq) {
changeFreqTx(); if (!packetIsBeacon || (packetIsBeacon && Config.beacon.beaconFreq == 1)) {
changeFreqTx();
}
} }
#ifdef INTERNAL_LED_PIN #ifdef INTERNAL_LED_PIN
@@ -165,7 +174,9 @@ namespace LoRa_Utils {
if (Config.digi.ecoMode != 1) digitalWrite(INTERNAL_LED_PIN, LOW); // disabled in Ultra Eco Mode if (Config.digi.ecoMode != 1) digitalWrite(INTERNAL_LED_PIN, LOW); // disabled in Ultra Eco Mode
#endif #endif
if (Config.loramodule.txFreq != Config.loramodule.rxFreq) { if (Config.loramodule.txFreq != Config.loramodule.rxFreq) {
changeFreqRx(); if (!packetIsBeacon || (packetIsBeacon && Config.beacon.beaconFreq == 1)) {
changeFreqRx();
}
} }
} }
+5 -5
View File
@@ -27,7 +27,7 @@
extern Configuration Config; extern Configuration Config;
WiFiUDP ntpUDP; WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 0, 15 * 60 * 1000); // Update interval 15 min NTPClient* timeClient;
namespace NTP_Utils { namespace NTP_Utils {
@@ -35,17 +35,17 @@ namespace NTP_Utils {
void setup() { void setup() {
if (WiFi.status() == WL_CONNECTED && Config.digi.ecoMode == 0 && Config.callsign != "NOCALL-10") { if (WiFi.status() == WL_CONNECTED && Config.digi.ecoMode == 0 && Config.callsign != "NOCALL-10") {
int gmt = Config.ntp.gmtCorrection * 3600; int gmt = Config.ntp.gmtCorrection * 3600;
timeClient.setTimeOffset(gmt); timeClient = new NTPClient(ntpUDP, Config.ntp.server.c_str(), gmt, 15 * 60 * 1000); // Update interval 15 min
timeClient.begin(); timeClient->begin();
} }
} }
void update() { void update() {
if (WiFi.status() == WL_CONNECTED && Config.digi.ecoMode == 0 && Config.callsign != "NOCALL-10") timeClient.update(); if (WiFi.status() == WL_CONNECTED && Config.digi.ecoMode == 0 && Config.callsign != "NOCALL-10") timeClient->update();
} }
String getFormatedTime() { String getFormatedTime() {
if (Config.digi.ecoMode == 0) return timeClient.getFormattedTime(); if (Config.digi.ecoMode == 0) return timeClient->getFormattedTime();
return "DigiEcoMode Active"; return "DigiEcoMode Active";
} }
+31 -8
View File
@@ -33,13 +33,26 @@ extern bool shouldSleepLowVoltage;
uint32_t lastTxTime = millis(); uint32_t lastTxTime = millis();
std::vector<LastHeardStation> lastHeardStations; std::vector<LastHeardStation> lastHeardStations;
std::vector<String> outputPacketBuffer;
std::vector<Packet25SegBuffer> packet25SegBuffer;
std::vector<String> blacklist; std::vector<String> blacklist;
std::vector<String> managers; std::vector<String> managers;
std::vector<LastHeardStation> lastHeardObjects; std::vector<LastHeardStation> lastHeardObjects;
struct OutputPacketBuffer {
String packet;
bool isBeacon;
};
std::vector<OutputPacketBuffer> outputPacketBuffer;
struct Packet25SegBuffer {
uint32_t receivedTime;
String station;
String payload;
};
std::vector<Packet25SegBuffer> packet25SegBuffer;
bool saveNewDigiEcoModeConfig = false; bool saveNewDigiEcoModeConfig = false;
bool packetIsBeacon = false;
namespace STATION_Utils { namespace STATION_Utils {
@@ -138,7 +151,7 @@ namespace STATION_Utils {
} }
} }
if (!stationHeard) lastHeardStations.emplace_back(LastHeardStation{millis(), station}); if (!stationHeard) lastHeardStations.emplace_back(LastHeardStation{millis(), station});
Utils::activeStations(); Utils::showActiveStations();
} }
bool wasHeard(const String& station) { bool wasHeard(const String& station) {
@@ -171,7 +184,9 @@ namespace STATION_Utils {
size_t currentIndex = 0; size_t currentIndex = 0;
while (currentIndex < outputPacketBuffer.size()) { // this sends all packets from output buffer while (currentIndex < outputPacketBuffer.size()) { // this sends all packets from output buffer
delay(3000); // and cleans buffer to avoid sending packets with time offset delay(3000); // and cleans buffer to avoid sending packets with time offset
LoRa_Utils::sendNewPacket(outputPacketBuffer[currentIndex]); // next time it wakes up if (outputPacketBuffer[currentIndex].isBeacon) packetIsBeacon = true;
LoRa_Utils::sendNewPacket(outputPacketBuffer[currentIndex].packet); // next time it wakes up
if (outputPacketBuffer[currentIndex].isBeacon) packetIsBeacon = false;
currentIndex++; currentIndex++;
} }
outputPacketBuffer.clear(); outputPacketBuffer.clear();
@@ -190,13 +205,17 @@ namespace STATION_Utils {
uint32_t lastRx = millis() - lastRxTime; uint32_t lastRx = millis() - lastRxTime;
uint32_t lastTx = millis() - lastTxTime; uint32_t lastTx = millis() - lastTxTime;
if (outputPacketBuffer.size() > 0 && lastTx > timeToWait && lastRx > timeToWait) { if (outputPacketBuffer.size() > 0 && lastTx > timeToWait && lastRx > timeToWait) {
LoRa_Utils::sendNewPacket(outputPacketBuffer[0]); if (outputPacketBuffer[0].isBeacon) packetIsBeacon = true;
LoRa_Utils::sendNewPacket(outputPacketBuffer[0].packet);
if (outputPacketBuffer[0].isBeacon) packetIsBeacon = false;
outputPacketBuffer.erase(outputPacketBuffer.begin()); outputPacketBuffer.erase(outputPacketBuffer.begin());
lastTxTime = millis(); lastTxTime = millis();
} }
if (shouldSleepLowVoltage) { if (shouldSleepLowVoltage) {
while (outputPacketBuffer.size() > 0) { while (outputPacketBuffer.size() > 0) {
LoRa_Utils::sendNewPacket(outputPacketBuffer[0]); if (outputPacketBuffer[0].isBeacon) packetIsBeacon = true;
LoRa_Utils::sendNewPacket(outputPacketBuffer[0].packet);
if (outputPacketBuffer[0].isBeacon) packetIsBeacon = false;
outputPacketBuffer.erase(outputPacketBuffer.begin()); outputPacketBuffer.erase(outputPacketBuffer.begin());
delay(4000); delay(4000);
} }
@@ -209,8 +228,12 @@ namespace STATION_Utils {
} }
} }
void addToOutputPacketBuffer(const String& packet) { void addToOutputPacketBuffer(const String& packet, bool flag) {
outputPacketBuffer.push_back(packet); OutputPacketBuffer entry;
entry.packet = packet;
entry.isBeacon = flag;
outputPacketBuffer.push_back(entry);
} }
} }
+12 -4
View File
@@ -88,7 +88,7 @@ namespace Utils {
if (statusAfterBoot && !Config.beacon.sendViaAPRSIS && Config.beacon.sendViaRF) { if (statusAfterBoot && !Config.beacon.sendViaAPRSIS && Config.beacon.sendViaRF) {
status.concat(":>"); status.concat(":>");
status.concat(Config.beacon.statusPacket); status.concat(Config.beacon.statusPacket);
STATION_Utils::addToOutputPacketBuffer(status); STATION_Utils::addToOutputPacketBuffer(status, true); // treated also as beacon on Tx Freq
statusAfterBoot = false; statusAfterBoot = false;
} }
} }
@@ -127,7 +127,7 @@ namespace Utils {
seventhLine = " listening..."; seventhLine = " listening...";
} }
void activeStations() { void showActiveStations() {
char buffer[30]; // Adjust size as needed char buffer[30]; // Adjust size as needed
sprintf(buffer, "Stations (%dmin) = %2d", Config.rememberStationTime, lastHeardStations.size()); sprintf(buffer, "Stations (%dmin) = %2d", Config.rememberStationTime, lastHeardStations.size());
fourthLine = buffer; fourthLine = buffer;
@@ -159,7 +159,7 @@ namespace Utils {
STATION_Utils::deleteNotHeard(); STATION_Utils::deleteNotHeard();
activeStations(); showActiveStations();
beaconPacket = iGateBeaconPacket; beaconPacket = iGateBeaconPacket;
secondaryBeaconPacket = iGateLoRaBeaconPacket; secondaryBeaconPacket = iGateLoRaBeaconPacket;
@@ -259,7 +259,7 @@ namespace Utils {
Utils::println("-- Sending Beacon to RF --"); Utils::println("-- Sending Beacon to RF --");
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING DIGI BEACON", 0); displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, "SENDING DIGI BEACON", 0);
seventhLine = " listening..."; seventhLine = " listening...";
STATION_Utils::addToOutputPacketBuffer(secondaryBeaconPacket); STATION_Utils::addToOutputPacketBuffer(secondaryBeaconPacket, true);
} }
lastBeaconTx = millis(); lastBeaconTx = millis();
@@ -284,6 +284,7 @@ namespace Utils {
Serial.println("Tx Freq less than 125kHz from Rx Freq ---> NOT VALID"); Serial.println("Tx Freq less than 125kHz from Rx Freq ---> NOT VALID");
displayShow("Tx Freq is less than ", "125kHz from Rx Freq", "device will autofix", "and then reboot", 1000); displayShow("Tx Freq is less than ", "125kHz from Rx Freq", "device will autofix", "and then reboot", 1000);
Config.loramodule.txFreq = Config.loramodule.rxFreq; // Inform about that but then change the TX QRG to RX QRG and reset the device Config.loramodule.txFreq = Config.loramodule.rxFreq; // Inform about that but then change the TX QRG to RX QRG and reset the device
Config.beacon.beaconFreq = 1; // return to LoRa Tx Beacon Freq
Config.writeFile(); Config.writeFile();
ESP.restart(); ESP.restart();
} }
@@ -436,4 +437,11 @@ namespace Utils {
return true; return true;
} }
void startupDelay() {
if (Config.startupDelay > 0) {
displayShow("", " STARTUP DELAY ...", "", "", 0);
delay(Config.startupDelay * 60 * 1000);
}
}
} }
+16 -7
View File
@@ -157,6 +157,8 @@ namespace WEB_Utils {
Config.wifiAPs.push_back(wifiap); Config.wifiAPs.push_back(wifiap);
} }
Config.startupDelay = getParamIntSafe("startupDelay", Config.startupDelay);
Config.callsign = getParamStringSafe("callsign", Config.callsign); Config.callsign = getParamStringSafe("callsign", Config.callsign);
Config.wifiAutoAP.password = getParamStringSafe("wifi.autoAP.password", Config.wifiAutoAP.password); Config.wifiAutoAP.password = getParamStringSafe("wifi.autoAP.password", Config.wifiAutoAP.password);
@@ -175,6 +177,7 @@ namespace WEB_Utils {
Config.beacon.interval = getParamIntSafe("beacon.interval", Config.beacon.interval); Config.beacon.interval = getParamIntSafe("beacon.interval", Config.beacon.interval);
Config.beacon.sendViaAPRSIS = request->hasParam("beacon.sendViaAPRSIS", true); Config.beacon.sendViaAPRSIS = request->hasParam("beacon.sendViaAPRSIS", true);
Config.beacon.sendViaRF = request->hasParam("beacon.sendViaRF", true); Config.beacon.sendViaRF = request->hasParam("beacon.sendViaRF", true);
Config.beacon.beaconFreq = getParamIntSafe("beacon.beaconFreq", Config.beacon.beaconFreq);
Config.beacon.latitude = getParamDoubleSafe("beacon.latitude", Config.beacon.latitude); Config.beacon.latitude = getParamDoubleSafe("beacon.latitude", Config.beacon.latitude);
Config.beacon.longitude = getParamDoubleSafe("beacon.longitude", Config.beacon.longitude); Config.beacon.longitude = getParamDoubleSafe("beacon.longitude", Config.beacon.longitude);
Config.beacon.comment = getParamStringSafe("beacon.comment", Config.beacon.comment); Config.beacon.comment = getParamStringSafe("beacon.comment", Config.beacon.comment);
@@ -196,15 +199,19 @@ namespace WEB_Utils {
Config.digi.mode = getParamIntSafe("digi.mode", Config.digi.mode); Config.digi.mode = getParamIntSafe("digi.mode", Config.digi.mode);
Config.digi.ecoMode = getParamIntSafe("digi.ecoMode", Config.digi.ecoMode); Config.digi.ecoMode = getParamIntSafe("digi.ecoMode", Config.digi.ecoMode);
Config.loramodule.txFreq = getParamIntSafe("lora.txFreq", Config.loramodule.txFreq);
Config.loramodule.rxFreq = getParamIntSafe("lora.rxFreq", Config.loramodule.rxFreq);
Config.loramodule.spreadingFactor = getParamIntSafe("lora.spreadingFactor", Config.loramodule.spreadingFactor);
Config.loramodule.signalBandwidth = getParamIntSafe("lora.signalBandwidth", Config.loramodule.signalBandwidth);
Config.loramodule.codingRate4 = getParamIntSafe("lora.codingRate4", Config.loramodule.codingRate4);
Config.loramodule.power = getParamIntSafe("lora.power", Config.loramodule.power);
Config.loramodule.txActive = request->hasParam("lora.txActive", true);
Config.loramodule.rxActive = request->hasParam("lora.rxActive", true); Config.loramodule.rxActive = request->hasParam("lora.rxActive", true);
Config.loramodule.rxFreq = getParamIntSafe("lora.rxFreq", Config.loramodule.rxFreq);
Config.loramodule.rxSpreadingFactor = getParamIntSafe("lora.rxSpreadingFactor", Config.loramodule.rxSpreadingFactor);
Config.loramodule.rxCodingRate4 = getParamIntSafe("lora.rxCodingRate4", Config.loramodule.rxCodingRate4);
Config.loramodule.rxSignalBandwidth = getParamIntSafe("lora.rxSignalBandwidth", Config.loramodule.rxSignalBandwidth);
Config.loramodule.txActive = request->hasParam("lora.txActive", true);
Config.loramodule.txFreq = getParamIntSafe("lora.txFreq", Config.loramodule.txFreq);
Config.loramodule.txSpreadingFactor = getParamIntSafe("lora.txSpreadingFactor", Config.loramodule.txSpreadingFactor);
Config.loramodule.txCodingRate4 = getParamIntSafe("lora.txCodingRate4", Config.loramodule.txCodingRate4);
Config.loramodule.txSignalBandwidth = getParamIntSafe("lora.txSignalBandwidth", Config.loramodule.txSignalBandwidth);
Config.loramodule.power = getParamIntSafe("lora.power", Config.loramodule.power);
Config.display.alwaysOn = request->hasParam("display.alwaysOn", true); Config.display.alwaysOn = request->hasParam("display.alwaysOn", true);
@@ -261,6 +268,7 @@ namespace WEB_Utils {
Config.mqtt.username = getParamStringSafe("mqtt.username", Config.mqtt.username); Config.mqtt.username = getParamStringSafe("mqtt.username", Config.mqtt.username);
Config.mqtt.password = getParamStringSafe("mqtt.password", Config.mqtt.password); Config.mqtt.password = getParamStringSafe("mqtt.password", Config.mqtt.password);
Config.mqtt.port = getParamIntSafe("mqtt.port", Config.mqtt.port); Config.mqtt.port = getParamIntSafe("mqtt.port", Config.mqtt.port);
Config.mqtt.beaconOverMqtt = request->hasParam("mqtt.beaconOverMqtt", true);
} }
@@ -281,6 +289,7 @@ namespace WEB_Utils {
Config.remoteManagement.managers = getParamStringSafe("remoteManagement.managers", Config.remoteManagement.managers); Config.remoteManagement.managers = getParamStringSafe("remoteManagement.managers", Config.remoteManagement.managers);
Config.remoteManagement.rfOnly = request->hasParam("remoteManagement.rfOnly", true); Config.remoteManagement.rfOnly = request->hasParam("remoteManagement.rfOnly", true);
Config.ntp.server = getParamStringSafe("ntp.server", Config.ntp.server);
Config.ntp.gmtCorrection = getParamFloatSafe("ntp.gmtCorrection", Config.ntp.gmtCorrection); Config.ntp.gmtCorrection = getParamFloatSafe("ntp.gmtCorrection", Config.ntp.gmtCorrection);
Config.rememberStationTime = getParamIntSafe("other.rememberStationTime", Config.rememberStationTime); Config.rememberStationTime = getParamIntSafe("other.rememberStationTime", Config.rememberStationTime);