mirror of
https://github.com/richonguzman/LoRa_APRS_iGate.git
synced 2026-03-28 16:52:33 +01:00
Compare commits
1 Commits
mqttVersio
...
coreTest
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d65b2c93f |
@@ -33,11 +33,9 @@ lib_deps =
|
||||
ayushsharma82/ElegantOTA @ 3.1.5
|
||||
bblanchon/ArduinoJson @ 6.21.3
|
||||
jgromes/RadioLib @ 7.1.0
|
||||
knolleary/PubSubClient @ 2.8
|
||||
mathieucarbou/AsyncTCP @ 3.2.5
|
||||
mathieucarbou/ESPAsyncWebServer @ 3.2.3
|
||||
mikalhart/TinyGPSPlus @ 1.0.3
|
||||
richonguzman/APRSPacketLib @1.0.0
|
||||
mikalhart/TinyGPSPlus @ 1.0.3
|
||||
display_libs =
|
||||
adafruit/Adafruit GFX Library @ 1.11.9
|
||||
adafruit/Adafruit SSD1306 @ 2.5.10
|
||||
|
||||
@@ -22,15 +22,13 @@
|
||||
},
|
||||
"aprs_is": {
|
||||
"active": false,
|
||||
"messagesToRF": false,
|
||||
"objectsToRF": false,
|
||||
"passcode": "XYZVW",
|
||||
"server": "rotate.aprs2.net",
|
||||
"passcode": "XYZVW",
|
||||
"port": 14580,
|
||||
"filter": "m/10"
|
||||
"filter": "m/10",
|
||||
"messagesToRF": false,
|
||||
"objectsToRF": false
|
||||
},
|
||||
"personalNote": "",
|
||||
"blacklist": "",
|
||||
"digi": {
|
||||
"mode": 0,
|
||||
"ecoMode": 0
|
||||
@@ -78,14 +76,6 @@
|
||||
"enableSerial": false,
|
||||
"acceptOwn": false
|
||||
},
|
||||
"mqtt": {
|
||||
"active": false,
|
||||
"server": "",
|
||||
"topic": "",
|
||||
"username": "",
|
||||
"password": "",
|
||||
"port": 1883
|
||||
},
|
||||
"ota": {
|
||||
"username": "",
|
||||
"password": ""
|
||||
@@ -94,17 +84,19 @@
|
||||
"username": "admin",
|
||||
"password": ""
|
||||
},
|
||||
"remoteManagement": {
|
||||
"managers": "",
|
||||
"rfOnly": true
|
||||
},
|
||||
"ntp": {
|
||||
"gmtCorrection": 0.0
|
||||
},
|
||||
"remoteManagement": {
|
||||
"managers": "",
|
||||
"rfOnly": true
|
||||
},
|
||||
"other": {
|
||||
"rememberStationTime": 30,
|
||||
"backupDigiMode": false,
|
||||
"rebootMode": false,
|
||||
"rebootModeTime": 6
|
||||
}
|
||||
},
|
||||
"personalNote": "",
|
||||
"blacklist": ""
|
||||
}
|
||||
@@ -283,7 +283,6 @@
|
||||
id="beacon.statusPacket"
|
||||
class="form-control"
|
||||
placeholder="Custom Status"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -439,9 +438,8 @@
|
||||
type="text"
|
||||
name="aprs_is.server"
|
||||
id="aprs_is.server"
|
||||
placeholder="rotate.aprs2.net"
|
||||
placeholder="soam.aprs2.net"
|
||||
class="form-control"
|
||||
value="rotate.aprs2.net"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
@@ -456,7 +454,6 @@
|
||||
id="aprs_is.port"
|
||||
placeholder="14580"
|
||||
class="form-control"
|
||||
value="14580"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -472,7 +469,6 @@
|
||||
name="aprs_is.passcode"
|
||||
id="aprs_is.passcode"
|
||||
class="form-control"
|
||||
value="XYZWV"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
@@ -486,7 +482,6 @@
|
||||
class="form-control"
|
||||
name="aprs_is.filter"
|
||||
id="aprs_is.filter"
|
||||
value="m/10"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1023,8 +1018,6 @@
|
||||
name="display.timeout"
|
||||
id="display.timeout"
|
||||
value="4"
|
||||
step="1"
|
||||
min="2"
|
||||
class="form-control"
|
||||
/>
|
||||
<span class="input-group-text"
|
||||
@@ -1386,6 +1379,7 @@
|
||||
id="syslog.server"
|
||||
placeholder="lora.link9.net"
|
||||
class="form-control"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
@@ -1400,6 +1394,7 @@
|
||||
id="syslog.port"
|
||||
placeholder="1514"
|
||||
class="form-control"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
@@ -1507,142 +1502,6 @@
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="row my-5 d-flex align-items-top">
|
||||
<div class="col-lg-3 col-sm-12">
|
||||
<h5>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
fill="currentColor"
|
||||
class="bi bi-database-fill"
|
||||
viewBox="0 0 16 16"
|
||||
>
|
||||
<path
|
||||
d="M3.904 1.777C4.978 1.289 6.427 1 8 1s3.022.289 4.096.777C13.125 2.245 14 2.993 14 4s-.875 1.755-1.904 2.223C11.022 6.711 9.573 7 8 7s-3.022-.289-4.096-.777C2.875 5.755 2 5.007 2 4s.875-1.755 1.904-2.223"
|
||||
/>
|
||||
<path
|
||||
d="M2 6.161V7c0 1.007.875 1.755 1.904 2.223C4.978 9.71 6.427 10 8 10s3.022-.289 4.096-.777C13.125 8.755 14 8.007 14 7v-.839c-.457.432-1.004.751-1.49.972C11.278 7.693 9.682 8 8 8s-3.278-.307-4.51-.867c-.486-.22-1.033-.54-1.49-.972"
|
||||
/>
|
||||
<path
|
||||
d="M2 9.161V10c0 1.007.875 1.755 1.904 2.223C4.978 12.711 6.427 13 8 13s3.022-.289 4.096-.777C13.125 11.755 14 11.007 14 10v-.839c-.457.432-1.004.751-1.49.972-1.232.56-2.828.867-4.51.867s-3.278-.307-4.51-.867c-.486-.22-1.033-.54-1.49-.972"
|
||||
/>
|
||||
<path
|
||||
d="M2 12.161V13c0 1.007.875 1.755 1.904 2.223C4.978 15.711 6.427 16 8 16s3.022-.289 4.096-.777C13.125 14.755 14 14.007 14 13v-.839c-.457.432-1.004.751-1.49.972-1.232.56-2.828.867-4.51.867s-3.278-.307-4.51-.867c-.486-.22-1.033-.54-1.49-.972"
|
||||
/>
|
||||
</svg>
|
||||
MQTT
|
||||
</h5>
|
||||
<small>Set your MQTT server</small>
|
||||
</div>
|
||||
<div class="col-lg-9 col-sm-12">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="mqtt.active"
|
||||
id="mqtt.active"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<label
|
||||
for="mqtt.active"
|
||||
class="form-label"
|
||||
>Enable</label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label
|
||||
for="mqtt.server"
|
||||
class="form-label"
|
||||
>Server</label
|
||||
>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="text"
|
||||
name="mqtt.server"
|
||||
id="mqtt.server"
|
||||
class="form-control"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label
|
||||
for="mqtt.topic"
|
||||
class="form-label"
|
||||
>Topic</label
|
||||
>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="text"
|
||||
name="mqtt.topic"
|
||||
id="mqtt.topic"
|
||||
class="form-control"
|
||||
placeholder="aprs-igate"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-text">
|
||||
Default is <strong>aprs-igate</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label
|
||||
for="mqtt.username"
|
||||
class="form-label"
|
||||
>Username</label
|
||||
>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="text"
|
||||
name="mqtt.username"
|
||||
id="mqtt.username"
|
||||
class="form-control"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 mt-3">
|
||||
<label
|
||||
for="mqtt.password"
|
||||
class="form-label"
|
||||
>Password</label
|
||||
>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="password"
|
||||
name="mqtt.password"
|
||||
id="mqtt.password"
|
||||
class="form-control"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 mt-3">
|
||||
<label
|
||||
for="mqtt.port"
|
||||
class="form-label"
|
||||
>Port</label
|
||||
>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="number"
|
||||
name="mqtt.port"
|
||||
id="mqtt.port"
|
||||
class="form-control"
|
||||
placeholder="1883"
|
||||
required=""
|
||||
step="1"
|
||||
min="0"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-text">
|
||||
Default is <strong>1883</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="row my-5 d-flex align-items-top">
|
||||
<div class="col-lg-3 col-sm-12">
|
||||
<h5>
|
||||
|
||||
@@ -49,6 +49,29 @@ function fetchSettings() {
|
||||
});
|
||||
}
|
||||
|
||||
const alwaysOnCheckbox = document.querySelector(
|
||||
'input[name="display.alwaysOn"]'
|
||||
);
|
||||
const timeoutInput = document.querySelector('input[name="display.timeout"]');
|
||||
|
||||
alwaysOnCheckbox.addEventListener("change", function () {
|
||||
timeoutInput.disabled = this.checked;
|
||||
});
|
||||
|
||||
// timeoutInput.addEventListener("change", function () {
|
||||
// alwaysOnCheckbox.disabled = this.value !== "";
|
||||
// });
|
||||
|
||||
const logCheckbox = document.querySelector('input[name="syslog.active"]');
|
||||
const serverField = document.querySelector('input[name="syslog.server"]');
|
||||
const portField = document.querySelector('input[name="syslog.port"]');
|
||||
const logBeaconOverTCPIPField = document.querySelector('input[name="syslog.logBeaconOverTCPIP"]');
|
||||
|
||||
logCheckbox.addEventListener("change", function () {
|
||||
serverField.disabled = !this.checked;
|
||||
portField.disabled = !this.checked;
|
||||
logBeaconOverTCPIPField.disabled = !this.checked
|
||||
});
|
||||
|
||||
function loadSettings(settings) {
|
||||
currentSettings = settings;
|
||||
@@ -104,13 +127,6 @@ function loadSettings(settings) {
|
||||
document.getElementById("aprs_is.port").value = settings.aprs_is.port;
|
||||
document.getElementById("aprs_is.filter").value = settings.aprs_is.filter;
|
||||
document.getElementById("aprs_is.passcode").value = settings.aprs_is.passcode;
|
||||
APRSISCheckbox.checked = settings.aprs_is.active;
|
||||
APRSISGateMessages.disabled = !APRSISCheckbox.checked;
|
||||
APRSISGateObjects.disabled = !APRSISCheckbox.checked;
|
||||
APRSISServer.disabled = !APRSISCheckbox.checked;
|
||||
APRSISPort.disabled = !APRSISCheckbox.checked;
|
||||
APRSISPasscode.disabled = !APRSISCheckbox.checked;
|
||||
APRSISFilter.disabled = !APRSISCheckbox.checked;
|
||||
|
||||
// Beacon
|
||||
document.getElementById("beacon.latitude").value = settings.beacon.latitude;
|
||||
@@ -122,8 +138,6 @@ function loadSettings(settings) {
|
||||
|
||||
document.getElementById("beacon.statusActive").checked = settings.beacon.statusActive;
|
||||
document.getElementById("beacon.statusPacket").value = settings.beacon.statusPacket;
|
||||
StatusCheckbox.checked = settings.beacon.statusActive;
|
||||
StatusPacket.disabled = !StatusCheckbox.checked;
|
||||
|
||||
document.getElementById("beacon.gpsActive").checked = settings.beacon.gpsActive;
|
||||
document.getElementById("beacon.gpsAmbiguity").checked = settings.beacon.gpsAmbiguity;
|
||||
@@ -133,7 +147,7 @@ function loadSettings(settings) {
|
||||
|
||||
// Digi
|
||||
document.getElementById("digi.mode").value = settings.digi.mode;
|
||||
document.getElementById("digi.ecoMode").value = settings.digi.ecoMode;
|
||||
document.getElementById("digi.ecoMode").checked = settings.digi.ecoMode;
|
||||
|
||||
// LoRa
|
||||
document.getElementById("lora.txFreq").value = settings.lora.txFreq;
|
||||
@@ -149,50 +163,40 @@ function loadSettings(settings) {
|
||||
document.getElementById("display.alwaysOn").checked = settings.display.alwaysOn;
|
||||
document.getElementById("display.turn180").checked = settings.display.turn180;
|
||||
document.getElementById("display.timeout").value = settings.display.timeout;
|
||||
DisplayAlwaysOnCheckbox.checked = settings.display.alwaysOn;
|
||||
DisplayTimeout.disabled = DisplayAlwaysOnCheckbox.checked;
|
||||
|
||||
if (settings.display.alwaysOn) {
|
||||
timeoutInput.disabled = true;
|
||||
}
|
||||
|
||||
// BATTERY
|
||||
document.getElementById("battery.sendInternalVoltage").checked = settings.battery.sendInternalVoltage;
|
||||
document.getElementById("battery.monitorInternalVoltage").checked = settings.battery.monitorInternalVoltage;
|
||||
document.getElementById("battery.internalSleepVoltage").value = settings.battery.internalSleepVoltage.toFixed(1);
|
||||
MonitorInternalVoltageCheckbox.checked = settings.battery.monitorInternalVoltage;
|
||||
MonitorInternalSleepVoltage.disabled = !MonitorInternalVoltageCheckbox.checked;
|
||||
|
||||
document.getElementById("battery.sendExternalVoltage").checked = settings.battery.sendExternalVoltage;
|
||||
document.getElementById("battery.externalVoltagePin").value = settings.battery.externalVoltagePin;
|
||||
document.getElementById("battery.voltageDividerR1").value = settings.battery.voltageDividerR1.toFixed(1);
|
||||
document.getElementById("battery.voltageDividerR2").value = settings.battery.voltageDividerR2.toFixed(1);
|
||||
SendExternalVoltageCheckbox.checked = settings.battery.sendExternalVoltage;
|
||||
ExternalVoltagePin.disabled = !SendExternalVoltageCheckbox.checked;
|
||||
ExternalVoltageDividerR1.disabled = !SendExternalVoltageCheckbox.checked;
|
||||
ExternalVoltageDividerR2.disabled = !SendExternalVoltageCheckbox.checked;
|
||||
|
||||
document.getElementById("battery.monitorExternalVoltage").checked = settings.battery.monitorExternalVoltage;
|
||||
document.getElementById("battery.externalSleepVoltage").value = settings.battery.externalSleepVoltage.toFixed(1);
|
||||
MonitorExternalVoltageCheckbox.checked = settings.battery.monitorExternalVoltage;
|
||||
MonitorExternalSleepVoltage.disabled = !MonitorExternalVoltageCheckbox.checked;
|
||||
|
||||
document.getElementById("battery.sendVoltageAsTelemetry").checked = settings.battery.sendVoltageAsTelemetry;
|
||||
|
||||
|
||||
// TELEMETRY WX SENSOR
|
||||
document.getElementById("wxsensor.active").checked = settings.wxsensor.active;
|
||||
document.getElementById("wxsensor.heightCorrection").value = settings.wxsensor.heightCorrection;
|
||||
document.getElementById("wxsensor.temperatureCorrection").value = settings.wxsensor.temperatureCorrection.toFixed(1);
|
||||
TelemetryCheckbox.checked = settings.wxsensor.active;
|
||||
TelemetryHeightCorrection.disabled = !TelemetryCheckbox.checked;
|
||||
TelemetryTempCorrection.disabled = !TelemetryCheckbox.checked;
|
||||
|
||||
// SYSLOG
|
||||
document.getElementById("syslog.active").checked = settings.syslog.active;
|
||||
document.getElementById("syslog.server").value = settings.syslog.server;
|
||||
document.getElementById("syslog.port").value = settings.syslog.port;
|
||||
document.getElementById("syslog.logBeaconOverTCPIP").checked = settings.syslog.logBeaconOverTCPIP;
|
||||
SyslogCheckbox.checked = settings.syslog.active;
|
||||
SyslogServer.disabled = !SyslogCheckbox.checked;
|
||||
SyslogPort.disabled = !SyslogCheckbox.checked;
|
||||
SyslogBeaconOverTCPIP.disabled = !SyslogCheckbox.checked;
|
||||
|
||||
|
||||
if (settings.syslog.active) {
|
||||
serverField.disabled = false;
|
||||
portField.disabled = false;
|
||||
logBeaconOverTCPIPField.disabled = false;
|
||||
}
|
||||
|
||||
// TNC
|
||||
if (settings.tnc) {
|
||||
document.getElementById("tnc.enableServer").checked = settings.tnc.enableServer;
|
||||
@@ -200,25 +204,9 @@ function loadSettings(settings) {
|
||||
document.getElementById("tnc.acceptOwn").checked = settings.tnc.acceptOwn;
|
||||
}
|
||||
|
||||
// MQTT
|
||||
document.getElementById("mqtt.active").checked = settings.mqtt.active;
|
||||
document.getElementById("mqtt.server").value = settings.mqtt.server;
|
||||
document.getElementById("mqtt.topic").value = settings.mqtt.topic;
|
||||
document.getElementById("mqtt.username").value = settings.mqtt.username;
|
||||
document.getElementById("mqtt.password").value = settings.mqtt.password;
|
||||
document.getElementById("mqtt.port").value = settings.mqtt.port;
|
||||
MqttCheckbox.checked = settings.mqtt.active;
|
||||
MqttServer.disabled = !MqttCheckbox.check;
|
||||
MqttTopic.disabled = !MqttCheckbox.check;
|
||||
MqttUsername.disabled = !MqttCheckbox.check;
|
||||
MqttPassword.disabled = !MqttCheckbox.check;
|
||||
MqttPort.disabled = !MqttCheckbox.check;
|
||||
|
||||
// Reboot
|
||||
document.getElementById("other.rebootMode").checked = settings.other.rebootMode;
|
||||
document.getElementById("other.rebootModeTime").value = settings.other.rebootModeTime;
|
||||
RebootModeCheckbox.checked = settings.other.rebootMode;
|
||||
RebootModeTime.disabled = !RebootModeCheckbox.check;
|
||||
|
||||
// WiFi Auto AP
|
||||
document.getElementById("wifi.autoAP.password").value = settings.wifi.autoAP.password;
|
||||
@@ -232,13 +220,6 @@ function loadSettings(settings) {
|
||||
document.getElementById("webadmin.active").checked = settings.webadmin.active;
|
||||
document.getElementById("webadmin.username").value = settings.webadmin.username;
|
||||
document.getElementById("webadmin.password").value = settings.webadmin.password;
|
||||
WebadminCheckbox.checked = settings.webadmin.active;
|
||||
WebadminUsername.disabled = !WebadminCheckbox.check;
|
||||
WebadminPassword.disabled = !WebadminCheckbox.check;
|
||||
|
||||
// Management over APRS
|
||||
document.getElementById("remoteManagement.managers").value = settings.remoteManagement.managers;
|
||||
document.getElementById("remoteManagement.rfOnly").checked = settings.remoteManagement.rfOnly;
|
||||
|
||||
// NTP
|
||||
document.getElementById("ntp.gmtCorrection").value = settings.ntp.gmtCorrection;
|
||||
@@ -246,8 +227,13 @@ function loadSettings(settings) {
|
||||
// Experimental
|
||||
document.getElementById("other.backupDigiMode").checked = settings.other.backupDigiMode;
|
||||
|
||||
// Management over APRS
|
||||
document.getElementById("remoteManagement.managers").value = settings.remoteManagement.managers;
|
||||
document.getElementById("remoteManagement.rfOnly").checked = settings.remoteManagement.rfOnly;
|
||||
|
||||
updateImage();
|
||||
refreshSpeedStandard();
|
||||
toggleFields();
|
||||
}
|
||||
|
||||
function showToast(message) {
|
||||
@@ -274,6 +260,8 @@ document.getElementById('reboot').addEventListener('click', function (e) {
|
||||
showToast("Your device will be rebooted in a while");
|
||||
});
|
||||
|
||||
const wxsensorCheckbox = document.querySelector("input[name='wxsensor.active']");
|
||||
|
||||
function updateImage() {
|
||||
const value = document.getElementById("beacon.overlay").value + document.getElementById("beacon.symbol").value;
|
||||
|
||||
@@ -299,111 +287,70 @@ function updateImage() {
|
||||
}
|
||||
}
|
||||
|
||||
function toggleFields() {
|
||||
const sendExternalVoltageCheckbox = document.querySelector(
|
||||
'input[name="battery.sendExternalVoltage"]'
|
||||
);
|
||||
const externalVoltagePinInput = document.querySelector(
|
||||
'input[name="battery.externalVoltagePin"]'
|
||||
);
|
||||
|
||||
// Status Switch
|
||||
const StatusCheckbox = document.querySelector('input[name="beacon.statusActive"]');
|
||||
const StatusPacket = document.querySelector('input[name="beacon.statusPacket"]');
|
||||
StatusCheckbox.addEventListener("change", function() {
|
||||
StatusPacket.disabled = !this.checked;
|
||||
externalVoltagePinInput.disabled = !sendExternalVoltageCheckbox.checked;
|
||||
voltageDividerR1.disabled = !sendExternalVoltageCheckbox.checked;
|
||||
voltageDividerR2.disabled = !sendExternalVoltageCheckbox.checked;
|
||||
|
||||
const WebadminCheckbox = document.querySelector(
|
||||
'input[name="webadmin.active"]'
|
||||
);
|
||||
|
||||
const WebadminUsername = document.querySelector(
|
||||
'input[name="webadmin.username"]'
|
||||
);
|
||||
|
||||
const WebadminPassword = document.querySelector(
|
||||
'input[name="webadmin.password"]'
|
||||
);
|
||||
WebadminUsername.disabled = !WebadminCheckbox.checked;
|
||||
WebadminPassword.disabled = !WebadminCheckbox.checked;
|
||||
}
|
||||
|
||||
const sendExternalVoltageCheckbox = document.querySelector(
|
||||
'input[name="battery.sendExternalVoltage"]'
|
||||
);
|
||||
const externalVoltagePinInput = document.querySelector(
|
||||
'input[name="battery.externalVoltagePin"]'
|
||||
);
|
||||
|
||||
const voltageDividerR1 = document.querySelector(
|
||||
'input[name="battery.voltageDividerR1"]'
|
||||
);
|
||||
|
||||
const voltageDividerR2 = document.querySelector(
|
||||
'input[name="battery.voltageDividerR2"]'
|
||||
);
|
||||
|
||||
sendExternalVoltageCheckbox.addEventListener("change", function () {
|
||||
externalVoltagePinInput.disabled = !this.checked;
|
||||
voltageDividerR1.disabled = !this.checked;
|
||||
voltageDividerR2.disabled = !this.checked;
|
||||
});
|
||||
|
||||
// APRS-IS Switches
|
||||
const APRSISCheckbox = document.querySelector('input[name="aprs_is.active"]');
|
||||
const APRSISGateMessages = document.querySelector('input[name="aprs_is.messagesToRF"]');
|
||||
const APRSISGateObjects = document.querySelector('input[name="aprs_is.objectsToRF"]');
|
||||
const APRSISServer = document.querySelector('input[name="aprs_is.server"]');
|
||||
const APRSISPort = document.querySelector('input[name="aprs_is.port"]');
|
||||
const APRSISPasscode = document.querySelector('input[name="aprs_is.passcode"]');
|
||||
const APRSISFilter = document.querySelector('input[name="aprs_is.filter"]');
|
||||
APRSISCheckbox.addEventListener("change", function() {
|
||||
APRSISGateMessages.disabled = !this.checked;
|
||||
APRSISGateObjects.disabled = !this.checked;
|
||||
APRSISServer.disabled = !this.checked;
|
||||
APRSISPort.disabled = !this.checked;
|
||||
APRSISPasscode.disabled = !this.checked;
|
||||
APRSISFilter.disabled = !this.checked;
|
||||
});
|
||||
const WebadminCheckbox = document.querySelector(
|
||||
'input[name="webadmin.active"]'
|
||||
);
|
||||
|
||||
// Display Switches
|
||||
const DisplayAlwaysOnCheckbox = document.querySelector('input[name="display.alwaysOn"]');
|
||||
const DisplayTimeout = document.querySelector('input[name="display.timeout"]');
|
||||
DisplayAlwaysOnCheckbox.addEventListener("change", function () {
|
||||
DisplayTimeout.disabled = this.checked;
|
||||
});
|
||||
const WebadminUsername = document.querySelector(
|
||||
'input[name="webadmin.username"]'
|
||||
);
|
||||
|
||||
// Battery Switches
|
||||
const MonitorInternalVoltageCheckbox = document.querySelector('input[name="battery.monitorInternalVoltage"]');
|
||||
const MonitorInternalSleepVoltage = document.querySelector('input[name="battery.internalSleepVoltage"]');
|
||||
MonitorInternalVoltageCheckbox.addEventListener("change", function () {
|
||||
MonitorInternalSleepVoltage.disabled = !this.checked;
|
||||
});
|
||||
const MonitorExternalVoltageCheckbox = document.querySelector('input[name="battery.monitorExternalVoltage"]');
|
||||
const MonitorExternalSleepVoltage = document.querySelector('input[name="battery.externalSleepVoltage"]');
|
||||
MonitorExternalVoltageCheckbox.addEventListener("change", function () {
|
||||
MonitorExternalSleepVoltage.disabled = !this.checked;
|
||||
});
|
||||
const SendExternalVoltageCheckbox = document.querySelector('input[name="battery.sendExternalVoltage"]');
|
||||
const ExternalVoltagePin = document.querySelector('input[name="battery.externalVoltagePin"]');
|
||||
const ExternalVoltageDividerR1 = document.querySelector('input[name="battery.voltageDividerR1"]');
|
||||
const ExternalVoltageDividerR2 = document.querySelector('input[name="battery.voltageDividerR2"]');
|
||||
SendExternalVoltageCheckbox.addEventListener("change", function () {
|
||||
ExternalVoltagePin.disabled = !this.checked;
|
||||
ExternalVoltageDividerR1.disabled = !this.checked;
|
||||
ExternalVoltageDividerR2.disabled = !this.checked;
|
||||
});
|
||||
|
||||
// Telemetry Switches
|
||||
const TelemetryCheckbox = document.querySelector('input[name="wxsensor.active"]');
|
||||
const TelemetryHeightCorrection = document.querySelector('input[name="wxsensor.heightCorrection"]');
|
||||
const TelemetryTempCorrection = document.querySelector('input[name="wxsensor.temperatureCorrection"]');
|
||||
TelemetryCheckbox.addEventListener("change", function () {
|
||||
TelemetryHeightCorrection.disabled = !this.checked;
|
||||
TelemetryTempCorrection.disabled = !this.checked;
|
||||
});
|
||||
|
||||
// Syslog Switches
|
||||
const SyslogCheckbox = document.querySelector('input[name="syslog.active"]');
|
||||
const SyslogServer = document.querySelector('input[name="syslog.server"]');
|
||||
const SyslogPort = document.querySelector('input[name="syslog.port"]');
|
||||
const SyslogBeaconOverTCPIP = document.querySelector('input[name="syslog.logBeaconOverTCPIP"]');
|
||||
SyslogCheckbox.addEventListener("change", function () {
|
||||
SyslogServer.disabled = !this.checked;
|
||||
SyslogPort.disabled = !this.checked;
|
||||
SyslogBeaconOverTCPIP.disabled = !this.checked
|
||||
});
|
||||
|
||||
// MQTT Switches
|
||||
const MqttCheckbox = document.querySelector('input[name="mqtt.active"]');
|
||||
const MqttServer = document.querySelector('input[name="mqtt.server"]');
|
||||
const MqttTopic = document.querySelector('input[name="mqtt.topic"]');
|
||||
const MqttUsername = document.querySelector('input[name="mqtt.username"]');
|
||||
const MqttPassword = document.querySelector('input[name="mqtt.password"]');
|
||||
const MqttPort = document.querySelector('input[name="mqtt.port"]');
|
||||
MqttCheckbox.addEventListener("change", function () {
|
||||
MqttServer.disabled = !this.checked;
|
||||
MqttTopic.disabled = !this.checked;
|
||||
MqttUsername.disabled = !this.checked;
|
||||
MqttPassword.disabled = !this.checked;
|
||||
MqttPort.disabled = !this.checked;
|
||||
});
|
||||
|
||||
// Reboot Switches
|
||||
const RebootModeCheckbox = document.querySelector('input[name="other.rebootMode"]');
|
||||
const RebootModeTime = document.querySelector('input[name="other.rebootModeTime"]');
|
||||
RebootModeCheckbox.addEventListener("change", function() {
|
||||
RebootModeTime.disabled = !this.checked;
|
||||
});
|
||||
|
||||
// Web Admin Switches
|
||||
const WebadminCheckbox = document.querySelector('input[name="webadmin.active"]');
|
||||
const WebadminUsername = document.querySelector('input[name="webadmin.username"]');
|
||||
const WebadminPassword = document.querySelector('input[name="webadmin.password"]');
|
||||
const WebadminPassword = document.querySelector(
|
||||
'input[name="webadmin.password"]'
|
||||
);
|
||||
WebadminCheckbox.addEventListener("change", function () {
|
||||
WebadminUsername.disabled = !this.checked;
|
||||
WebadminPassword.disabled = !this.checked;
|
||||
WebadminUsername.disabled = !this.checked;
|
||||
WebadminPassword.disabled = !this.checked;
|
||||
});
|
||||
|
||||
|
||||
document.querySelector(".new button").addEventListener("click", function () {
|
||||
const networksContainer = document.querySelector(".list-networks");
|
||||
|
||||
|
||||
@@ -35,11 +35,16 @@ namespace APRS_IS_Utils {
|
||||
void processLoRaPacket(const String& packet);
|
||||
|
||||
String buildPacketToTx(const String& aprsisPacket, uint8_t packetType);
|
||||
void processAPRSISPacket(const String& packet);
|
||||
void processAPRSISPacket();//const String& packet);
|
||||
void listenAPRSIS();
|
||||
|
||||
void firstConnection();
|
||||
|
||||
bool startListenerAPRSISTask(uint32_t stackSize = 8192, UBaseType_t priority = 1);
|
||||
void stopListenerAPRSISTask();
|
||||
void suspendListenerAPRSISTask();
|
||||
void resumeListenerAPRSISTask();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -32,6 +32,9 @@ namespace BATTERY_Utils {
|
||||
float checkExternalVoltage();
|
||||
void startupBatteryHealth();
|
||||
|
||||
String generateEncodedTelemetryBytes(float value, bool firstBytes, byte voltageType);
|
||||
String generateEncodedTelemetry();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -149,16 +149,6 @@ public:
|
||||
bool rfOnly;
|
||||
};
|
||||
|
||||
class MQTT {
|
||||
public:
|
||||
bool active;
|
||||
String server;
|
||||
String topic;
|
||||
String username;
|
||||
String password;
|
||||
int port;
|
||||
};
|
||||
|
||||
class Configuration {
|
||||
public:
|
||||
String callsign;
|
||||
@@ -183,7 +173,6 @@ public:
|
||||
WEBADMIN webadmin;
|
||||
NTP ntp;
|
||||
REMOTE_MANAGEMENT remoteManagement;
|
||||
MQTT mqtt;
|
||||
|
||||
void init();
|
||||
void writeFile();
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||
*
|
||||
* This file is part of LoRa APRS iGate.
|
||||
*
|
||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MQTT_UTILS_H_
|
||||
#define MQTT_UTILS_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
namespace MQTT_Utils {
|
||||
|
||||
void sendToMqtt(const String& packet);
|
||||
void connect();
|
||||
void loop();
|
||||
void setup();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -41,6 +41,7 @@ namespace POWER_Utils {
|
||||
|
||||
double getBatteryVoltage();
|
||||
bool isBatteryConnected();
|
||||
void activateMeasurement();
|
||||
void activateGPS();
|
||||
void deactivateGPS();
|
||||
void activateLoRa();
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||
*
|
||||
* This file is part of LoRa APRS iGate.
|
||||
*
|
||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TELEMETRY_UTILS_H_
|
||||
#define TELEMETRY_UTILS_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
namespace TELEMETRY_Utils {
|
||||
|
||||
void sendEquationsUnitsParameters();
|
||||
String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType);
|
||||
String generateEncodedTelemetry();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -51,7 +51,6 @@ ___________________________________________________________________*/
|
||||
#include "syslog_utils.h"
|
||||
#include "power_utils.h"
|
||||
#include "sleep_utils.h"
|
||||
#include "mqtt_utils.h"
|
||||
#include "lora_utils.h"
|
||||
#include "wifi_utils.h"
|
||||
#include "digi_utils.h"
|
||||
@@ -67,11 +66,9 @@ ___________________________________________________________________*/
|
||||
#endif
|
||||
|
||||
|
||||
String versionDate = "2025-08-29";
|
||||
String versionNumber = "3.1";
|
||||
String versionDate = "2025-08-20";
|
||||
Configuration Config;
|
||||
WiFiClient aprsIsClient;
|
||||
WiFiClient mqttClient;
|
||||
WiFiClient espClient;
|
||||
#ifdef HAS_GPS
|
||||
HardwareSerial gpsSerial(1);
|
||||
TinyGPSPlus gps;
|
||||
@@ -99,6 +96,11 @@ std::vector<ReceivedPacket> receivedPackets;
|
||||
String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine;
|
||||
//#define STARTUP_DELAY 5 //min
|
||||
|
||||
#ifdef HAS_TWO_CORES
|
||||
QueueHandle_t aprsIsTxQueue = NULL;
|
||||
QueueHandle_t aprsIsRxQueue = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
@@ -121,16 +123,43 @@ void setup() {
|
||||
WX_Utils::setup();
|
||||
WEB_Utils::setup();
|
||||
TNC_Utils::setup();
|
||||
MQTT_Utils::setup();
|
||||
#ifdef HAS_A7670
|
||||
A7670_Utils::setup();
|
||||
#endif
|
||||
Utils::checkRebootMode();
|
||||
|
||||
APRS_IS_Utils::firstConnection();
|
||||
SLEEP_Utils::checkSerial();
|
||||
|
||||
// Crear queues con verificación detallada
|
||||
//Serial.println("Creando aprsIsTxQueue...");
|
||||
aprsIsTxQueue = xQueueCreate(50, sizeof(String));
|
||||
//Serial.printf("aprsIsTxQueue = %p\n", aprsIsTxQueue);
|
||||
|
||||
//Serial.println("Creando aprsIsRxQueue...");
|
||||
aprsIsRxQueue = xQueueCreate(50, sizeof(String));
|
||||
//Serial.printf("aprsIsRxQueue = %p\n", aprsIsRxQueue);
|
||||
|
||||
// Verificación crítica
|
||||
if (aprsIsRxQueue == NULL || aprsIsTxQueue == NULL) {
|
||||
Serial.println("FATAL: Error creando queues!");
|
||||
while(1) {
|
||||
Serial.println("STUCK - Queues failed");
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
Serial.println("Queues creadas OK");
|
||||
|
||||
// Iniciar el task de APRSIS
|
||||
if (!APRS_IS_Utils::startListenerAPRSISTask()) {
|
||||
Serial.println("Error: No se pudo crear el task de APRSIS");
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//Serial.println("Loop tick: " + String(millis()));
|
||||
//delay(1000);
|
||||
|
||||
if (Config.digi.ecoMode == 1) {
|
||||
SLEEP_Utils::checkWakeUpFlag();
|
||||
Utils::checkBeaconInterval();
|
||||
@@ -170,13 +199,11 @@ void loop() {
|
||||
if (Config.aprs_is.active && !modemLoggedToAPRSIS) A7670_Utils::APRS_IS_connect();
|
||||
#else
|
||||
WIFI_Utils::checkWiFi();
|
||||
if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !aprsIsClient.connected()) APRS_IS_Utils::connect();
|
||||
if (Config.mqtt.active && (WiFi.status() == WL_CONNECTED) && !mqttClient.connected()) MQTT_Utils::connect();
|
||||
if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !espClient.connected()) APRS_IS_Utils::connect();
|
||||
#endif
|
||||
|
||||
NTP_Utils::update();
|
||||
TNC_Utils::loop();
|
||||
MQTT_Utils::loop();
|
||||
|
||||
Utils::checkDisplayInterval();
|
||||
Utils::checkBeaconInterval();
|
||||
@@ -189,7 +216,7 @@ void loop() {
|
||||
}
|
||||
|
||||
if (packet != "") {
|
||||
if (Config.aprs_is.active) { // If APRSIS enabled
|
||||
if (Config.aprs_is.active) { // If APRSIS enabled
|
||||
APRS_IS_Utils::processLoRaPacket(packet); // Send received packet to APRSIS
|
||||
}
|
||||
|
||||
@@ -198,12 +225,18 @@ void loop() {
|
||||
DIGI_Utils::processLoRaPacket(packet); // Send received packet to Digi
|
||||
}
|
||||
|
||||
if (Config.tnc.enableServer) TNC_Utils::sendToClients(packet); // Send received packet to TNC KISS
|
||||
if (Config.tnc.enableSerial) TNC_Utils::sendToSerial(packet); // Send received packet to Serial KISS
|
||||
if (Config.mqtt.active) MQTT_Utils::sendToMqtt(packet); // Send received packet to MQTT
|
||||
if (Config.tnc.enableServer) { // If TNC server enabled
|
||||
TNC_Utils::sendToClients(packet); // Send received packet to TNC KISS
|
||||
}
|
||||
if (Config.tnc.enableSerial) { // If Serial KISS enabled
|
||||
TNC_Utils::sendToSerial(packet); // Send received packet to Serial KISS
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.aprs_is.active) APRS_IS_Utils::listenAPRSIS(); // listen received packet from APRSIS
|
||||
if (Config.aprs_is.active) {
|
||||
APRS_IS_Utils::processAPRSISPacket();
|
||||
//APRS_IS_Utils::listenAPRSIS(); // listen received packet from APRSIS
|
||||
}
|
||||
|
||||
STATION_Utils::processOutputPacketBuffer();
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
|
||||
|
||||
extern Configuration Config;
|
||||
extern WiFiClient aprsIsClient;
|
||||
extern WiFiClient espClient;
|
||||
extern QueueHandle_t aprsIsRxQueue;
|
||||
extern uint32_t lastScreenOn;
|
||||
extern String firstLine;
|
||||
extern String secondLine;
|
||||
@@ -41,7 +42,6 @@ extern String sixthLine;
|
||||
extern String seventhLine;
|
||||
extern bool modemLoggedToAPRSIS;
|
||||
extern bool backUpDigiMode;
|
||||
extern String versionNumber;
|
||||
|
||||
uint32_t lastRxTime = millis();
|
||||
bool passcodeValid = false;
|
||||
@@ -53,18 +53,21 @@ bool passcodeValid = false;
|
||||
|
||||
namespace APRS_IS_Utils {
|
||||
|
||||
// Handle del task (opcional, para poder controlarlo después)
|
||||
TaskHandle_t aprsisTaskHandle = NULL;
|
||||
|
||||
void upload(const String& line) {
|
||||
aprsIsClient.print(line + "\r\n");
|
||||
espClient.print(line + "\r\n");
|
||||
}
|
||||
|
||||
void connect() {
|
||||
Serial.print("Connecting to APRS-IS ... ");
|
||||
uint8_t count = 0;
|
||||
while (!aprsIsClient.connect(Config.aprs_is.server.c_str(), Config.aprs_is.port) && count < 20) {
|
||||
while (!espClient.connect(Config.aprs_is.server.c_str(), Config.aprs_is.port) && count < 20) {
|
||||
Serial.println("Didn't connect with server...");
|
||||
delay(1000);
|
||||
aprsIsClient.stop();
|
||||
aprsIsClient.flush();
|
||||
espClient.stop();
|
||||
espClient.flush();
|
||||
Serial.println("Run client.stop");
|
||||
Serial.println("Trying to connect with Server: " + String(Config.aprs_is.server) + " AprsServerPort: " + String(Config.aprs_is.port));
|
||||
count++;
|
||||
@@ -79,9 +82,7 @@ namespace APRS_IS_Utils {
|
||||
aprsAuth += Config.callsign;
|
||||
aprsAuth += " pass ";
|
||||
aprsAuth += Config.aprs_is.passcode;
|
||||
aprsAuth += " vers CA2RXUiGate ";
|
||||
aprsAuth += versionNumber;
|
||||
aprsAuth += " filter ";
|
||||
aprsAuth += " vers CA2RXU_iGate 3.0 filter ";
|
||||
aprsAuth += Config.aprs_is.filter;
|
||||
upload(aprsAuth);
|
||||
}
|
||||
@@ -113,7 +114,7 @@ namespace APRS_IS_Utils {
|
||||
aprsisState = "--";
|
||||
}
|
||||
#else
|
||||
if (aprsIsClient.connected()) {
|
||||
if (espClient.connected()) {
|
||||
aprsisState = "OK";
|
||||
} else {
|
||||
aprsisState = "--";
|
||||
@@ -195,7 +196,7 @@ namespace APRS_IS_Utils {
|
||||
}
|
||||
|
||||
void processLoRaPacket(const String& packet) {
|
||||
if (passcodeValid && (aprsIsClient.connected() || modemLoggedToAPRSIS)) {
|
||||
if (passcodeValid && (espClient.connected() || modemLoggedToAPRSIS)) {
|
||||
if (packet.indexOf("NOGATE") == -1 && packet.indexOf("RFONLY") == -1) {
|
||||
int firstColonIndex = packet.indexOf(":");
|
||||
if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] != '}' && packet.indexOf("TCPIP") == -1) {
|
||||
@@ -277,95 +278,103 @@ namespace APRS_IS_Utils {
|
||||
return outputPacket;
|
||||
}
|
||||
|
||||
void processAPRSISPacket(const String& packet) {
|
||||
if (!passcodeValid && packet.indexOf(Config.callsign) != -1) {
|
||||
if (packet.indexOf("unverified") != -1 ) {
|
||||
Serial.println("\n****APRS PASSCODE NOT VALID****\n");
|
||||
displayShow(firstLine, "", " APRS PASSCODE", " NOT VALID !!!", "", "", "", 0);
|
||||
while (1) {};
|
||||
} else if (packet.indexOf("verified") != -1 ) {
|
||||
passcodeValid = true;
|
||||
}
|
||||
}
|
||||
if (passcodeValid && !packet.startsWith("#")) {
|
||||
if (Config.aprs_is.messagesToRF && packet.indexOf("::") > 0) {
|
||||
String Sender = packet.substring(0, packet.indexOf(">"));
|
||||
const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
|
||||
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
||||
Addressee.trim();
|
||||
if (Addressee == Config.callsign) { // its for me!
|
||||
String receivedMessage;
|
||||
if (AddresseeAndMessage.indexOf("{") > 0) { // ack?
|
||||
String ackMessage = "ack";
|
||||
ackMessage += AddresseeAndMessage.substring(AddresseeAndMessage.indexOf("{") + 1);
|
||||
ackMessage.trim();
|
||||
delay(4000);
|
||||
for (int i = Sender.length(); i < 9; i++) {
|
||||
Sender += ' ';
|
||||
}
|
||||
//uint32_t lastLog = 0;
|
||||
void processAPRSISPacket() {
|
||||
/*Serial.println("processAPRSISPacket");
|
||||
|
||||
String ackPacket = Config.callsign;
|
||||
ackPacket += ">APLRG1,TCPIP,qAC::";
|
||||
ackPacket += Sender;
|
||||
ackPacket += ":";
|
||||
ackPacket += ackMessage;
|
||||
#ifdef HAS_A7670
|
||||
A7670_Utils::uploadToAPRSIS(ackPacket);
|
||||
#else
|
||||
upload(ackPacket);
|
||||
#endif
|
||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1, AddresseeAndMessage.indexOf("{"));
|
||||
if (millis() - lastLog > 5000) { // Cada 5 segundos
|
||||
UBaseType_t packets = uxQueueMessagesWaiting(aprsIsRxQueue);
|
||||
UBaseType_t spaces = uxQueueSpacesAvailable(aprsIsRxQueue);
|
||||
Serial.printf("[STATS] APRSIS Queue: %d/%d (%.1f%% full)\n",
|
||||
packets, packets + spaces,
|
||||
(packets * 100.0) / (packets + spaces));
|
||||
lastLog = millis();
|
||||
}*/
|
||||
|
||||
|
||||
String packet;
|
||||
if (xQueueReceive(aprsIsRxQueue, &packet, 0) == pdTRUE) {
|
||||
|
||||
if (passcodeValid && !packet.startsWith("#")) {
|
||||
if (Config.aprs_is.messagesToRF && packet.indexOf("::") > 0) {
|
||||
String Sender = packet.substring(0, packet.indexOf(">"));
|
||||
const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
|
||||
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
||||
Addressee.trim();
|
||||
if (Addressee == Config.callsign) { // its for me!
|
||||
String receivedMessage;
|
||||
if (AddresseeAndMessage.indexOf("{") > 0) { // ack?
|
||||
String ackMessage = "ack";
|
||||
ackMessage += AddresseeAndMessage.substring(AddresseeAndMessage.indexOf("{") + 1);
|
||||
ackMessage.trim();
|
||||
delay(4000);
|
||||
for (int i = Sender.length(); i < 9; i++) {
|
||||
Sender += ' ';
|
||||
}
|
||||
|
||||
String ackPacket = Config.callsign;
|
||||
ackPacket += ">APLRG1,TCPIP,qAC::";
|
||||
ackPacket += Sender;
|
||||
ackPacket += ":";
|
||||
ackPacket += ackMessage;
|
||||
#ifdef HAS_A7670
|
||||
A7670_Utils::uploadToAPRSIS(ackPacket);
|
||||
#else
|
||||
upload(ackPacket);
|
||||
#endif
|
||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1, AddresseeAndMessage.indexOf("{"));
|
||||
} else {
|
||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1);
|
||||
}
|
||||
if (receivedMessage.indexOf("?") == 0) {
|
||||
Utils::println("Rx Query (APRS-IS) : " + packet);
|
||||
Sender.trim();
|
||||
String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, true, false);
|
||||
//Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
|
||||
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
|
||||
displayToggle(true);
|
||||
}
|
||||
lastScreenOn = millis();
|
||||
delay(500);
|
||||
#ifdef HAS_A7670
|
||||
A7670_Utils::uploadToAPRSIS(queryAnswer);
|
||||
#else
|
||||
upload(queryAnswer);
|
||||
#endif
|
||||
SYSLOG_Utils::log(2, queryAnswer, 0, 0.0, 0); // APRSIS TX
|
||||
fifthLine = "APRS-IS ----> APRS-IS";
|
||||
sixthLine = Config.callsign;
|
||||
for (int j = sixthLine.length();j < 9;j++) {
|
||||
sixthLine += " ";
|
||||
}
|
||||
sixthLine += "> ";
|
||||
sixthLine += Sender;
|
||||
seventhLine = "QUERY = ";
|
||||
seventhLine += receivedMessage;
|
||||
}
|
||||
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||
} else {
|
||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1);
|
||||
}
|
||||
if (receivedMessage.indexOf("?") == 0) {
|
||||
Utils::println("Rx Query (APRS-IS) : " + packet);
|
||||
Sender.trim();
|
||||
String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, true, false);
|
||||
//Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
|
||||
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
|
||||
Utils::print("Rx Message (APRS-IS): " + packet);
|
||||
if (STATION_Utils::wasHeard(Addressee) && packet.indexOf("EQNS.") == -1 && packet.indexOf("UNIT.") == -1 && packet.indexOf("PARM.") == -1) {
|
||||
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 1));
|
||||
displayToggle(true);
|
||||
lastScreenOn = millis();
|
||||
Utils::typeOfPacket(packet, 1); // APRS-LoRa
|
||||
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||
}
|
||||
lastScreenOn = millis();
|
||||
delay(500);
|
||||
#ifdef HAS_A7670
|
||||
A7670_Utils::uploadToAPRSIS(queryAnswer);
|
||||
#else
|
||||
upload(queryAnswer);
|
||||
#endif
|
||||
SYSLOG_Utils::log(2, queryAnswer, 0, 0.0, 0); // APRSIS TX
|
||||
fifthLine = "APRS-IS ----> APRS-IS";
|
||||
sixthLine = Config.callsign;
|
||||
for (int j = sixthLine.length();j < 9;j++) {
|
||||
sixthLine += " ";
|
||||
}
|
||||
sixthLine += "> ";
|
||||
sixthLine += Sender;
|
||||
seventhLine = "QUERY = ";
|
||||
seventhLine += receivedMessage;
|
||||
}
|
||||
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||
} else {
|
||||
Utils::print("Rx Message (APRS-IS): " + packet);
|
||||
if (STATION_Utils::wasHeard(Addressee) && packet.indexOf("EQNS.") == -1 && packet.indexOf("UNIT.") == -1 && packet.indexOf("PARM.") == -1) {
|
||||
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 1));
|
||||
} else if (Config.aprs_is.objectsToRF && packet.indexOf(":;") > 0) {
|
||||
Utils::print("Rx Object (APRS-IS) : " + packet);
|
||||
if (STATION_Utils::checkObjectTime(packet)) {
|
||||
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 5));
|
||||
displayToggle(true);
|
||||
lastScreenOn = millis();
|
||||
Utils::typeOfPacket(packet, 1); // APRS-LoRa
|
||||
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||
Serial.println();
|
||||
} else {
|
||||
Serial.println(" ---> Rejected (Time): No Tx");
|
||||
}
|
||||
}
|
||||
} else if (Config.aprs_is.objectsToRF && packet.indexOf(":;") > 0) {
|
||||
Utils::print("Rx Object (APRS-IS) : " + packet);
|
||||
if (STATION_Utils::checkObjectTime(packet)) {
|
||||
STATION_Utils::addToOutputPacketBuffer(buildPacketToTx(packet, 5));
|
||||
displayToggle(true);
|
||||
lastScreenOn = millis();
|
||||
Utils::typeOfPacket(packet, 1); // APRS-LoRa
|
||||
Serial.println();
|
||||
} else {
|
||||
Serial.println(" ---> Rejected (Time): No Tx");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -374,11 +383,12 @@ namespace APRS_IS_Utils {
|
||||
#ifdef HAS_A7670
|
||||
A7670_Utils::listenAPRSIS();
|
||||
#else
|
||||
if (aprsIsClient.connected()) {
|
||||
if (aprsIsClient.available()) {
|
||||
String aprsisPacket = aprsIsClient.readStringUntil('\r');
|
||||
aprsisPacket.trim(); // Serial.println(aprsisPacket);
|
||||
processAPRSISPacket(aprsisPacket);
|
||||
if (espClient.connected()) {
|
||||
if (espClient.available()) {
|
||||
String aprsisPacket = espClient.readStringUntil('\r');
|
||||
aprsisPacket.trim(); //Serial.println(aprsisPacket);
|
||||
xQueueSend(aprsIsRxQueue, &aprsisPacket, 0);
|
||||
//processAPRSISPacket(aprsisPacket);
|
||||
lastRxTime = millis();
|
||||
}
|
||||
}
|
||||
@@ -386,12 +396,68 @@ namespace APRS_IS_Utils {
|
||||
}
|
||||
|
||||
void firstConnection() {
|
||||
if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !aprsIsClient.connected()) {
|
||||
if (Config.aprs_is.active && (WiFi.status() == WL_CONNECTED) && !espClient.connected()) {
|
||||
connect();
|
||||
while (!passcodeValid) {
|
||||
listenAPRSIS();
|
||||
if (espClient.connected() && espClient.available()) {
|
||||
String aprsisPacket = espClient.readStringUntil('\r');
|
||||
aprsisPacket.trim();
|
||||
if (!passcodeValid && aprsisPacket.indexOf(Config.callsign) != -1) {
|
||||
if (aprsisPacket.indexOf("unverified") != -1 ) {
|
||||
Serial.println("\n****APRS PASSCODE NOT VALID****\n");
|
||||
displayShow(firstLine, "", " APRS PASSCODE", " NOT VALID !!!", "", "", "", 0);
|
||||
while (1) {};
|
||||
} else if (aprsisPacket.indexOf("verified") != -1 ) {
|
||||
Serial.println("(APRS PASSCODE VALIDATED)");
|
||||
passcodeValid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void aprsisListenerTask(void *parameter) {
|
||||
while (true) {
|
||||
listenAPRSIS();
|
||||
vTaskDelay(pdMS_TO_TICKS(10)); // 10ms delay
|
||||
}
|
||||
}
|
||||
|
||||
// Función para iniciar el task
|
||||
bool startListenerAPRSISTask(uint32_t stackSize, UBaseType_t priority) {
|
||||
BaseType_t result = xTaskCreatePinnedToCore(
|
||||
aprsisListenerTask, // Función del task
|
||||
"APRSIS_Listener", // Nombre del task
|
||||
stackSize, // Stack size en words (no bytes)
|
||||
NULL, // Parámetro pasado al task
|
||||
priority, // Prioridad
|
||||
&aprsisTaskHandle, // Handle del task
|
||||
0
|
||||
);
|
||||
|
||||
return (result == pdPASS);
|
||||
}
|
||||
|
||||
// Función opcional para detener el task
|
||||
void stopListenerAPRSISTask() {
|
||||
if (aprsisTaskHandle != NULL) {
|
||||
vTaskDelete(aprsisTaskHandle);
|
||||
aprsisTaskHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Función opcional para suspender/reanudar el task
|
||||
void suspendListenerAPRSISTask() {
|
||||
if (aprsisTaskHandle != NULL) {
|
||||
vTaskSuspend(aprsisTaskHandle);
|
||||
}
|
||||
}
|
||||
|
||||
void resumeListenerAPRSISTask() {
|
||||
if (aprsisTaskHandle != NULL) {
|
||||
vTaskResume(aprsisTaskHandle);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,6 +37,8 @@ float multiplyCorrection = 0.035;
|
||||
|
||||
float voltageDividerTransformation = 0.0;
|
||||
|
||||
int telemetryCounter = random(1,999);
|
||||
|
||||
|
||||
|
||||
#ifdef HAS_ADC_CALIBRATION
|
||||
@@ -226,4 +228,43 @@ namespace BATTERY_Utils {
|
||||
}
|
||||
}
|
||||
|
||||
String generateEncodedTelemetryBytes(float value, bool firstBytes, byte voltageType) { // 0 = internal battery(0-4,2V) , 1 = external battery(0-15V)
|
||||
String encodedBytes;
|
||||
int tempValue;
|
||||
|
||||
if (firstBytes) {
|
||||
tempValue = value;
|
||||
} else {
|
||||
switch (voltageType) {
|
||||
case 0:
|
||||
tempValue = value * 100; // Internal voltage calculation
|
||||
break;
|
||||
case 1:
|
||||
tempValue = (value * 100) / 2; // External voltage calculation
|
||||
break;
|
||||
default:
|
||||
tempValue = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int firstByte = tempValue / 91;
|
||||
tempValue -= firstByte * 91;
|
||||
|
||||
encodedBytes = char(firstByte + 33);
|
||||
encodedBytes += char(tempValue + 33);
|
||||
return encodedBytes;
|
||||
}
|
||||
|
||||
String generateEncodedTelemetry() {
|
||||
String telemetry = "|";
|
||||
telemetry += generateEncodedTelemetryBytes(telemetryCounter, true, 0);
|
||||
telemetryCounter++;
|
||||
if (telemetryCounter == 1000) telemetryCounter = 0;
|
||||
if (Config.battery.sendInternalVoltage) telemetry += generateEncodedTelemetryBytes(checkInternalVoltage(), false, 0);
|
||||
if (Config.battery.sendExternalVoltage) telemetry += generateEncodedTelemetryBytes(checkExternalVoltage(), false, 1);
|
||||
telemetry += "|";
|
||||
return telemetry;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -68,10 +68,6 @@ void Configuration::writeFile() {
|
||||
data["beacon"]["gpsActive"] = beacon.gpsActive;
|
||||
data["beacon"]["gpsAmbiguity"] = beacon.gpsAmbiguity;
|
||||
|
||||
data["personalNote"] = personalNote;
|
||||
|
||||
data["blacklist"] = blacklist;
|
||||
|
||||
data["digi"]["mode"] = digi.mode;
|
||||
data["digi"]["ecoMode"] = digi.ecoMode;
|
||||
#if defined(HAS_A7670)
|
||||
@@ -117,31 +113,28 @@ void Configuration::writeFile() {
|
||||
data["tnc"]["enableSerial"] = tnc.enableSerial;
|
||||
data["tnc"]["acceptOwn"] = tnc.acceptOwn;
|
||||
|
||||
data["mqtt"]["active"] = mqtt.active;
|
||||
data["mqtt"]["server"] = mqtt.server;
|
||||
data["mqtt"]["topic"] = mqtt.topic;
|
||||
data["mqtt"]["username"] = mqtt.username;
|
||||
data["mqtt"]["password"] = mqtt.password;
|
||||
data["mqtt"]["port"] = mqtt.port;
|
||||
data["other"]["rebootMode"] = rebootMode;
|
||||
data["other"]["rebootModeTime"] = rebootModeTime;
|
||||
|
||||
data["ota"]["username"] = ota.username;
|
||||
data["ota"]["password"] = ota.password;
|
||||
|
||||
data["other"]["rememberStationTime"] = rememberStationTime;
|
||||
|
||||
data["other"]["backupDigiMode"] = backupDigiMode;
|
||||
|
||||
data["personalNote"] = personalNote;
|
||||
|
||||
data["blacklist"] = blacklist;
|
||||
|
||||
data["webadmin"]["active"] = webadmin.active;
|
||||
data["webadmin"]["username"] = webadmin.username;
|
||||
data["webadmin"]["password"] = webadmin.password;
|
||||
|
||||
data["remoteManagement"]["managers"] = remoteManagement.managers;
|
||||
data["remoteManagement"]["rfOnly"] = remoteManagement.rfOnly;
|
||||
|
||||
data["ntp"]["gmtCorrection"] = ntp.gmtCorrection;
|
||||
|
||||
data["other"]["rebootMode"] = rebootMode;
|
||||
data["other"]["rebootModeTime"] = rebootModeTime;
|
||||
|
||||
data["other"]["rememberStationTime"] = rememberStationTime;
|
||||
|
||||
data["other"]["backupDigiMode"] = backupDigiMode;
|
||||
data["remoteManagement"]["managers"] = remoteManagement.managers;
|
||||
data["remoteManagement"]["rfOnly"] = remoteManagement.rfOnly;
|
||||
|
||||
serializeJson(data, configFile);
|
||||
|
||||
@@ -177,16 +170,7 @@ bool Configuration::readFile() {
|
||||
wifiAutoAP.timeout = data["wifi"]["autoAP"]["timeout"] | 10;
|
||||
|
||||
callsign = data["callsign"] | "NOCALL-10";
|
||||
|
||||
|
||||
aprs_is.active = data["aprs_is"]["active"] | false;
|
||||
aprs_is.passcode = data["aprs_is"]["passcode"] | "XYZWV";
|
||||
aprs_is.server = data["aprs_is"]["server"] | "rotate.aprs2.net";
|
||||
aprs_is.port = data["aprs_is"]["port"] | 14580;
|
||||
aprs_is.filter = data["aprs_is"]["filter"] | "m/10";
|
||||
aprs_is.messagesToRF = data["aprs_is"]["messagesToRF"] | false;
|
||||
aprs_is.objectsToRF = data["aprs_is"]["objectsToRF"] | false;
|
||||
|
||||
rememberStationTime = data["other"]["rememberStationTime"] | 30;
|
||||
|
||||
beacon.latitude = data["beacon"]["latitude"] | 0.0;
|
||||
beacon.longitude = data["beacon"]["longitude"] | 0.0;
|
||||
@@ -197,16 +181,20 @@ bool Configuration::readFile() {
|
||||
beacon.path = data["beacon"]["path"] | "WIDE1-1";
|
||||
beacon.sendViaAPRSIS = data["beacon"]["sendViaAPRSIS"] | false;
|
||||
beacon.sendViaRF = data["beacon"]["sendViaRF"] | false;
|
||||
|
||||
|
||||
beacon.statusActive = data["beacon"]["statusActive"] | false;
|
||||
beacon.statusPacket = data["beacon"]["statusPacket"] | "";
|
||||
|
||||
beacon.gpsActive = data["beacon"]["gpsActive"] | false;
|
||||
beacon.gpsAmbiguity = data["beacon"]["gpsAmbiguity"] | false;
|
||||
|
||||
personalNote = data["personalNote"] | "personal note here";
|
||||
|
||||
blacklist = data["blacklist"] | "station callsign";
|
||||
aprs_is.active = data["aprs_is"]["active"] | false;
|
||||
aprs_is.passcode = data["aprs_is"]["passcode"] | "XYZWV";
|
||||
aprs_is.server = data["aprs_is"]["server"] | "rotate.aprs2.net";
|
||||
aprs_is.port = data["aprs_is"]["port"] | 14580;
|
||||
aprs_is.filter = data["aprs_is"]["filter"] | "m/10";
|
||||
aprs_is.messagesToRF = data["aprs_is"]["messagesToRF"] | false;
|
||||
aprs_is.objectsToRF = data["aprs_is"]["objectsToRF"] | false;
|
||||
|
||||
digi.mode = data["digi"]["mode"] | 0;
|
||||
digi.ecoMode = data["digi"]["ecoMode"] | 0;
|
||||
@@ -250,18 +238,11 @@ bool Configuration::readFile() {
|
||||
syslog.server = data["syslog"]["server"] | "lora.link9.net";
|
||||
syslog.port = data["syslog"]["port"] | 1514;
|
||||
syslog.logBeaconOverTCPIP = data["syslog"]["logBeaconOverTCPIP"] | false;
|
||||
|
||||
|
||||
tnc.enableServer = data["tnc"]["enableServer"] | false;
|
||||
tnc.enableSerial = data["tnc"]["enableSerial"] | false;
|
||||
tnc.acceptOwn = data["tnc"]["acceptOwn"] | false;
|
||||
|
||||
mqtt.active = data["mqtt"]["active"] | false;
|
||||
mqtt.server = data["mqtt"]["server"] | "";
|
||||
mqtt.topic = data["mqtt"]["topic"] | "aprs-igate";
|
||||
mqtt.username = data["mqtt"]["username"] | "";
|
||||
mqtt.password = data["mqtt"]["password"] | "";
|
||||
mqtt.port = data["mqtt"]["port"] | 1883;
|
||||
|
||||
ota.username = data["ota"]["username"] | "";
|
||||
ota.password = data["ota"]["password"] | "";
|
||||
|
||||
@@ -269,17 +250,19 @@ bool Configuration::readFile() {
|
||||
webadmin.username = data["webadmin"]["username"] | "admin";
|
||||
webadmin.password = data["webadmin"]["password"] | "";
|
||||
|
||||
remoteManagement.managers = data["remoteManagement"]["managers"] | "";
|
||||
remoteManagement.rfOnly = data["remoteManagement"]["rfOnly"] | true;
|
||||
|
||||
ntp.gmtCorrection = data["ntp"]["gmtCorrection"] | 0.0;
|
||||
|
||||
backupDigiMode = data["other"]["backupDigiMode"] | false;
|
||||
|
||||
rebootMode = data["other"]["rebootMode"] | false;
|
||||
rebootModeTime = data["other"]["rebootModeTime"] | 6;
|
||||
|
||||
rememberStationTime = data["other"]["rememberStationTime"] | 30;
|
||||
personalNote = data["personalNote"] | "personal note here";
|
||||
|
||||
backupDigiMode = data["other"]["backupDigiMode"] | false;
|
||||
blacklist = data["blacklist"] | "station callsign";
|
||||
|
||||
remoteManagement.managers = data["remoteManagement"]["managers"] | "";
|
||||
remoteManagement.rfOnly = data["remoteManagement"]["rfOnly"] | true;
|
||||
|
||||
if (wifiAPs.size() == 0) { // If we don't have any WiFi's from config we need to add "empty" SSID for AUTO AP
|
||||
WiFi_AP wifiap;
|
||||
@@ -310,14 +293,6 @@ void Configuration::init() {
|
||||
|
||||
callsign = "N0CALL-10";
|
||||
|
||||
aprs_is.active = false;
|
||||
aprs_is.passcode = "XYZVW";
|
||||
aprs_is.server = "rotate.aprs2.net";
|
||||
aprs_is.port = 14580;
|
||||
aprs_is.filter = "m/10";
|
||||
aprs_is.messagesToRF = false;
|
||||
aprs_is.objectsToRF = false;
|
||||
|
||||
beacon.comment = "LoRa APRS";
|
||||
beacon.latitude = 0.0;
|
||||
beacon.longitude = 0.0;
|
||||
@@ -329,18 +304,26 @@ void Configuration::init() {
|
||||
beacon.path = "WIDE1-1";
|
||||
|
||||
beacon.statusActive = false;
|
||||
beacon.statusPacket = "";
|
||||
beacon.statusPacket = "";
|
||||
|
||||
beacon.gpsActive = false;
|
||||
beacon.gpsAmbiguity = false;
|
||||
|
||||
personalNote = "";
|
||||
|
||||
blacklist = "";
|
||||
|
||||
digi.mode = 0;
|
||||
digi.ecoMode = 0;
|
||||
|
||||
tnc.enableServer = false;
|
||||
tnc.enableSerial = false;
|
||||
tnc.acceptOwn = false;
|
||||
|
||||
aprs_is.active = false;
|
||||
aprs_is.passcode = "XYZVW";
|
||||
aprs_is.server = "rotate.aprs2.net";
|
||||
aprs_is.port = 14580;
|
||||
aprs_is.filter = "m/10";
|
||||
aprs_is.messagesToRF = false;
|
||||
aprs_is.objectsToRF = false;
|
||||
|
||||
loramodule.txFreq = 433775000;
|
||||
loramodule.rxFreq = 433775000;
|
||||
loramodule.spreadingFactor = 12;
|
||||
@@ -353,7 +336,21 @@ void Configuration::init() {
|
||||
display.alwaysOn = true;
|
||||
display.timeout = 4;
|
||||
display.turn180 = false;
|
||||
|
||||
|
||||
syslog.active = false;
|
||||
syslog.server = "lora.link9.net";
|
||||
syslog.port = 1514;
|
||||
syslog.logBeaconOverTCPIP = false;
|
||||
|
||||
wxsensor.active = false;
|
||||
wxsensor.heightCorrection = 0;
|
||||
wxsensor.temperatureCorrection = 0.0;
|
||||
|
||||
ota.username = "";
|
||||
ota.password = "";
|
||||
|
||||
rememberStationTime = 30;
|
||||
|
||||
battery.sendInternalVoltage = false;
|
||||
battery.monitorInternalVoltage = false;
|
||||
battery.internalSleepVoltage = 2.9;
|
||||
@@ -367,44 +364,23 @@ void Configuration::init() {
|
||||
|
||||
battery.sendVoltageAsTelemetry = false;
|
||||
|
||||
wxsensor.active = false;
|
||||
wxsensor.heightCorrection = 0;
|
||||
wxsensor.temperatureCorrection = 0.0;
|
||||
backupDigiMode = false;
|
||||
|
||||
syslog.active = false;
|
||||
syslog.server = "lora.link9.net";
|
||||
syslog.port = 1514;
|
||||
syslog.logBeaconOverTCPIP = false;
|
||||
rebootMode = false;
|
||||
rebootModeTime = 0;
|
||||
|
||||
tnc.enableServer = false;
|
||||
tnc.enableSerial = false;
|
||||
tnc.acceptOwn = false;
|
||||
personalNote = "";
|
||||
|
||||
mqtt.active = false;
|
||||
mqtt.server = "";
|
||||
mqtt.topic = "aprs-igate";
|
||||
mqtt.username = "";
|
||||
mqtt.password = "";
|
||||
mqtt.port = 1883;
|
||||
|
||||
ota.username = "";
|
||||
ota.password = "";
|
||||
blacklist = "";
|
||||
|
||||
webadmin.active = false;
|
||||
webadmin.username = "admin";
|
||||
webadmin.password = "";
|
||||
|
||||
remoteManagement.managers = "";
|
||||
remoteManagement.rfOnly = true;
|
||||
|
||||
ntp.gmtCorrection = 0.0;
|
||||
|
||||
rebootMode = false;
|
||||
rebootModeTime = 0;
|
||||
|
||||
rememberStationTime = 30;
|
||||
|
||||
backupDigiMode = false;
|
||||
remoteManagement.managers = "";
|
||||
remoteManagement.rfOnly = true;
|
||||
|
||||
Serial.println("All is Written!");
|
||||
}
|
||||
|
||||
@@ -101,7 +101,8 @@ void displaySetup() {
|
||||
#endif
|
||||
|
||||
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
||||
if (!display.begin(0x3c, false)) {
|
||||
if (!display.begin(0x3c)) {
|
||||
//if (!display.begin(0x3c, false)) {
|
||||
displayFound = true;
|
||||
if (Config.display.turn180) display.setRotation(2);
|
||||
display.clearDisplay();
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#endif
|
||||
|
||||
extern Configuration Config;
|
||||
extern WiFiClient espClient;
|
||||
extern HardwareSerial gpsSerial;
|
||||
extern TinyGPSPlus gps;
|
||||
String distance, iGateBeaconPacket, iGateLoRaBeaconPacket;
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||
*
|
||||
* This file is part of LoRa APRS iGate.
|
||||
*
|
||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <PubSubClient.h>
|
||||
#include "configuration.h"
|
||||
#include "station_utils.h"
|
||||
#include "mqtt_utils.h"
|
||||
|
||||
|
||||
extern Configuration Config;
|
||||
extern WiFiClient mqttClient;
|
||||
|
||||
PubSubClient pubSub;
|
||||
|
||||
|
||||
namespace MQTT_Utils {
|
||||
|
||||
void sendToMqtt(const String& packet) {
|
||||
if (!pubSub.connected()) {
|
||||
Serial.println("Can not send to MQTT because it is not connected");
|
||||
return;
|
||||
}
|
||||
const String cleanPacket = packet.substring(3);
|
||||
const String sender = cleanPacket.substring(0, cleanPacket.indexOf(">"));
|
||||
const String topic = String(Config.mqtt.topic + "/" + sender);
|
||||
|
||||
const bool result = pubSub.publish(topic.c_str(), cleanPacket.c_str());
|
||||
if (result) {
|
||||
Serial.print("Packet sent to MQTT topic "); Serial.println(topic);
|
||||
} else {
|
||||
Serial.println("Packet not sent to MQTT (check connection)");
|
||||
}
|
||||
}
|
||||
|
||||
void receivedFromMqtt(char* topic, byte* payload, unsigned int length) {
|
||||
Serial.print("Received from MQTT topic "); Serial.print(topic); Serial.print(": ");
|
||||
for (int i = 0; i < length; i++) {
|
||||
Serial.print((char)payload[i]);
|
||||
}
|
||||
Serial.println();
|
||||
STATION_Utils::addToOutputPacketBuffer(String(payload, length));
|
||||
}
|
||||
|
||||
void connect() {
|
||||
if (pubSub.connected()) return;
|
||||
if (Config.mqtt.server.isEmpty() || Config.mqtt.port <= 0) {
|
||||
Serial.println("Connect to MQTT server KO because no host or port given");
|
||||
return;
|
||||
}
|
||||
pubSub.setServer(Config.mqtt.server.c_str(), Config.mqtt.port);
|
||||
Serial.print("Trying to connect with MQTT Server: " + String(Config.mqtt.server) + " MqttServerPort: " + String(Config.mqtt.port));
|
||||
|
||||
bool connected = false;
|
||||
if (!Config.mqtt.username.isEmpty()) {
|
||||
connected = pubSub.connect(Config.callsign.c_str(), Config.mqtt.username.c_str(), Config.mqtt.password.c_str());
|
||||
} else {
|
||||
connected = pubSub.connect(Config.callsign.c_str());
|
||||
}
|
||||
|
||||
if (connected) {
|
||||
Serial.println(" -> Connected !");
|
||||
const String subscribedTopic = Config.mqtt.topic + "/" + Config.callsign + "/#";
|
||||
if (!pubSub.subscribe(subscribedTopic.c_str())) {
|
||||
Serial.println("Subscribed to MQTT Failed");
|
||||
}
|
||||
Serial.print("Subscribed to MQTT topic : ");
|
||||
Serial.println(subscribedTopic);
|
||||
} else {
|
||||
Serial.println(" -> Not Connected (Retry in a few secs)");
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!Config.mqtt.active) return;
|
||||
if (!pubSub.connected()) return;
|
||||
pubSub.loop();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
if (!Config.mqtt.active) return;
|
||||
pubSub.setClient(mqttClient);
|
||||
pubSub.setCallback(receivedFromMqtt);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -88,16 +88,6 @@ namespace POWER_Utils {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
|
||||
void activateMeasurement() {
|
||||
PMU.disableTSPinMeasure();
|
||||
PMU.enableBattDetection();
|
||||
PMU.enableVbusVoltageMeasure();
|
||||
PMU.enableBattVoltageMeasure();
|
||||
PMU.enableSystemVoltageMeasure();
|
||||
}
|
||||
#endif
|
||||
|
||||
double getBatteryVoltage() {
|
||||
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
|
||||
return (PMU.getBattVoltage() / 1000.0);
|
||||
@@ -112,7 +102,17 @@ namespace POWER_Utils {
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void activateMeasurement() {
|
||||
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
|
||||
PMU.disableTSPinMeasure();
|
||||
PMU.enableBattDetection();
|
||||
PMU.enableVbusVoltageMeasure();
|
||||
PMU.enableBattVoltageMeasure();
|
||||
PMU.enableSystemVoltageMeasure();
|
||||
#endif
|
||||
}
|
||||
|
||||
void activateGPS() {
|
||||
#ifdef HAS_AXP192
|
||||
|
||||
@@ -31,7 +31,6 @@ extern float snr;
|
||||
extern int freqError;
|
||||
extern bool shouldSleepLowVoltage;
|
||||
extern bool saveNewDigiEcoModeConfig;
|
||||
extern String versionNumber;
|
||||
|
||||
|
||||
namespace QUERY_Utils {
|
||||
@@ -43,9 +42,7 @@ namespace QUERY_Utils {
|
||||
if (queryQuestion == "?APRS?" || queryQuestion == "H" || queryQuestion == "HELP" || queryQuestion=="?") {
|
||||
answer.concat("?APRSV ?APRSP ?APRSL ?APRSSSR ?EM=? ?TX=? "); // ?APRSH ?WHERE callsign
|
||||
} else if (queryQuestion == "?APRSV") {
|
||||
answer.concat("CA2RXU_LoRa_iGate v");
|
||||
answer.concat(versionNumber);
|
||||
answer.concat(" ");
|
||||
answer.concat("CA2RXU_LoRa_iGate 3.0 v");
|
||||
answer.concat(versionDate);
|
||||
} else if (queryQuestion == "?APRSP") {
|
||||
answer.concat("iGate QTH: ");
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
extern Configuration Config;
|
||||
extern String versionDate;
|
||||
extern String versionNumber;
|
||||
|
||||
WiFiUDP udpClient;
|
||||
|
||||
@@ -36,9 +35,7 @@ namespace SYSLOG_Utils {
|
||||
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
|
||||
String syslogPacket = "<165>1 - ";
|
||||
syslogPacket.concat(Config.callsign);
|
||||
syslogPacket.concat(" CA2RXU_LoRa_iGate_");
|
||||
syslogPacket.concat(versionNumber);
|
||||
syslogPacket.concat(" - - - "); //RFC5424 The Syslog Protocol
|
||||
syslogPacket.concat(" CA2RXU_LoRa_iGate_3.0 - - - "); //RFC5424 The Syslog Protocol
|
||||
|
||||
char signalData[35];
|
||||
snprintf(signalData, sizeof(signalData), " / %ddBm / %.2fdB / %dHz", rssi, snr, freqError);
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
|
||||
*
|
||||
* This file is part of LoRa APRS iGate.
|
||||
*
|
||||
* LoRa APRS iGate is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LoRa APRS iGate is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <APRSPacketLib.h>
|
||||
#include <Arduino.h>
|
||||
#include <vector>
|
||||
#include "telemetry_utils.h"
|
||||
#include "aprs_is_utils.h"
|
||||
#include "configuration.h"
|
||||
#include "station_utils.h"
|
||||
#include "battery_utils.h"
|
||||
#include "lora_utils.h"
|
||||
#include "wx_utils.h"
|
||||
#include "display.h"
|
||||
|
||||
|
||||
extern Configuration Config;
|
||||
extern bool sendStartTelemetry;
|
||||
|
||||
int telemetryCounter = random(1,999);
|
||||
|
||||
|
||||
namespace TELEMETRY_Utils {
|
||||
|
||||
String joinWithCommas(const std::vector<String>& items) {
|
||||
String result;
|
||||
for (size_t i = 0; i < items.size(); ++i) {
|
||||
result += items[i];
|
||||
if (i < items.size() - 1) result += ",";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<String> getEquationCoefficients() {
|
||||
std::vector<String> coefficients;
|
||||
if (Config.battery.sendInternalVoltage) coefficients.push_back("0,0.01,0");
|
||||
if (Config.battery.sendExternalVoltage) coefficients.push_back("0,0.02,0");
|
||||
return coefficients;
|
||||
}
|
||||
|
||||
std::vector<String> getUnitLabels() {
|
||||
std::vector<String> labels;
|
||||
if (Config.battery.sendInternalVoltage) labels.push_back("VDC");
|
||||
if (Config.battery.sendExternalVoltage) labels.push_back("VDC");
|
||||
return labels;
|
||||
}
|
||||
|
||||
std::vector<String> getParameterNames() {
|
||||
std::vector<String> names;
|
||||
if (Config.battery.sendInternalVoltage) names.push_back("V_Batt");
|
||||
if (Config.battery.sendExternalVoltage) names.push_back("V_Ext");
|
||||
return names;
|
||||
}
|
||||
|
||||
void sendBaseTelemetryPacket(const String& prefix, const std::vector<String>& values) {
|
||||
String packet = prefix + joinWithCommas(values);
|
||||
|
||||
if (Config.beacon.sendViaAPRSIS) {
|
||||
String baseAPRSISTelemetryPacket = APRSPacketLib::generateMessagePacket(Config.callsign, "APLRG1", "TCPIP,qAC", Config.callsign, packet);
|
||||
#ifdef HAS_A7670
|
||||
A7670_Utils::uploadToAPRSIS(baseAPRSISTelemetryPacket);
|
||||
#else
|
||||
APRS_IS_Utils::upload(baseAPRSISTelemetryPacket);
|
||||
#endif
|
||||
delay(300);
|
||||
} else if (Config.beacon.sendViaRF) {
|
||||
String baseRFTelemetryPacket = APRSPacketLib::generateMessagePacket(Config.callsign, "APLRG1", Config.beacon.path, Config.callsign, packet);
|
||||
LoRa_Utils::sendNewPacket(baseRFTelemetryPacket);
|
||||
delay(3000);
|
||||
}
|
||||
}
|
||||
|
||||
void sendEquationsUnitsParameters() {
|
||||
sendBaseTelemetryPacket("EQNS.", getEquationCoefficients());
|
||||
sendBaseTelemetryPacket("UNIT.", getUnitLabels());
|
||||
sendBaseTelemetryPacket("PARM.", getParameterNames());
|
||||
sendStartTelemetry = false;
|
||||
}
|
||||
|
||||
String generateEncodedTelemetryBytes(float value, bool counterBytes, byte telemetryType) {
|
||||
String encodedBytes;
|
||||
int tempValue;
|
||||
|
||||
if (counterBytes) {
|
||||
tempValue = value;
|
||||
} else {
|
||||
switch (telemetryType) {
|
||||
case 0: tempValue = value * 100; break; // Internal voltage (0-4,2V), Humidity, Gas calculation
|
||||
case 1: tempValue = (value * 100) / 2; break; // External voltage calculation (0-15V)
|
||||
case 2: tempValue = (value * 10) + 500; break; // Temperature
|
||||
case 3: tempValue = (value * 8); break; // Pressure
|
||||
default: tempValue = value; break;
|
||||
}
|
||||
}
|
||||
|
||||
int firstByte = tempValue / 91;
|
||||
tempValue -= firstByte * 91;
|
||||
|
||||
encodedBytes = char(firstByte + 33);
|
||||
encodedBytes += char(tempValue + 33);
|
||||
return encodedBytes;
|
||||
}
|
||||
|
||||
String generateEncodedTelemetry() {
|
||||
String telemetry = "|";
|
||||
telemetry += generateEncodedTelemetryBytes(telemetryCounter, true, 0);
|
||||
telemetryCounter++;
|
||||
if (telemetryCounter == 1000) telemetryCounter = 0;
|
||||
if (Config.battery.sendInternalVoltage) telemetry += generateEncodedTelemetryBytes(BATTERY_Utils::checkInternalVoltage(), false, 0);
|
||||
if (Config.battery.sendExternalVoltage) telemetry += generateEncodedTelemetryBytes(BATTERY_Utils::checkExternalVoltage(), false, 1);
|
||||
telemetry += "|";
|
||||
return telemetry;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include <TinyGPS++.h>
|
||||
#include <WiFi.h>
|
||||
#include "telemetry_utils.h"
|
||||
#include "configuration.h"
|
||||
#include "station_utils.h"
|
||||
#include "battery_utils.h"
|
||||
@@ -35,6 +34,7 @@
|
||||
|
||||
|
||||
extern Configuration Config;
|
||||
extern WiFiClient espClient;
|
||||
extern TinyGPSPlus gps;
|
||||
extern String versionDate;
|
||||
extern String firstLine;
|
||||
@@ -133,6 +133,77 @@ namespace Utils {
|
||||
fourthLine = buffer;
|
||||
}
|
||||
|
||||
void sendInitialTelemetryPackets() {
|
||||
char sender[10]; // 9 characters + null terminator
|
||||
snprintf(sender, sizeof(sender), "%-9s", Config.callsign.c_str()); // Left-align with spaces
|
||||
|
||||
String baseAPRSISTelemetryPacket = Config.callsign;
|
||||
baseAPRSISTelemetryPacket += ">APLRG1,TCPIP,qAC::";
|
||||
baseAPRSISTelemetryPacket += sender;
|
||||
baseAPRSISTelemetryPacket += ":";
|
||||
|
||||
String baseRFTelemetryPacket = Config.callsign;
|
||||
baseRFTelemetryPacket += ">APLRG1";
|
||||
if (Config.beacon.path.indexOf("WIDE") != -1) {
|
||||
baseRFTelemetryPacket += ",";
|
||||
baseRFTelemetryPacket += Config.beacon.path;
|
||||
}
|
||||
baseRFTelemetryPacket += "::";
|
||||
baseRFTelemetryPacket += sender;
|
||||
baseRFTelemetryPacket += ":";
|
||||
|
||||
String telemetryPacket1 = "EQNS.";
|
||||
if (Config.battery.sendInternalVoltage) {
|
||||
telemetryPacket1 += "0,0.01,0";
|
||||
}
|
||||
if (Config.battery.sendExternalVoltage) {
|
||||
telemetryPacket1 += String(Config.battery.sendInternalVoltage ? ",0,0.02,0" : "0,0.02,0");
|
||||
}
|
||||
|
||||
String telemetryPacket2 = "UNIT.";
|
||||
if (Config.battery.sendInternalVoltage) {
|
||||
telemetryPacket2 += "VDC";
|
||||
}
|
||||
if (Config.battery.sendExternalVoltage) {
|
||||
telemetryPacket2 += String(Config.battery.sendInternalVoltage ? ",VDC" : "VDC");
|
||||
}
|
||||
|
||||
String telemetryPacket3 = "PARM.";
|
||||
if (Config.battery.sendInternalVoltage) {
|
||||
telemetryPacket3 += "V_Batt";
|
||||
}
|
||||
if (Config.battery.sendExternalVoltage) {
|
||||
telemetryPacket3 += String(Config.battery.sendInternalVoltage ? ",V_Ext" : "V_Ext");
|
||||
}
|
||||
|
||||
if (Config.beacon.sendViaAPRSIS) {
|
||||
#ifdef HAS_A7670
|
||||
A7670_Utils::uploadToAPRSIS(baseAPRSISTelemetryPacket + telemetryPacket1);
|
||||
delay(300);
|
||||
A7670_Utils::uploadToAPRSIS(baseAPRSISTelemetryPacket + telemetryPacket2);
|
||||
delay(300);
|
||||
A7670_Utils::uploadToAPRSIS(baseAPRSISTelemetryPacket + telemetryPacket3);
|
||||
delay(300);
|
||||
#else
|
||||
APRS_IS_Utils::upload(baseAPRSISTelemetryPacket + telemetryPacket1);
|
||||
delay(300);
|
||||
APRS_IS_Utils::upload(baseAPRSISTelemetryPacket + telemetryPacket2);
|
||||
delay(300);
|
||||
APRS_IS_Utils::upload(baseAPRSISTelemetryPacket + telemetryPacket3);
|
||||
delay(300);
|
||||
#endif
|
||||
delay(300);
|
||||
} else if (Config.beacon.sendViaRF) {
|
||||
LoRa_Utils::sendNewPacket(baseRFTelemetryPacket + telemetryPacket1);
|
||||
delay(3000);
|
||||
LoRa_Utils::sendNewPacket(baseRFTelemetryPacket + telemetryPacket2);
|
||||
delay(3000);
|
||||
LoRa_Utils::sendNewPacket(baseRFTelemetryPacket + telemetryPacket3);
|
||||
delay(3000);
|
||||
}
|
||||
sendStartTelemetry = false;
|
||||
}
|
||||
|
||||
void checkBeaconInterval() {
|
||||
uint32_t lastTx = millis() - lastBeaconTx;
|
||||
if (lastBeaconTx == 0 || lastTx >= Config.beacon.interval * 60 * 1000) {
|
||||
@@ -154,7 +225,7 @@ namespace Utils {
|
||||
!Config.wxsensor.active &&
|
||||
(Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage) &&
|
||||
(lastBeaconTx > 0)) {
|
||||
TELEMETRY_Utils::sendEquationsUnitsParameters();
|
||||
sendInitialTelemetryPackets();
|
||||
}
|
||||
|
||||
STATION_Utils::deleteNotHeard();
|
||||
@@ -238,7 +309,7 @@ namespace Utils {
|
||||
#endif
|
||||
|
||||
if (Config.battery.sendVoltageAsTelemetry && !Config.wxsensor.active && (Config.battery.sendInternalVoltage || Config.battery.sendExternalVoltage)){
|
||||
String encodedTelemetry = TELEMETRY_Utils::generateEncodedTelemetry();
|
||||
String encodedTelemetry = BATTERY_Utils::generateEncodedTelemetry();
|
||||
beaconPacket += encodedTelemetry;
|
||||
secondaryBeaconPacket += encodedTelemetry;
|
||||
}
|
||||
|
||||
@@ -130,20 +130,19 @@ namespace WEB_Utils {
|
||||
}
|
||||
|
||||
Config.callsign = request->getParam("callsign", true)->value();
|
||||
|
||||
|
||||
Config.wifiAutoAP.password = request->getParam("wifi.autoAP.password", true)->value();
|
||||
Config.wifiAutoAP.timeout = request->getParam("wifi.autoAP.timeout", true)->value().toInt();
|
||||
|
||||
|
||||
|
||||
Config.aprs_is.active = request->hasParam("aprs_is.active", true);
|
||||
if (Config.aprs_is.active) {
|
||||
Config.aprs_is.messagesToRF = request->hasParam("aprs_is.messagesToRF", true);
|
||||
Config.aprs_is.objectsToRF = request->hasParam("aprs_is.objectsToRF", true);
|
||||
Config.aprs_is.server = request->getParam("aprs_is.server", true)->value();
|
||||
Config.aprs_is.passcode = request->getParam("aprs_is.passcode", true)->value();
|
||||
Config.aprs_is.port = request->getParam("aprs_is.port", true)->value().toInt();
|
||||
Config.aprs_is.filter = request->getParam("aprs_is.filter", true)->value();
|
||||
}
|
||||
Config.aprs_is.passcode = request->getParam("aprs_is.passcode", true)->value();
|
||||
Config.aprs_is.server = request->getParam("aprs_is.server", true)->value();
|
||||
Config.aprs_is.port = request->getParam("aprs_is.port", true)->value().toInt();
|
||||
Config.aprs_is.filter = request->getParam("aprs_is.filter", true)->value();
|
||||
Config.aprs_is.messagesToRF = request->hasParam("aprs_is.messagesToRF", true);
|
||||
Config.aprs_is.objectsToRF = request->hasParam("aprs_is.objectsToRF", true);
|
||||
|
||||
|
||||
Config.beacon.interval = request->getParam("beacon.interval", true)->value().toInt();
|
||||
Config.beacon.sendViaAPRSIS = request->hasParam("beacon.sendViaAPRSIS", true);
|
||||
@@ -156,20 +155,16 @@ namespace WEB_Utils {
|
||||
Config.beacon.path = request->getParam("beacon.path", true)->value();
|
||||
|
||||
Config.beacon.statusActive = request->hasParam("beacon.statusActive", true);
|
||||
if (Config.beacon.statusActive) {
|
||||
Config.beacon.statusPacket = request->getParam("beacon.statusPacket", true)->value();
|
||||
}
|
||||
Config.beacon.statusPacket = request->getParam("beacon.statusPacket", true)->value();
|
||||
|
||||
Config.beacon.gpsActive = request->hasParam("beacon.gpsActive", true);
|
||||
Config.beacon.gpsAmbiguity = request->hasParam("beacon.gpsAmbiguity", true);
|
||||
|
||||
Config.personalNote = request->getParam("personalNote", true)->value();
|
||||
|
||||
Config.blacklist = request->getParam("blacklist", true)->value();
|
||||
|
||||
Config.digi.mode = request->getParam("digi.mode", true)->value().toInt();
|
||||
Config.digi.ecoMode = request->getParam("digi.ecoMode", true)->value().toInt();;
|
||||
|
||||
|
||||
Config.loramodule.txFreq = request->getParam("lora.txFreq", true)->value().toInt();
|
||||
Config.loramodule.rxFreq = request->getParam("lora.rxFreq", true)->value().toInt();
|
||||
Config.loramodule.spreadingFactor = request->getParam("lora.spreadingFactor", true)->value().toInt();
|
||||
@@ -180,18 +175,16 @@ namespace WEB_Utils {
|
||||
Config.loramodule.rxActive = request->hasParam("lora.rxActive", true);
|
||||
|
||||
|
||||
Config.display.alwaysOn = request->hasParam("display.alwaysOn", true);
|
||||
Config.display.alwaysOn = request->hasParam("display.alwaysOn", true);
|
||||
if (!Config.display.alwaysOn) {
|
||||
Config.display.timeout = request->getParam("display.timeout", true)->value().toInt();
|
||||
Config.display.timeout = request->getParam("display.timeout", true)->value().toInt();
|
||||
}
|
||||
Config.display.turn180 = request->hasParam("display.turn180", true);
|
||||
Config.display.turn180 = request->hasParam("display.turn180", true);
|
||||
|
||||
|
||||
Config.battery.sendInternalVoltage = request->hasParam("battery.sendInternalVoltage", true);
|
||||
Config.battery.monitorInternalVoltage = request->hasParam("battery.monitorInternalVoltage", true);
|
||||
if (Config.battery.monitorInternalVoltage) {
|
||||
Config.battery.internalSleepVoltage = request->getParam("battery.internalSleepVoltage", true)->value().toFloat();
|
||||
}
|
||||
Config.battery.internalSleepVoltage = request->getParam("battery.internalSleepVoltage", true)->value().toFloat();
|
||||
|
||||
Config.battery.sendExternalVoltage = request->hasParam("battery.sendExternalVoltage", true);
|
||||
if (Config.battery.sendExternalVoltage) {
|
||||
@@ -200,20 +193,17 @@ namespace WEB_Utils {
|
||||
Config.battery.voltageDividerR2 = request->getParam("battery.voltageDividerR2", true)->value().toFloat();
|
||||
}
|
||||
Config.battery.monitorExternalVoltage = request->hasParam("battery.monitorExternalVoltage", true);
|
||||
if (Config.battery.monitorExternalVoltage) {
|
||||
Config.battery.externalSleepVoltage = request->getParam("battery.externalSleepVoltage", true)->value().toFloat();
|
||||
}
|
||||
Config.battery.externalSleepVoltage = request->getParam("battery.externalSleepVoltage", true)->value().toFloat();
|
||||
|
||||
Config.battery.sendVoltageAsTelemetry = request->hasParam("battery.sendVoltageAsTelemetry", true);
|
||||
|
||||
|
||||
Config.wxsensor.active = request->hasParam("wxsensor.active", true);
|
||||
Config.wxsensor.active = request->hasParam("wxsensor.active", true);
|
||||
Config.wxsensor.heightCorrection = request->getParam("wxsensor.heightCorrection", true)->value().toInt();
|
||||
Config.wxsensor.temperatureCorrection = request->getParam("wxsensor.temperatureCorrection", true)->value().toFloat();
|
||||
if (Config.wxsensor.active) {
|
||||
Config.wxsensor.heightCorrection = request->getParam("wxsensor.heightCorrection", true)->value().toInt();
|
||||
Config.wxsensor.temperatureCorrection = request->getParam("wxsensor.temperatureCorrection", true)->value().toFloat();
|
||||
Config.beacon.symbol = "_";
|
||||
}
|
||||
|
||||
|
||||
Config.syslog.active = request->hasParam("syslog.active", true);
|
||||
if (Config.syslog.active) {
|
||||
Config.syslog.server = request->getParam("syslog.server", true)->value();
|
||||
@@ -221,29 +211,23 @@ namespace WEB_Utils {
|
||||
Config.syslog.logBeaconOverTCPIP = request->hasParam("syslog.logBeaconOverTCPIP", true);
|
||||
}
|
||||
|
||||
Config.tnc.enableServer = request->hasParam("tnc.enableServer", true);
|
||||
Config.tnc.enableSerial = request->hasParam("tnc.enableSerial", true);
|
||||
Config.tnc.acceptOwn = request->hasParam("tnc.acceptOwn", true);
|
||||
|
||||
Config.tnc.enableServer = request->hasParam("tnc.enableServer", true);
|
||||
Config.tnc.enableSerial = request->hasParam("tnc.enableSerial", true);
|
||||
Config.tnc.acceptOwn = request->hasParam("tnc.acceptOwn", true);
|
||||
Config.rebootMode = request->hasParam("other.rebootMode", true);
|
||||
Config.rebootModeTime = request->getParam("other.rebootModeTime", true)->value().toInt();
|
||||
|
||||
Config.ota.username = request->getParam("ota.username", true)->value();
|
||||
Config.ota.password = request->getParam("ota.password", true)->value();
|
||||
|
||||
Config.mqtt.active = request->hasParam("mqtt.active", true);
|
||||
if (Config.mqtt.active) {
|
||||
Config.mqtt.server = request->getParam("mqtt.server", true)->value();
|
||||
Config.mqtt.topic = request->getParam("mqtt.topic", true)->value();
|
||||
Config.mqtt.username = request->getParam("mqtt.username", true)->value();
|
||||
Config.mqtt.password = request->getParam("mqtt.password", true)->value();
|
||||
Config.mqtt.port = request->getParam("mqtt.port", true)->value().toInt();
|
||||
}
|
||||
Config.rememberStationTime = request->getParam("other.rememberStationTime", true)->value().toInt();
|
||||
|
||||
|
||||
Config.rebootMode = request->hasParam("other.rebootMode", true);
|
||||
if (Config.rebootMode) {
|
||||
Config.rebootModeTime = request->getParam("other.rebootModeTime", true)->value().toInt();
|
||||
}
|
||||
Config.backupDigiMode = request->hasParam("other.backupDigiMode", true);
|
||||
|
||||
Config.ota.username = request->getParam("ota.username", true)->value();
|
||||
Config.ota.password = request->getParam("ota.password", true)->value();
|
||||
Config.personalNote = request->getParam("personalNote", true)->value();
|
||||
|
||||
Config.blacklist = request->getParam("blacklist", true)->value();
|
||||
|
||||
Config.webadmin.active = request->hasParam("webadmin.active", true);
|
||||
if (Config.webadmin.active) {
|
||||
@@ -251,14 +235,10 @@ namespace WEB_Utils {
|
||||
Config.webadmin.password = request->getParam("webadmin.password", true)->value();
|
||||
}
|
||||
|
||||
Config.remoteManagement.managers = request->getParam("remoteManagement.managers", true)->value();
|
||||
Config.remoteManagement.rfOnly = request->hasParam("remoteManagement.rfOnly", true);
|
||||
|
||||
Config.ntp.gmtCorrection = request->getParam("ntp.gmtCorrection", true)->value().toFloat();
|
||||
|
||||
Config.rememberStationTime = request->getParam("other.rememberStationTime", true)->value().toInt();
|
||||
|
||||
Config.backupDigiMode = request->hasParam("other.backupDigiMode", true);
|
||||
Config.remoteManagement.managers = request->getParam("remoteManagement.managers", true)->value();
|
||||
Config.remoteManagement.rfOnly = request->getParam("remoteManagement.rfOnly", true);
|
||||
|
||||
Config.writeFile();
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#define OLED_RST -1 // Reset pin # (or -1 if sharing Arduino reset pin)
|
||||
|
||||
// Aditional Config
|
||||
#define HAS_TWO_CORES
|
||||
#define INTERNAL_LED_PIN 25 // Green Led
|
||||
#define BATTERY_PIN 35
|
||||
#define HAS_ADC_CALIBRATION
|
||||
|
||||
Reference in New Issue
Block a user