kopia lustrzana https://github.com/lora-aprs/LoRa_APRS_iGate
Merge branch 'master' into fkp-Gualtherius-LoRaHam
commit
a90122beec
|
@ -1,19 +1,15 @@
|
|||
name: Integreation Tests
|
||||
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
- '!master'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
version_check:
|
||||
name: Version Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
- name: check version
|
||||
run: ./scripts/check_version.py
|
||||
|
||||
build:
|
||||
name: Compile Firmware
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
@ -1,46 +1,39 @@
|
|||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
name: Create new release
|
||||
|
||||
name: Upload Release Assets
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Upload Release Assets
|
||||
version_check:
|
||||
name: Version Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
- run: pip install GitPython
|
||||
- name: check version
|
||||
run: ./scripts/check_version.py
|
||||
|
||||
create_release:
|
||||
needs: version_check
|
||||
name: Create new release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: sudo apt-get install python3-setuptools python3-wheel
|
||||
- run: pip3 install platformio
|
||||
- run: echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
- run: platformio run
|
||||
- id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: echo "VERSION=$(./scripts/create_version_tag.py)" >> $GITHUB_ENV
|
||||
- uses: ncipollo/release-action@v1
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: Release ${{ github.ref }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
# upload firmware bin
|
||||
- uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: .pio/build/lora_board/firmware.bin
|
||||
asset_name: lora_board.bin
|
||||
asset_content_type: application/bin
|
||||
# upload json file
|
||||
- uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: data/is-cfg.json
|
||||
asset_name: is-cfg.json
|
||||
asset_content_type: application/json
|
||||
tag: ${{ env.VERSION }}
|
||||
commit: master
|
||||
generateReleaseNotes: true
|
||||
artifacts: ".pio/build/lora_board/firmware.bin,data/is-cfg.json"
|
||||
owner: ${{ secrets.OWNER }}
|
||||
token: ${{ secrets.PAT }}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
name: tweet-release
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
tweet:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: Eomm/why-don-t-you-tweet@v1
|
||||
if: ${{ !github.event.repository.private }}
|
||||
with:
|
||||
tweet-message: "New ${{ github.event.repository.name }} release ${{ github.event.release.tag_name }}! ${{ github.event.release.html_url }} #LoRa #APRS #HAM #hamradio #iGate"
|
||||
env:
|
||||
TWITTER_CONSUMER_API_KEY: ${{ secrets.TWITTER_CONSUMER_API_KEY }}
|
||||
TWITTER_CONSUMER_API_SECRET: ${{ secrets.TWITTER_CONSUMER_API_SECRET }}
|
||||
TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
|
||||
TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
|
|
@ -29,6 +29,7 @@
|
|||
"latitude": 0.000000,
|
||||
"longitude": 0.000000
|
||||
},
|
||||
"use_gps": false,
|
||||
"timeout": 15
|
||||
},
|
||||
"aprs_is": {
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
#define MODULE_NAME "BoardFinder"
|
||||
|
||||
BoardConfig::BoardConfig(String name, BoardType type, uint8_t oledsda, uint8_t oledscl, uint8_t oledaddr, uint8_t oledreset, uint8_t lorasck, uint8_t loramiso, uint8_t loramosi, uint8_t loracs, uint8_t lorareset, uint8_t lorairq, bool needcheckpowerchip, bool powercheckstatus)
|
||||
: Name(name), Type(type), OledSda(oledsda), OledScl(oledscl), OledAddr(oledaddr), OledReset(oledreset), LoraSck(lorasck), LoraMiso(loramiso), LoraMosi(loramosi), LoraCS(loracs), LoraReset(lorareset), LoraIRQ(lorairq), needCheckPowerChip(needcheckpowerchip), powerCheckStatus(powercheckstatus) {
|
||||
BoardConfig::BoardConfig(String name, BoardType type, uint8_t oledsda, uint8_t oledscl, uint8_t oledaddr, uint8_t oledreset, uint8_t lorasck, uint8_t loramiso, uint8_t loramosi, uint8_t loracs, uint8_t lorareset, uint8_t lorairq, uint8_t gpsrx, uint8_t gpstx, uint8_t button, bool needcheckpowerchip, bool powercheckstatus)
|
||||
: Name(name), Type(type), OledSda(oledsda), OledScl(oledscl), OledAddr(oledaddr), OledReset(oledreset), LoraSck(lorasck), LoraMiso(loramiso), LoraMosi(loramosi), LoraCS(loracs), LoraReset(lorareset), LoraIRQ(lorairq), GpsRx(gpsrx), GpsTx(gpstx), Button(button), needCheckPowerChip(needcheckpowerchip), powerCheckStatus(powercheckstatus) {
|
||||
}
|
||||
|
||||
BoardFinder::BoardFinder(const std::list<BoardConfig const *> &boardConfigs) : _boardConfigs(boardConfigs) {
|
||||
|
@ -130,14 +130,14 @@ bool BoardFinder::checkPowerConfig(BoardConfig const *boardConfig, logging::Logg
|
|||
}
|
||||
|
||||
// clang-format off
|
||||
BoardConfig TTGO_LORA32_V1 ("TTGO_LORA32_V1", eTTGO_LORA32_V1, 4, 15, 0x3C, 0, 5, 19, 27, 18, 14, 26);
|
||||
BoardConfig TTGO_LORA32_V2 ("TTGO_LORA32_V2", eTTGO_LORA32_V2, 21, 22, 0x3C, 0, 5, 19, 27, 18, 14, 26, true);
|
||||
BoardConfig TTGO_T_Beam_V0_7 ("TTGO_T_Beam_V0_7", eTTGO_T_Beam_V0_7, 21, 22, 0x3C, 0, 5, 19, 27, 18, 14, 26, true);
|
||||
BoardConfig TTGO_T_Beam_V1_0 ("TTGO_T_Beam_V1_0", eTTGO_T_Beam_V1_0, 21, 22, 0x3C, 0, 5, 19, 27, 18, 14, 26, true, true);
|
||||
BoardConfig ETH_BOARD ("ETH_BOARD", eETH_BOARD, 33, 32, 0x3C, 0, 14, 2, 15, 12, 4, 36);
|
||||
BoardConfig TRACKERD ("TRACKERD", eTRACKERD, 5, 4, 0x3C, 0, 18, 19, 23, 16, 14, 26);
|
||||
BoardConfig HELTEC_WIFI_LORA_32_V1("HELTEC_WIFI_LORA_32_V1", eHELTEC_WIFI_LORA_32_V1, 4, 15, 0x3C, 16, 5, 19, 27, 18, 14, 26);
|
||||
BoardConfig HELTEC_WIFI_LORA_32_V2("HELTEC_WIFI_LORA_32_V2", eHELTEC_WIFI_LORA_32_V2, 4, 15, 0x3C, 16, 5, 19, 27, 18, 14, 26);
|
||||
BoardConfig GUALTHERIUS_LORAHAM_v100("GUALTHERIUS_LORAHAM_v100", eGUALTHERIUS_LORAHAM_v100, 17, 16, 0x3C, 0, 18, 19, 23, 5, 13, 35);
|
||||
BoardConfig GUALTHERIUS_LORAHAM_v106("GUALTHERIUS_LORAHAM_v106", eGUALTHERIUS_LORAHAM_v100, 17, 16, 0x3C, 0, 18, 19, 23, 2, 13, 35);
|
||||
BoardConfig TTGO_LORA32_V1 ("TTGO_LORA32_V1", eTTGO_LORA32_V1, 4, 15, 0x3C, 0, 5, 19, 27, 18, 14, 26, 0, 0, 0);
|
||||
BoardConfig TTGO_LORA32_V2 ("TTGO_LORA32_V2", eTTGO_LORA32_V2, 21, 22, 0x3C, 0, 5, 19, 27, 18, 14, 26, 0, 0, 0, true);
|
||||
BoardConfig TTGO_T_Beam_V0_7 ("TTGO_T_Beam_V0_7", eTTGO_T_Beam_V0_7, 21, 22, 0x3C, 0, 5, 19, 27, 18, 14, 26, 15, 12, 38, true);
|
||||
BoardConfig TTGO_T_Beam_V1_0 ("TTGO_T_Beam_V1_0", eTTGO_T_Beam_V1_0, 21, 22, 0x3C, 0, 5, 19, 27, 18, 14, 26, 12, 34, 38, true, true);
|
||||
BoardConfig ETH_BOARD ("ETH_BOARD", eETH_BOARD, 33, 32, 0x3C, 0, 14, 2, 15, 12, 4, 36, 0, 0, 0);
|
||||
BoardConfig TRACKERD ("TRACKERD", eTRACKERD, 5, 4, 0x3C, 0, 18, 19, 23, 16, 14, 26, 0, 0, 0);
|
||||
BoardConfig HELTEC_WIFI_LORA_32_V1("HELTEC_WIFI_LORA_32_V1", eHELTEC_WIFI_LORA_32_V1, 4, 15, 0x3C, 16, 5, 19, 27, 18, 14, 26, 0, 0, 0);
|
||||
BoardConfig HELTEC_WIFI_LORA_32_V2("HELTEC_WIFI_LORA_32_V2", eHELTEC_WIFI_LORA_32_V2, 4, 15, 0x3C, 16, 5, 19, 27, 18, 14, 26, 0, 0, 0);
|
||||
BoardConfig GUALTHERIUS_LORAHAM_v100("GUALTHERIUS_LORAHAM_v100", eGUALTHERIUS_LORAHAM_v100, 17, 16, 0x3C, 0, 18, 19, 23, 5, 13, 35, 0, 0, 0);
|
||||
BoardConfig GUALTHERIUS_LORAHAM_v106("GUALTHERIUS_LORAHAM_v106", eGUALTHERIUS_LORAHAM_v106, 17, 16, 0x3C, 0, 18, 19, 23, 2, 13, 35, 0, 0, 0);
|
||||
// clang-format on
|
||||
|
|
|
@ -26,7 +26,7 @@ enum BoardType
|
|||
|
||||
class BoardConfig {
|
||||
public:
|
||||
explicit BoardConfig(String name, BoardType type, uint8_t oledsda, uint8_t oledscl, uint8_t oledaddr, uint8_t oledreset, uint8_t lorasck, uint8_t loramiso, uint8_t loramosi, uint8_t loracs, uint8_t lorareset, uint8_t lorairq, bool needcheckpowerchip = false, bool powercheckstatus = false);
|
||||
explicit BoardConfig(String name, BoardType type, uint8_t oledsda, uint8_t oledscl, uint8_t oledaddr, uint8_t oledreset, uint8_t lorasck, uint8_t loramiso, uint8_t loramosi, uint8_t loracs, uint8_t lorareset, uint8_t lorairq, uint8_t gpsrx, uint8_t gpstx, uint8_t button, bool needcheckpowerchip = false, bool powercheckstatus = false);
|
||||
|
||||
String Name;
|
||||
BoardType Type;
|
||||
|
@ -42,6 +42,9 @@ public:
|
|||
uint8_t LoraCS;
|
||||
uint8_t LoraReset;
|
||||
uint8_t LoraIRQ;
|
||||
uint8_t GpsRx;
|
||||
uint8_t GpsTx;
|
||||
uint8_t Button;
|
||||
|
||||
bool needCheckPowerChip;
|
||||
bool powerCheckStatus;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#define REG_FIFO_RX_CURRENT_ADDR 0x10
|
||||
#define REG_IRQ_FLAGS 0x12
|
||||
#define REG_RX_NB_BYTES 0x13
|
||||
#define REG_MODEM_STAT 0x18
|
||||
#define REG_PKT_SNR_VALUE 0x19
|
||||
#define REG_PKT_RSSI_VALUE 0x1a
|
||||
#define REG_RSSI_VALUE 0x1b
|
||||
|
@ -251,6 +252,10 @@ float LoRaClass::packetSnr() {
|
|||
return ((int8_t)readRegister(REG_PKT_SNR_VALUE)) * 0.25;
|
||||
}
|
||||
|
||||
bool LoRaClass::rxSignalDetected() {
|
||||
return (readRegister(REG_MODEM_STAT) & 0x01) == 0x01;
|
||||
}
|
||||
|
||||
long LoRaClass::packetFrequencyError() {
|
||||
int32_t freqError = 0;
|
||||
freqError = static_cast<int32_t>(readRegister(REG_FREQ_ERROR_MSB) & B111);
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
int packetRssi();
|
||||
float packetSnr();
|
||||
long packetFrequencyError();
|
||||
bool rxSignalDetected();
|
||||
|
||||
int rssi();
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ lib_deps =
|
|||
peterus/esp-logger @ 1.0.0
|
||||
peterus/ESP-FTP-Server-Lib @ 0.9.5
|
||||
knolleary/PubSubClient@^2.8
|
||||
mikalhart/TinyGPSPlus @ 1.0.2
|
||||
shaggydog/OneButton @ 1.5.0
|
||||
check_tool = cppcheck
|
||||
check_flags =
|
||||
cppcheck: --suppress=*:*.pio\* --inline-suppr -DCPPCHECK --force lib -ilib/TimeLib -ilib/LoRa -ilib/NTPClient
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import git
|
||||
from datetime import date
|
||||
|
||||
today = date.today()
|
||||
|
@ -16,20 +17,33 @@ with open("src/LoRa_APRS_iGate.cpp") as f:
|
|||
version_split = version.split(".")
|
||||
version_year = int(version_split[0])
|
||||
version_week = int(version_split[1])
|
||||
version_vers = int(version_split[2])
|
||||
|
||||
print(f"firmware version year: {version_year}")
|
||||
print(f"firmware version week: {version_week}")
|
||||
print(f"[INFO] firmware version year: {version_year}")
|
||||
print(f"[INFO] firmware version week: {version_week}")
|
||||
print(f"[INFO] firmware version version: {version_vers}")
|
||||
print(f"[INFO] -> {version}")
|
||||
|
||||
print(f"current year: {current_year}")
|
||||
print(f"current week: {current_week}")
|
||||
print(f"[INFO] current year: {current_year}")
|
||||
print(f"[INFO] current week: {current_week}")
|
||||
print(f"[INFO] -> {current_year}.{current_week}.x")
|
||||
|
||||
error = False
|
||||
if version_year != current_year:
|
||||
print("firmware version is not current year!")
|
||||
print("[ERROR] firmware version is not current year!")
|
||||
error = True
|
||||
|
||||
if version_week != current_week:
|
||||
print("firmware version is not current week!")
|
||||
print("[ERROR] firmware version is not current week!")
|
||||
error = True
|
||||
|
||||
repo = git.Repo('.')
|
||||
print(f"[INFO] found {len(repo.tags)} tags in repo")
|
||||
if f"v{version}" in repo.tags:
|
||||
print("[ERROR] tag with this version is already existing")
|
||||
error = True
|
||||
|
||||
if error:
|
||||
print("[ERROR] check/update VERSION define in src/LoRa_APRS_iGate.cpp to fix this issue")
|
||||
|
||||
exit(error)
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from datetime import date
|
||||
|
||||
today = date.today()
|
||||
|
||||
current_year = int(str(today.isocalendar()[0])[2:])
|
||||
current_week = int(today.isocalendar()[1])
|
||||
|
||||
version = None
|
||||
with open("src/LoRa_APRS_iGate.cpp") as f:
|
||||
for line in f:
|
||||
if line.startswith("#define VERSION"):
|
||||
version = line.strip().split(" ")[-1].replace('"', "")
|
||||
|
||||
version_split = version.split(".")
|
||||
version_year = int(version_split[0])
|
||||
version_week = int(version_split[1])
|
||||
version_vers = int(version_split[2])
|
||||
|
||||
print(f"v{version_year}.{version_week}.{version_vers}")
|
|
@ -8,6 +8,7 @@
|
|||
#include <power_management.h>
|
||||
|
||||
#include "TaskAprsIs.h"
|
||||
#include "TaskBeacon.h"
|
||||
#include "TaskDisplay.h"
|
||||
#include "TaskEth.h"
|
||||
#include "TaskFTP.h"
|
||||
|
@ -19,7 +20,7 @@
|
|||
#include "TaskWifi.h"
|
||||
#include "project_configuration.h"
|
||||
|
||||
#define VERSION "22.11.2"
|
||||
#define VERSION "22.14.0"
|
||||
#define MODULE_NAME "Main"
|
||||
|
||||
String create_lat_aprs(double lat);
|
||||
|
@ -43,6 +44,7 @@ FTPTask ftpTask;
|
|||
MQTTTask mqttTask(toMQTT);
|
||||
AprsIsTask aprsIsTask(toAprsIs);
|
||||
RouterTask routerTask(fromModem, toModem, toAprsIs, toMQTT);
|
||||
BeaconTask beaconTask(toModem, toAprsIs);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
@ -95,7 +97,11 @@ void setup() {
|
|||
}
|
||||
powerManagement.activateLoRa();
|
||||
powerManagement.activateOLED();
|
||||
powerManagement.deactivateGPS();
|
||||
if (userConfig.beacon.use_gps) {
|
||||
powerManagement.activateGPS();
|
||||
} else {
|
||||
powerManagement.deactivateGPS();
|
||||
}
|
||||
}
|
||||
|
||||
LoRaSystem.setBoardConfig(boardConfig);
|
||||
|
@ -112,24 +118,33 @@ void setup() {
|
|||
LoRaSystem.getTaskManager().addTask(&displayTask);
|
||||
LoRaSystem.getTaskManager().addTask(&modemTask);
|
||||
LoRaSystem.getTaskManager().addTask(&routerTask);
|
||||
LoRaSystem.getTaskManager().addTask(&beaconTask);
|
||||
|
||||
if (userConfig.aprs_is.active) {
|
||||
if (boardConfig->Type == eETH_BOARD && !userConfig.wifi.active) {
|
||||
LoRaSystem.getTaskManager().addAlwaysRunTask(ðTask);
|
||||
}
|
||||
if (userConfig.wifi.active) {
|
||||
LoRaSystem.getTaskManager().addAlwaysRunTask(&wifiTask);
|
||||
}
|
||||
bool tcpip = false;
|
||||
|
||||
if (userConfig.wifi.active) {
|
||||
LoRaSystem.getTaskManager().addAlwaysRunTask(&wifiTask);
|
||||
tcpip = true;
|
||||
}
|
||||
if (boardConfig->Type == eETH_BOARD) {
|
||||
LoRaSystem.getTaskManager().addAlwaysRunTask(ðTask);
|
||||
tcpip = true;
|
||||
}
|
||||
|
||||
if (tcpip) {
|
||||
LoRaSystem.getTaskManager().addTask(&otaTask);
|
||||
LoRaSystem.getTaskManager().addTask(&ntpTask);
|
||||
if (userConfig.ftp.active) {
|
||||
LoRaSystem.getTaskManager().addTask(&ftpTask);
|
||||
}
|
||||
LoRaSystem.getTaskManager().addTask(&aprsIsTask);
|
||||
}
|
||||
|
||||
if (userConfig.mqtt.active) {
|
||||
LoRaSystem.getTaskManager().addTask(&mqttTask);
|
||||
if (userConfig.aprs_is.active) {
|
||||
LoRaSystem.getTaskManager().addTask(&aprsIsTask);
|
||||
}
|
||||
|
||||
if (userConfig.mqtt.active) {
|
||||
LoRaSystem.getTaskManager().addTask(&mqttTask);
|
||||
}
|
||||
}
|
||||
|
||||
LoRaSystem.getTaskManager().setup(LoRaSystem);
|
||||
|
@ -176,27 +191,3 @@ void loop() {
|
|||
syslogSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
String create_lat_aprs(double lat) {
|
||||
char str[20];
|
||||
char n_s = 'N';
|
||||
if (lat < 0) {
|
||||
n_s = 'S';
|
||||
}
|
||||
lat = std::abs(lat);
|
||||
sprintf(str, "%02d%05.2f%c", (int)lat, (lat - (double)((int)lat)) * 60.0, n_s);
|
||||
String lat_str(str);
|
||||
return lat_str;
|
||||
}
|
||||
|
||||
String create_long_aprs(double lng) {
|
||||
char str[20];
|
||||
char e_w = 'E';
|
||||
if (lng < 0) {
|
||||
e_w = 'W';
|
||||
}
|
||||
lng = std::abs(lng);
|
||||
sprintf(str, "%03d%05.2f%c", (int)lng, (lng - (double)((int)lng)) * 60.0, e_w);
|
||||
String lng_str(str);
|
||||
return lng_str;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ enum TaskNames
|
|||
TaskWifi,
|
||||
TaskRouter,
|
||||
TaskMQTT,
|
||||
TaskBeacon,
|
||||
TaskSize
|
||||
};
|
||||
|
||||
|
@ -24,5 +25,6 @@ enum TaskNames
|
|||
#define TASK_WIFI "WifiTask"
|
||||
#define TASK_ROUTER "RouterTask"
|
||||
#define TASK_MQTT "MQTTTask"
|
||||
#define TASK_BEACON "BeaconTask"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
#include <logger.h>
|
||||
|
||||
#include <OneButton.h>
|
||||
#include <TimeLib.h>
|
||||
|
||||
#include "Task.h"
|
||||
#include "TaskBeacon.h"
|
||||
#include "project_configuration.h"
|
||||
|
||||
BeaconTask::BeaconTask(TaskQueue<std::shared_ptr<APRSMessage>> &toModem, TaskQueue<std::shared_ptr<APRSMessage>> &toAprsIs) : Task(TASK_BEACON, TaskBeacon), _toModem(toModem), _toAprsIs(toAprsIs), _ss(1), _useGps(false) {
|
||||
}
|
||||
|
||||
BeaconTask::~BeaconTask() {
|
||||
}
|
||||
|
||||
OneButton BeaconTask::_userButton;
|
||||
bool BeaconTask::_send_update;
|
||||
uint BeaconTask::_instances;
|
||||
|
||||
void BeaconTask::pushButton() {
|
||||
_send_update = true;
|
||||
}
|
||||
|
||||
bool BeaconTask::setup(System &system) {
|
||||
if (_instances++ == 0 && system.getBoardConfig()->Button > 0) {
|
||||
_userButton = OneButton(system.getBoardConfig()->Button, true, true);
|
||||
_userButton.attachClick(pushButton);
|
||||
_send_update = false;
|
||||
}
|
||||
|
||||
_useGps = system.getUserConfig()->beacon.use_gps;
|
||||
|
||||
if (_useGps) {
|
||||
if (system.getBoardConfig()->GpsRx != 0) {
|
||||
_ss.begin(9600, SERIAL_8N1, system.getBoardConfig()->GpsTx, system.getBoardConfig()->GpsRx);
|
||||
} else {
|
||||
system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_INFO, getName(), "NO GPS found.");
|
||||
_useGps = false;
|
||||
}
|
||||
}
|
||||
// setup beacon
|
||||
_beacon_timer.setTimeout(system.getUserConfig()->beacon.timeout * 60 * 1000);
|
||||
|
||||
_beaconMsg = std::shared_ptr<APRSMessage>(new APRSMessage());
|
||||
_beaconMsg->setSource(system.getUserConfig()->callsign);
|
||||
_beaconMsg->setDestination("APLG01");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BeaconTask::loop(System &system) {
|
||||
if (_useGps) {
|
||||
while (_ss.available() > 0) {
|
||||
char c = _ss.read();
|
||||
_gps.encode(c);
|
||||
}
|
||||
}
|
||||
|
||||
_userButton.tick();
|
||||
|
||||
// check for beacon
|
||||
if (_beacon_timer.check() || _send_update) {
|
||||
if (sendBeacon(system)) {
|
||||
_send_update = false;
|
||||
_beacon_timer.start();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t diff = _beacon_timer.getTriggerTimeInSec();
|
||||
_stateInfo = "beacon " + String(uint32_t(diff / 600)) + String(uint32_t(diff / 60) % 10) + ":" + String(uint32_t(diff / 10) % 6) + String(uint32_t(diff % 10));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String create_lat_aprs(double lat) {
|
||||
char str[20];
|
||||
char n_s = 'N';
|
||||
if (lat < 0) {
|
||||
n_s = 'S';
|
||||
}
|
||||
lat = std::abs(lat);
|
||||
sprintf(str, "%02d%05.2f%c", (int)lat, (lat - (double)((int)lat)) * 60.0, n_s);
|
||||
String lat_str(str);
|
||||
return lat_str;
|
||||
}
|
||||
|
||||
String create_long_aprs(double lng) {
|
||||
char str[20];
|
||||
char e_w = 'E';
|
||||
if (lng < 0) {
|
||||
e_w = 'W';
|
||||
}
|
||||
lng = std::abs(lng);
|
||||
sprintf(str, "%03d%05.2f%c", (int)lng, (lng - (double)((int)lng)) * 60.0, e_w);
|
||||
String lng_str(str);
|
||||
return lng_str;
|
||||
}
|
||||
|
||||
bool BeaconTask::sendBeacon(System &system) {
|
||||
double lat = system.getUserConfig()->beacon.positionLatitude;
|
||||
double lng = system.getUserConfig()->beacon.positionLongitude;
|
||||
|
||||
if (_useGps) {
|
||||
if (_gps.location.isUpdated()) {
|
||||
lat = _gps.location.lat();
|
||||
lng = _gps.location.lng();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
_beaconMsg->getBody()->setData(String("=") + create_lat_aprs(lat) + "L" + create_long_aprs(lng) + "&" + system.getUserConfig()->beacon.message);
|
||||
|
||||
system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_INFO, getName(), "[%s] %s", timeString().c_str(), _beaconMsg->encode().c_str());
|
||||
|
||||
if (system.getUserConfig()->aprs_is.active) {
|
||||
_toAprsIs.addElement(_beaconMsg);
|
||||
}
|
||||
|
||||
if (system.getUserConfig()->digi.beacon) {
|
||||
_toModem.addElement(_beaconMsg);
|
||||
}
|
||||
|
||||
system.getDisplay().addFrame(std::shared_ptr<DisplayFrame>(new TextFrame("BEACON", _beaconMsg->toString())));
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef TASK_BEACON_H_
|
||||
#define TASK_BEACON_H_
|
||||
|
||||
#include <OneButton.h>
|
||||
#include <TinyGPS++.h>
|
||||
|
||||
#include <APRSMessage.h>
|
||||
#include <TaskMQTT.h>
|
||||
#include <TaskManager.h>
|
||||
|
||||
class BeaconTask : public Task {
|
||||
public:
|
||||
BeaconTask(TaskQueue<std::shared_ptr<APRSMessage>> &toModem, TaskQueue<std::shared_ptr<APRSMessage>> &toAprsIs);
|
||||
virtual ~BeaconTask();
|
||||
|
||||
virtual bool setup(System &system) override;
|
||||
virtual bool loop(System &system) override;
|
||||
bool sendBeacon(System &system);
|
||||
|
||||
private:
|
||||
TaskQueue<std::shared_ptr<APRSMessage>> &_toModem;
|
||||
TaskQueue<std::shared_ptr<APRSMessage>> &_toAprsIs;
|
||||
|
||||
std::shared_ptr<APRSMessage> _beaconMsg;
|
||||
Timer _beacon_timer;
|
||||
|
||||
HardwareSerial _ss;
|
||||
TinyGPSPlus _gps;
|
||||
bool _useGps;
|
||||
|
||||
static uint _instances;
|
||||
static OneButton _userButton;
|
||||
static bool _send_update;
|
||||
static void pushButton();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -39,19 +39,24 @@ bool ModemTask::setup(System &system) {
|
|||
bool ModemTask::loop(System &system) {
|
||||
if (_lora_aprs.checkMessage()) {
|
||||
std::shared_ptr<APRSMessage> msg = _lora_aprs.getMessage();
|
||||
system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] Received packet '%s' with RSSI %d and SNR %f", timeString().c_str(), msg->toString().c_str(), _lora_aprs.packetRssi(), _lora_aprs.packetSnr());
|
||||
system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] Received packet '%s' with RSSI %ddBm, SNR %.2fdB and FreqErr %dHz", timeString().c_str(), msg->toString().c_str(), _lora_aprs.packetRssi(), _lora_aprs.packetSnr(), -_lora_aprs.packetFrequencyError());
|
||||
_fromModem.addElement(msg);
|
||||
system.getDisplay().addFrame(std::shared_ptr<DisplayFrame>(new TextFrame("LoRa", msg->toString().c_str())));
|
||||
}
|
||||
|
||||
if (!_toModem.empty()) {
|
||||
std::shared_ptr<APRSMessage> msg = _toModem.getElement();
|
||||
if (system.getUserConfig()->lora.tx_enable) {
|
||||
system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] Transmitting packet '%s'", timeString().c_str(), msg->toString().c_str());
|
||||
_lora_aprs.sendMessage(msg);
|
||||
system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] TX done", timeString().c_str());
|
||||
if (_lora_aprs.rxSignalDetected()) {
|
||||
system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] RX signal detected. Waiting TX", timeString().c_str());
|
||||
delay(1000);
|
||||
} else {
|
||||
system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] NOT transmitting packet as TX is not enabled '%s'", timeString().c_str(), msg->toString().c_str());
|
||||
std::shared_ptr<APRSMessage> msg = _toModem.getElement();
|
||||
if (system.getUserConfig()->lora.tx_enable) {
|
||||
system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] Transmitting packet '%s'", timeString().c_str(), msg->toString().c_str());
|
||||
_lora_aprs.sendMessage(msg);
|
||||
system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] TX done", timeString().c_str());
|
||||
} else {
|
||||
system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] NOT transmitting packet as TX is not enabled '%s'", timeString().c_str(), msg->toString().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
#include "TaskRouter.h"
|
||||
#include "project_configuration.h"
|
||||
|
||||
String create_lat_aprs(double lat);
|
||||
String create_long_aprs(double lng);
|
||||
|
||||
RouterTask::RouterTask(TaskQueue<std::shared_ptr<APRSMessage>> &fromModem, TaskQueue<std::shared_ptr<APRSMessage>> &toModem, TaskQueue<std::shared_ptr<APRSMessage>> &toAprsIs, TaskQueue<std::shared_ptr<APRSMessage>> &toMQTT) : Task(TASK_ROUTER, TaskRouter), _fromModem(fromModem), _toModem(toModem), _toAprsIs(toAprsIs), _toMQTT(toMQTT) {
|
||||
}
|
||||
|
||||
|
@ -16,15 +13,6 @@ RouterTask::~RouterTask() {
|
|||
}
|
||||
|
||||
bool RouterTask::setup(System &system) {
|
||||
_beacon_timer.setTimeout(system.getUserConfig()->beacon.timeout * 60 * 1000);
|
||||
|
||||
_beaconMsg = std::shared_ptr<APRSMessage>(new APRSMessage());
|
||||
_beaconMsg->setSource(system.getUserConfig()->callsign);
|
||||
_beaconMsg->setDestination("APLG01");
|
||||
String lat = create_lat_aprs(system.getUserConfig()->beacon.positionLatitude);
|
||||
String lng = create_long_aprs(system.getUserConfig()->beacon.positionLongitude);
|
||||
_beaconMsg->getBody()->setData(String("=") + lat + "L" + lng + "&" + system.getUserConfig()->beacon.message);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -78,23 +66,7 @@ bool RouterTask::loop(System &system) {
|
|||
}
|
||||
}
|
||||
|
||||
// check for beacon
|
||||
if (_beacon_timer.check()) {
|
||||
system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_INFO, getName(), "[%s] %s", timeString().c_str(), _beaconMsg->encode().c_str());
|
||||
|
||||
if (system.getUserConfig()->aprs_is.active)
|
||||
_toAprsIs.addElement(_beaconMsg);
|
||||
|
||||
if (system.getUserConfig()->digi.beacon) {
|
||||
_toModem.addElement(_beaconMsg);
|
||||
}
|
||||
|
||||
system.getDisplay().addFrame(std::shared_ptr<DisplayFrame>(new TextFrame("BEACON", _beaconMsg->toString())));
|
||||
_beacon_timer.start();
|
||||
}
|
||||
|
||||
uint32_t diff = _beacon_timer.getTriggerTimeInSec();
|
||||
_stateInfo = "beacon " + String(uint32_t(diff / 600)) + String(uint32_t(diff / 60) % 10) + ":" + String(uint32_t(diff / 10) % 6) + String(uint32_t(diff % 10));
|
||||
_stateInfo = "Router done ";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -18,9 +18,6 @@ private:
|
|||
TaskQueue<std::shared_ptr<APRSMessage>> &_toModem;
|
||||
TaskQueue<std::shared_ptr<APRSMessage>> &_toAprsIs;
|
||||
TaskQueue<std::shared_ptr<APRSMessage>> &_toMQTT;
|
||||
|
||||
std::shared_ptr<APRSMessage> _beaconMsg;
|
||||
Timer _beacon_timer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -33,24 +33,29 @@ void ProjectConfigurationManagement::readProjectConfiguration(DynamicJsonDocumen
|
|||
JsonArray aps = data["wifi"]["AP"].as<JsonArray>();
|
||||
for (JsonVariant v : aps) {
|
||||
Configuration::Wifi::AP ap;
|
||||
ap.SSID = v["SSID"].as<String>();
|
||||
ap.password = v["password"].as<String>();
|
||||
if (v.containsKey("SSID"))
|
||||
ap.SSID = v["SSID"].as<String>();
|
||||
if (v.containsKey("password"))
|
||||
ap.password = v["password"].as<String>();
|
||||
conf.wifi.APs.push_back(ap);
|
||||
}
|
||||
if (data.containsKey("beacon") && data["beacon"].containsKey("message"))
|
||||
conf.beacon.message = data["beacon"]["message"].as<String>();
|
||||
conf.beacon.positionLatitude = data["beacon"]["position"]["latitude"] | 0.0;
|
||||
conf.beacon.positionLongitude = data["beacon"]["position"]["longitude"] | 0.0;
|
||||
conf.beacon.use_gps = data["beacon"]["use_gps"] | false;
|
||||
conf.beacon.timeout = data["beacon"]["timeout"] | 15;
|
||||
conf.aprs_is.active = data["aprs_is"]["active"] | true;
|
||||
|
||||
if (data.containsKey("aprs_is") && data["aprs_is"].containsKey("passcode"))
|
||||
conf.aprs_is.passcode = data["aprs_is"]["passcode"].as<String>();
|
||||
if (data.containsKey("aprs_is") && data["aprs_is"].containsKey("server"))
|
||||
conf.aprs_is.server = data["aprs_is"]["server"].as<String>();
|
||||
conf.aprs_is.port = data["aprs_is"]["port"] | 14580;
|
||||
|
||||
conf.digi.active = data["digi"]["active"] | false;
|
||||
conf.digi.beacon = data["digi"]["beacon"] | false;
|
||||
conf.digi.active = data["digi"]["active"] | false;
|
||||
conf.digi.beacon = data["digi"]["beacon"] | false;
|
||||
|
||||
conf.lora.frequencyRx = data["lora"]["frequency_rx"] | 433775000;
|
||||
conf.lora.gainRx = data["lora"]["gain_rx"] | 0;
|
||||
conf.lora.frequencyTx = data["lora"]["frequency_tx"] | 433775000;
|
||||
|
@ -59,6 +64,7 @@ void ProjectConfigurationManagement::readProjectConfiguration(DynamicJsonDocumen
|
|||
conf.lora.signalBandwidth = data["lora"]["signal_bandwidth"] | 125000;
|
||||
conf.lora.codingRate4 = data["lora"]["coding_rate4"] | 5;
|
||||
conf.lora.tx_enable = data["lora"]["tx_enable"] | true;
|
||||
|
||||
conf.display.alwaysOn = data["display"]["always_on"] | true;
|
||||
conf.display.timeout = data["display"]["timeout"] | 10;
|
||||
conf.display.overwritePin = data["display"]["overwrite_pin"] | 0;
|
||||
|
@ -70,8 +76,10 @@ void ProjectConfigurationManagement::readProjectConfiguration(DynamicJsonDocumen
|
|||
JsonArray users = data["ftp"]["user"].as<JsonArray>();
|
||||
for (JsonVariant u : users) {
|
||||
Configuration::Ftp::User us;
|
||||
us.name = u["name"].as<String>();
|
||||
us.password = u["password"].as<String>();
|
||||
if (u.containsKey("name"))
|
||||
us.name = u["name"].as<String>();
|
||||
if (u.containsKey("password"))
|
||||
us.password = u["password"].as<String>();
|
||||
conf.ftp.users.push_back(us);
|
||||
}
|
||||
if (conf.ftp.users.empty()) {
|
||||
|
@ -80,19 +88,23 @@ void ProjectConfigurationManagement::readProjectConfiguration(DynamicJsonDocumen
|
|||
us.password = "ftp";
|
||||
conf.ftp.users.push_back(us);
|
||||
}
|
||||
if (data.containsKey("mqtt")) {
|
||||
conf.mqtt.active = data["mqtt"]["active"] | false;
|
||||
conf.mqtt.server = data["mqtt"]["server"].as<String>();
|
||||
conf.mqtt.port = data["mqtt"]["port"].as<uint16_t>();
|
||||
conf.mqtt.name = data["mqtt"]["name"].as<String>();
|
||||
|
||||
conf.mqtt.active = data["mqtt"]["active"] | false;
|
||||
if (data["mqtt"].containsKey("server"))
|
||||
conf.mqtt.server = data["mqtt"]["server"].as<String>();
|
||||
conf.mqtt.port = data["mqtt"]["port"] | 1883;
|
||||
if (data["mqtt"].containsKey("name"))
|
||||
conf.mqtt.name = data["mqtt"]["name"].as<String>();
|
||||
if (data["mqtt"].containsKey("password"))
|
||||
conf.mqtt.password = data["mqtt"]["password"].as<String>();
|
||||
conf.mqtt.topic = data["mqtt"]["topic"].as<String>();
|
||||
}
|
||||
if (data.containsKey("syslog")) {
|
||||
conf.syslog.active = data["syslog"]["active"] | true;
|
||||
if (data["mqtt"].containsKey("topic"))
|
||||
conf.mqtt.topic = data["mqtt"]["topic"].as<String>();
|
||||
|
||||
conf.syslog.active = data["syslog"]["active"] | true;
|
||||
if (data["syslog"].containsKey("server"))
|
||||
conf.syslog.server = data["syslog"]["server"].as<String>();
|
||||
conf.syslog.port = data["syslog"]["port"] | 514;
|
||||
}
|
||||
conf.syslog.port = data["syslog"]["port"] | 514;
|
||||
|
||||
if (data.containsKey("ntp_server"))
|
||||
conf.ntpServer = data["ntp_server"].as<String>();
|
||||
|
||||
|
@ -124,6 +136,7 @@ void ProjectConfigurationManagement::writeProjectConfiguration(Configuration &co
|
|||
data["beacon"]["message"] = conf.beacon.message;
|
||||
data["beacon"]["position"]["latitude"] = conf.beacon.positionLatitude;
|
||||
data["beacon"]["position"]["longitude"] = conf.beacon.positionLongitude;
|
||||
data["beacon"]["use_gps"] = conf.beacon.use_gps;
|
||||
data["beacon"]["timeout"] = conf.beacon.timeout;
|
||||
data["aprs_is"]["active"] = conf.aprs_is.active;
|
||||
data["aprs_is"]["passcode"] = conf.aprs_is.passcode;
|
||||
|
|
|
@ -48,12 +48,13 @@ public:
|
|||
|
||||
class Beacon {
|
||||
public:
|
||||
Beacon() : message("LoRa iGATE & Digi, Info: github.com/peterus/LoRa_APRS_iGate"), positionLatitude(0.0), positionLongitude(0.0), timeout(15) {
|
||||
Beacon() : message("LoRa iGATE & Digi, Info: github.com/peterus/LoRa_APRS_iGate"), positionLatitude(0.0), positionLongitude(0.0), use_gps(false), timeout(15) {
|
||||
}
|
||||
|
||||
String message;
|
||||
double positionLatitude;
|
||||
double positionLongitude;
|
||||
bool use_gps;
|
||||
int timeout;
|
||||
};
|
||||
|
||||
|
@ -125,12 +126,12 @@ public:
|
|||
MQTT() : active(false), server(""), port(1883), name(""), password(""), topic("LoraAPRS/Data") {
|
||||
}
|
||||
|
||||
bool active;
|
||||
String server;
|
||||
uint16_t port;
|
||||
String name;
|
||||
String password;
|
||||
String topic;
|
||||
bool active;
|
||||
String server;
|
||||
int port;
|
||||
String name;
|
||||
String password;
|
||||
String topic;
|
||||
};
|
||||
|
||||
class Syslog {
|
||||
|
|
Ładowanie…
Reference in New Issue