Compare commits

...

13 Commits

Author SHA1 Message Date
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
48 changed files with 593 additions and 489 deletions
+6 -4
View File
@@ -32,7 +32,7 @@ ____________________________________________________
- 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(or 19003) - RAK Wireless 4631 + 19007(or 19003)
@@ -51,9 +51,11 @@ ____________________________________________________
<br /> <br />
# Timeline (Versions): # Timeline (Versions):
- 2025-10-13 Rx and Tx Frequencies are now with fully configurable.
- 2025-10-11 User defined NTP server added. - 2025-10-13 Startup Delay to allow the Router/Modem to start WiFiAP before connecting.
- 2025-10-10 Changed Wiki into a pdf manual. - 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 Changed Wiki into a pdf manual file.
- 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 -9
View File
@@ -35,17 +35,21 @@
"blacklist": "", "blacklist": "",
"digi": { "digi": {
"mode": 0, "mode": 0,
"ecoMode": 0 "ecoMode": 0,
"beaconOnRxFreq": false
}, },
"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": "",
@@ -108,6 +113,7 @@
"rememberStationTime": 30, "rememberStationTime": 30,
"backupDigiMode": false, "backupDigiMode": false,
"rebootMode": false, "rebootMode": false,
"rebootModeTime": 6 "rebootModeTime": 6,
"startupDelay": 0
} }
} }
+403 -327
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>
@@ -550,7 +572,7 @@
</div> </div>
</div> </div>
<div class="row mt-4"> <div class="row mt-4">
<div class="col-12"> <div class="col-6">
<label <label
for="beacon.interval" for="beacon.interval"
class="form-label" class="form-label"
@@ -626,7 +648,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 +689,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 +728,35 @@
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>
</select>
</div>
<div class="col-12 mt-3">
<label
for="digi.beaconOnRxFreq"
class="form-label"
>Digipeater Beacon Frequency
<small
>(If Rx Freq different from Tx Freq).</small
></label
>
<select
class="form-select form-select"
name="digi.beaconOnRxFreq"
id="digi.beaconOnRxFreq"
>
<option value="false">
Beacon on Tx Freq
</option>
<option value="true">
Beacon on Rx Freq
</option> </option>
</select> </select>
</div> </div>
@@ -744,21 +788,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 +804,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 +865,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 +1003,7 @@
>dBm</span >dBm</span
> >
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@@ -1013,7 +1063,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 +1142,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 +1172,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 +1324,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 +1345,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 +1413,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 +1474,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 +1595,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 +1610,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 +1642,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 +1657,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 +1675,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 +1690,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 +1710,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 +1737,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 +1754,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 +1808,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 +1887,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 +1939,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 +2022,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,41 +2064,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.server" <label
class="form-label" for="ntp.server"
>NTP Server hostname</label class="form-label"
> >NTP Server hostname</label
<div class="input-group">
<input
type="text"
name="ntp.server"
id="ntp.server"
class="form-control"
/>
</div>
</div>
<div class="col-12">
<label
for="ntp.gmtCorrection"
class="form-label"
>GMT Time Correction for accurate Local Time</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>
+21 -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;
@@ -134,15 +135,19 @@ function loadSettings(settings) {
// Digi // Digi
document.getElementById("digi.mode").value = settings.digi.mode; document.getElementById("digi.mode").value = settings.digi.mode;
document.getElementById("digi.ecoMode").value = settings.digi.ecoMode; document.getElementById("digi.ecoMode").value = settings.digi.ecoMode;
document.getElementById("digi.beaconOnRxFreq").value = settings.digi.beaconOnRxFreq;
// 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 +212,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;
@@ -248,7 +255,6 @@ function loadSettings(settings) {
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) {
@@ -380,12 +386,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
@@ -452,65 +460,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

+12 -6
View File
@@ -68,17 +68,21 @@ 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)
bool beaconOnRxFreq;
}; };
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;
}; };
@@ -158,6 +162,7 @@ public:
String username; String username;
String password; String password;
int port; int port;
bool beaconOverMqtt;
}; };
class Configuration { class Configuration {
@@ -167,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.
+3 -9
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,7 +67,7 @@ ___________________________________________________________________*/
#endif #endif
String versionDate = "2025-10-11"; String versionDate = "2025-10-13";
String versionNumber = "3.1.3"; String versionNumber = "3.1.3";
Configuration Config; Configuration Config;
WiFiClient aprsIsClient; WiFiClient aprsIsClient;
@@ -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();
+56 -29
View File
@@ -45,6 +45,8 @@ 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;
@@ -85,15 +87,19 @@ bool Configuration::writeFile() {
#if defined(HAS_A7670) #if defined(HAS_A7670)
if (digi.ecoMode == 1) data["digi"]["ecoMode"] = 2; if (digi.ecoMode == 1) data["digi"]["ecoMode"] = 2;
#endif #endif
data["digi"]["beaconOnRxFreq"] = digi.beaconOnRxFreq;
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;
@@ -131,6 +137,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;
@@ -184,6 +191,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";
@@ -241,32 +251,40 @@ bool Configuration::readFile() {
blacklist = data["blacklist"] | "station callsign"; blacklist = data["blacklist"] | "station callsign";
if (!data["digi"].containsKey("mode") || if (!data["digi"].containsKey("mode") ||
!data["digi"].containsKey("ecoMode")) needsRewrite = true; !data["digi"].containsKey("ecoMode") ||
!data["digi"].containsKey("beaconOnRxFreq")) needsRewrite = true;
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;
digi.beaconOnRxFreq = data["digi"]["beaconOnRxFreq"] | 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;
@@ -323,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;
@@ -395,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;
@@ -430,15 +452,19 @@ void Configuration::setDefaultValues() {
digi.mode = 0; digi.mode = 0;
digi.ecoMode = 0; digi.ecoMode = 0;
digi.beaconOnRxFreq = false;
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;
@@ -476,6 +502,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 = "";
+17 -6
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)
@@ -131,19 +132,27 @@ namespace LoRa_Utils {
delay(500); delay(500);
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(500);
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.digi.beaconOnRxFreq)) {
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.digi.beaconOnRxFreq)) {
changeFreqRx();
}
} }
} }
+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);
} }
} }
+11 -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();
@@ -436,4 +436,11 @@ namespace Utils {
return true; return true;
} }
void startupDelay() {
if (Config.startupDelay > 0) {
displayShow("", " STARTUP DELAY ...", "", "", 0);
delay(Config.startupDelay * 60 * 1000);
}
}
} }
+15 -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);
@@ -196,15 +198,20 @@ 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.digi.beaconOnRxFreq = request->hasParam("digi.beaconOnRxFreq", true);
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);
} }