mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
Merge branch 'develop' of github.com:DJ2LS/FreeDATA into develop
This commit is contained in:
commit
8736613277
21 changed files with 491 additions and 539 deletions
|
@ -8,7 +8,7 @@ import "../../node_modules/gridstack/dist/gridstack.min.css";
|
||||||
import { GridStack } from "gridstack";
|
import { GridStack } from "gridstack";
|
||||||
import { useStateStore } from "../store/stateStore.js";
|
import { useStateStore } from "../store/stateStore.js";
|
||||||
const state = useStateStore(pinia);
|
const state = useStateStore(pinia);
|
||||||
import { setModemFrequency } from "../js/api";
|
import { setRadioParameters } from "../js/api";
|
||||||
import { saveLocalSettingsToConfig, settingsStore } from "../store/settingsStore";
|
import { saveLocalSettingsToConfig, settingsStore } from "../store/settingsStore";
|
||||||
|
|
||||||
import active_heard_stations from "./grid/grid_active_heard_stations.vue";
|
import active_heard_stations from "./grid/grid_active_heard_stations.vue";
|
||||||
|
@ -25,6 +25,7 @@ import grid_button from "./grid/button.vue";
|
||||||
import grid_ptt from "./grid/grid_ptt.vue";
|
import grid_ptt from "./grid/grid_ptt.vue";
|
||||||
import grid_mycall from "./grid/grid_mycall.vue";
|
import grid_mycall from "./grid/grid_mycall.vue";
|
||||||
import grid_stop from "./grid/grid_stop.vue";
|
import grid_stop from "./grid/grid_stop.vue";
|
||||||
|
import grid_tune from "./grid/grid_tune.vue";
|
||||||
import grid_CQ_btn from "./grid/grid_CQ.vue";
|
import grid_CQ_btn from "./grid/grid_CQ.vue";
|
||||||
import grid_ping from "./grid/grid_ping.vue";
|
import grid_ping from "./grid/grid_ping.vue";
|
||||||
import grid_freq from "./grid/grid_frequency.vue";
|
import grid_freq from "./grid/grid_frequency.vue";
|
||||||
|
@ -226,6 +227,15 @@ new gridWidget(
|
||||||
"Other",
|
"Other",
|
||||||
15,
|
15,
|
||||||
),
|
),
|
||||||
|
new gridWidget(
|
||||||
|
grid_tune,
|
||||||
|
{ x: 0, y: 0, w: 2, h: 13 },
|
||||||
|
"Tune widget",
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
"Audio",
|
||||||
|
18,
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
//New new widget ID should be 18
|
//New new widget ID should be 18
|
||||||
|
@ -233,12 +243,20 @@ new gridWidget(
|
||||||
|
|
||||||
function updateFrequencyAndApply(frequency) {
|
function updateFrequencyAndApply(frequency) {
|
||||||
state.new_frequency = frequency;
|
state.new_frequency = frequency;
|
||||||
setModemFrequency(state.new_frequency);
|
set_radio_parameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_hamlib_frequency_manually() {
|
function set_radio_parameters(){
|
||||||
setModemFrequency(state.new_frequency);
|
setRadioParameters(state.new_frequency, state.mode, state.rf_level);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function savePreset()
|
function savePreset()
|
||||||
{
|
{
|
||||||
settingsStore.local.grid_preset=settingsStore.local.grid_layout;
|
settingsStore.local.grid_preset=settingsStore.local.grid_layout;
|
||||||
|
@ -246,7 +264,7 @@ function savePreset()
|
||||||
}
|
}
|
||||||
function loadPreset()
|
function loadPreset()
|
||||||
{
|
{
|
||||||
|
|
||||||
clearAllItems();
|
clearAllItems();
|
||||||
settingsStore.local.grid_layout=settingsStore.local.grid_preset;
|
settingsStore.local.grid_layout=settingsStore.local.grid_preset;
|
||||||
restoreGridLayoutFromConfig();
|
restoreGridLayoutFromConfig();
|
||||||
|
@ -392,7 +410,7 @@ function addNewWidget2(componentToAdd :gridWidget,saveToConfig :boolean) {
|
||||||
if (saveToConfig)
|
if (saveToConfig)
|
||||||
saveGridLayout();
|
saveGridLayout();
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function remove(widget) {
|
function remove(widget) {
|
||||||
|
@ -677,7 +695,7 @@ function quickfill() {
|
||||||
aria-label="Close"
|
aria-label="Close"
|
||||||
></button>
|
></button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="offcanvas-body">
|
<div class="offcanvas-body">
|
||||||
|
@ -707,7 +725,7 @@ function quickfill() {
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-outline-success"
|
class="btn btn-sm btn-outline-success"
|
||||||
type="button"
|
type="button"
|
||||||
@click="set_hamlib_frequency_manually"
|
@click="updateFrequencyAndApply(state.new_frequency)"
|
||||||
v-bind:class="{
|
v-bind:class="{
|
||||||
disabled: state.hamlib_status === 'disconnected',
|
disabled: state.hamlib_status === 'disconnected',
|
||||||
}"
|
}"
|
||||||
|
|
|
@ -8,28 +8,9 @@ const state = useStateStore(pinia);
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="card w-100 h-100">
|
<div class="card w-100 h-100">
|
||||||
<div class="card-header p-0">
|
<div class="card-header p-0 mb-1">
|
||||||
<div class="dropdown">
|
<i class="bi bi-volume-up" style="font-size: 1rem"></i>
|
||||||
<button
|
<strong>Audio</strong>
|
||||||
class="btn btn-sm btn-outline-secondary dropdown-toggle"
|
|
||||||
type="button"
|
|
||||||
data-bs-toggle="dropdown"
|
|
||||||
aria-expanded="false"
|
|
||||||
></button>
|
|
||||||
<i class="bi bi-volume-up" style="font-size: 1rem"></i>
|
|
||||||
<strong>Audio</strong>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
data-bs-toggle="modal"
|
|
||||||
data-bs-target="#audioModal"
|
|
||||||
href="#"
|
|
||||||
>Tune</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body pt-0 pb-0">
|
<div class="card-body pt-0 pb-0">
|
||||||
<div class="container-wide">
|
<div class="container-wide">
|
||||||
|
|
|
@ -1,18 +1,14 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { setActivePinia } from "pinia";
|
import { setActivePinia } from "pinia";
|
||||||
import pinia from "../../store/index";
|
import pinia from "../../store/index";
|
||||||
import { setModemRigMode, setModemRigPowerLvl } from "../../js/api";
|
import { setRadioParameters } from "../../js/api";
|
||||||
setActivePinia(pinia);
|
setActivePinia(pinia);
|
||||||
|
|
||||||
import { useStateStore } from "../../store/stateStore.js";
|
import { useStateStore } from "../../store/stateStore.js";
|
||||||
const state = useStateStore(pinia);
|
const state = useStateStore(pinia);
|
||||||
|
|
||||||
function set_hamlib_mode() {
|
function set_radio_parameters() {
|
||||||
setModemRigMode(state.mode);
|
setRadioParameters(state.frequency, state.mode, state.rf_level);
|
||||||
}
|
|
||||||
|
|
||||||
function set_hamlib_rf_level() {
|
|
||||||
setModemRigPowerLvl(state.rf_level);
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -51,7 +47,7 @@ function set_hamlib_rf_level() {
|
||||||
<select
|
<select
|
||||||
class="form-control"
|
class="form-control"
|
||||||
v-model="state.mode"
|
v-model="state.mode"
|
||||||
@click="set_hamlib_mode()"
|
@click="set_radio_parameters()"
|
||||||
v-bind:class="{
|
v-bind:class="{
|
||||||
disabled: state.hamlib_status === 'disconnected',
|
disabled: state.hamlib_status === 'disconnected',
|
||||||
}"
|
}"
|
||||||
|
@ -73,7 +69,7 @@ function set_hamlib_rf_level() {
|
||||||
<select
|
<select
|
||||||
class="form-control"
|
class="form-control"
|
||||||
v-model="state.rf_level"
|
v-model="state.rf_level"
|
||||||
@click="set_hamlib_rf_level()"
|
@click="set_radio_parameters()"
|
||||||
v-bind:class="{
|
v-bind:class="{
|
||||||
disabled: state.hamlib_status === 'disconnected',
|
disabled: state.hamlib_status === 'disconnected',
|
||||||
}"
|
}"
|
||||||
|
|
18
gui/src/components/grid/grid_tune.vue
Normal file
18
gui/src/components/grid/grid_tune.vue
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { setActivePinia } from "pinia";
|
||||||
|
import pinia from "../../store/index";
|
||||||
|
setActivePinia(pinia);
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<a
|
||||||
|
class="btn btn-outline-primary d-flex border justify-content-center align-items-center object-fill rounded w-100 h-100"
|
||||||
|
id="stop_transmission_connection"
|
||||||
|
data-bs-trigger="hover"
|
||||||
|
data-bs-html="false"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-target="#audioModal"
|
||||||
|
title="Tune"
|
||||||
|
>
|
||||||
|
<h5>Tune</h5>
|
||||||
|
</a>
|
||||||
|
</template>
|
|
@ -6,23 +6,15 @@ setActivePinia(pinia);
|
||||||
import { useStateStore } from "../store/stateStore.js";
|
import { useStateStore } from "../store/stateStore.js";
|
||||||
const state = useStateStore(pinia);
|
const state = useStateStore(pinia);
|
||||||
|
|
||||||
import { setModemRigMode, setModemRigPowerLvl } from "../js/api";
|
import { setRadioParameters } from "../js/api";
|
||||||
|
|
||||||
function updateFrequencyAndApply(frequency) {
|
function updateFrequencyAndApply(frequency) {
|
||||||
//state.new_frequency = frequency;
|
state.new_frequency = frequency;
|
||||||
//set_frequency(state.new_frequency);
|
set_radio_parameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_hamlib_frequency_manually() {
|
function set_radio_parameters() {
|
||||||
//set_frequency(state.new_frequency);
|
setRadioParameters(state.new_frequency, state.mode, state.rf_level);
|
||||||
}
|
|
||||||
|
|
||||||
function set_hamlib_mode() {
|
|
||||||
setModemRigMode(state.mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
function set_hamlib_rf_level() {
|
|
||||||
setModemRigPowerLvl(state.rf_level);
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -102,7 +94,7 @@ function set_hamlib_rf_level() {
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-outline-success"
|
class="btn btn-sm btn-outline-success"
|
||||||
type="button"
|
type="button"
|
||||||
@click="set_hamlib_frequency_manually"
|
@click="updateFrequencyAndApply(state.new_frequency)"
|
||||||
v-bind:class="{
|
v-bind:class="{
|
||||||
disabled: state.hamlib_status === 'disconnected',
|
disabled: state.hamlib_status === 'disconnected',
|
||||||
}"
|
}"
|
||||||
|
@ -215,7 +207,7 @@ function set_hamlib_rf_level() {
|
||||||
<select
|
<select
|
||||||
class="form-control"
|
class="form-control"
|
||||||
v-model="state.mode"
|
v-model="state.mode"
|
||||||
@click="set_hamlib_mode()"
|
@click="set_radio_parameters()"
|
||||||
v-bind:class="{
|
v-bind:class="{
|
||||||
disabled: state.hamlib_status === 'disconnected',
|
disabled: state.hamlib_status === 'disconnected',
|
||||||
}"
|
}"
|
||||||
|
@ -237,7 +229,7 @@ function set_hamlib_rf_level() {
|
||||||
<select
|
<select
|
||||||
class="form-control"
|
class="form-control"
|
||||||
v-model="state.rf_level"
|
v-model="state.rf_level"
|
||||||
@click="set_hamlib_rf_level()"
|
@click="set_radio_parameters()"
|
||||||
v-bind:class="{
|
v-bind:class="{
|
||||||
disabled: state.hamlib_status === 'disconnected',
|
disabled: state.hamlib_status === 'disconnected',
|
||||||
}"
|
}"
|
||||||
|
|
|
@ -8,7 +8,7 @@ setActivePinia(pinia);
|
||||||
import { useChatStore } from "../store/chatStore.js";
|
import { useChatStore } from "../store/chatStore.js";
|
||||||
const chat = useChatStore(pinia);
|
const chat = useChatStore(pinia);
|
||||||
|
|
||||||
import { settingsStore as settings } from "../store/settingsStore.js";
|
import { settingsStore as settings, onChange } from "../store/settingsStore.js";
|
||||||
|
|
||||||
import { sendModemTestFrame } from "../js/api";
|
import { sendModemTestFrame } from "../js/api";
|
||||||
|
|
||||||
|
@ -19,16 +19,6 @@ import {
|
||||||
|
|
||||||
import main_startup_check from "./main_startup_check.vue";
|
import main_startup_check from "./main_startup_check.vue";
|
||||||
|
|
||||||
function set_tx_audio_level() {
|
|
||||||
saveSettingsToFile();
|
|
||||||
setTxAudioLevel(settings.tx_audio_level);
|
|
||||||
}
|
|
||||||
|
|
||||||
function set_rx_audio_level() {
|
|
||||||
saveSettingsToFile();
|
|
||||||
setRxAudioLevel(settings.rx_audio_level);
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteChat() {
|
function deleteChat() {
|
||||||
//console.log(chat.selectedCallsign)
|
//console.log(chat.selectedCallsign)
|
||||||
deleteChatByCallsign(chat.selectedCallsign);
|
deleteChatByCallsign(chat.selectedCallsign);
|
||||||
|
@ -1186,6 +1176,10 @@ const transmissionSpeedChartDataMessageInfo = computed(() => ({
|
||||||
></button>
|
></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
<div class="alert alert-info" role="alert">
|
||||||
|
Adjust audio levels. Value in dB. Default is <strong>0</strong>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="input-group input-group-sm mb-1">
|
<div class="input-group input-group-sm mb-1">
|
||||||
<span class="input-group-text">Test-Frame</span>
|
<span class="input-group-text">Test-Frame</span>
|
||||||
<button
|
<button
|
||||||
|
@ -1199,7 +1193,9 @@ const transmissionSpeedChartDataMessageInfo = computed(() => ({
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group input-group-sm mb-1">
|
<div class="input-group input-group-sm mb-1">
|
||||||
<span class="input-group-text">RX Level</span>
|
<span class="input-group-text">RX Level</span>
|
||||||
<span class="input-group-text">{{ settings.rx_audio_level }}</span>
|
<span class="input-group-text">{{
|
||||||
|
settings.remote.AUDIO.rx_audio_level
|
||||||
|
}}</span>
|
||||||
<span class="input-group-text w-75">
|
<span class="input-group-text w-75">
|
||||||
<input
|
<input
|
||||||
type="range"
|
type="range"
|
||||||
|
@ -1208,13 +1204,15 @@ const transmissionSpeedChartDataMessageInfo = computed(() => ({
|
||||||
max="20"
|
max="20"
|
||||||
step="1"
|
step="1"
|
||||||
id="audioLevelRX"
|
id="audioLevelRX"
|
||||||
@click="set_rx_audio_level()"
|
@change="onChange"
|
||||||
v-model="settings.rx_audio_level"
|
v-model.number="settings.remote.AUDIO.rx_audio_level"
|
||||||
/></span>
|
/></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group input-group-sm mb-1">
|
<div class="input-group input-group-sm mb-1">
|
||||||
<span class="input-group-text">TX Level</span>
|
<span class="input-group-text">TX Level</span>
|
||||||
<span class="input-group-text">{{ settings.tx_audio_level }}</span>
|
<span class="input-group-text">{{
|
||||||
|
settings.remote.AUDIO.tx_audio_level
|
||||||
|
}}</span>
|
||||||
<span class="input-group-text w-75">
|
<span class="input-group-text w-75">
|
||||||
<input
|
<input
|
||||||
type="range"
|
type="range"
|
||||||
|
@ -1223,8 +1221,8 @@ const transmissionSpeedChartDataMessageInfo = computed(() => ({
|
||||||
max="20"
|
max="20"
|
||||||
step="1"
|
step="1"
|
||||||
id="audioLevelTX"
|
id="audioLevelTX"
|
||||||
@click="set_tx_audio_level()"
|
@change="onChange"
|
||||||
v-model="settings.tx_audio_level"
|
v-model.number="settings.remote.AUDIO.tx_audio_level"
|
||||||
/></span>
|
/></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,7 +3,6 @@ import settings_station from "./settings_station.vue";
|
||||||
import settings_gui from "./settings_gui.vue";
|
import settings_gui from "./settings_gui.vue";
|
||||||
import settings_chat from "./settings_chat.vue";
|
import settings_chat from "./settings_chat.vue";
|
||||||
import settings_rigcontrol from "./settings_rigcontrol.vue";
|
import settings_rigcontrol from "./settings_rigcontrol.vue";
|
||||||
import settings_hamlib from "./settings_hamlib.vue";
|
|
||||||
import settings_modem from "./settings_modem.vue";
|
import settings_modem from "./settings_modem.vue";
|
||||||
import settings_web from "./settings_web.vue";
|
import settings_web from "./settings_web.vue";
|
||||||
import settings_exp from "./settings_exp.vue";
|
import settings_exp from "./settings_exp.vue";
|
||||||
|
@ -76,20 +75,7 @@ import settings_exp from "./settings_exp.vue";
|
||||||
Rig Control
|
Rig Control
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button
|
|
||||||
class="nav-link"
|
|
||||||
id="hamlib-tab"
|
|
||||||
data-bs-toggle="tab"
|
|
||||||
data-bs-target="#hamlib"
|
|
||||||
type="button"
|
|
||||||
role="tab"
|
|
||||||
aria-controls="profile"
|
|
||||||
aria-selected="false"
|
|
||||||
>
|
|
||||||
Hamlib
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item" role="presentation">
|
<li class="nav-item" role="presentation">
|
||||||
<button
|
<button
|
||||||
class="nav-link"
|
class="nav-link"
|
||||||
|
@ -180,15 +166,6 @@ import settings_exp from "./settings_exp.vue";
|
||||||
<settings_rigcontrol />
|
<settings_rigcontrol />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
|
||||||
class="tab-pane"
|
|
||||||
id="hamlib"
|
|
||||||
role="tabpanel"
|
|
||||||
aria-labelledby="hamlib-tab"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
<settings_hamlib />
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
class="tab-pane"
|
class="tab-pane"
|
||||||
id="modem"
|
id="modem"
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { settingsStore as settings, onChange } from "../store/settingsStore.js";
|
import { settingsStore as settings, onChange } from "../store/settingsStore.js";
|
||||||
|
import settings_hamlib from "./settings_hamlib.vue";
|
||||||
|
import settings_tci from "./settings_tci.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -23,29 +25,54 @@ import { settingsStore as settings, onChange } from "../store/settingsStore.js";
|
||||||
|
|
||||||
<hr class="m-2" />
|
<hr class="m-2" />
|
||||||
|
|
||||||
<div class="input-group input-group-sm mb-1">
|
<nav>
|
||||||
<span class="input-group-text" style="width: 180px">TCI IP Address</span>
|
<div class="nav nav-tabs" id="nav-tab" role="tablist">
|
||||||
<input
|
<button
|
||||||
type="text"
|
class="nav-link active"
|
||||||
class="form-control"
|
id="nav-home-tab"
|
||||||
placeholder="TCI IP"
|
data-bs-toggle="tab"
|
||||||
id="rigcontrol_tci_ip"
|
data-bs-target="#nav-hamlib"
|
||||||
aria-label="Device IP"
|
type="button"
|
||||||
@change="onChange"
|
role="tab"
|
||||||
v-model="settings.remote.TCI.tci_ip"
|
aria-controls="nav-home"
|
||||||
/>
|
aria-selected="true"
|
||||||
|
>
|
||||||
|
Hamlib
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="nav-link"
|
||||||
|
id="nav-profile-tab"
|
||||||
|
data-bs-toggle="tab"
|
||||||
|
data-bs-target="#nav-tci"
|
||||||
|
type="button"
|
||||||
|
role="tab"
|
||||||
|
aria-controls="nav-profile"
|
||||||
|
aria-selected="false"
|
||||||
|
>
|
||||||
|
TCI
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div class="tab-content" id="nav-tabContent">
|
||||||
|
<div
|
||||||
|
class="tab-pane fade show active"
|
||||||
|
id="nav-hamlib"
|
||||||
|
role="tabpanel"
|
||||||
|
aria-labelledby="nav-hamlib-tab"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<settings_hamlib />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="tab-pane fade"
|
||||||
|
id="nav-tci"
|
||||||
|
role="tabpanel"
|
||||||
|
aria-labelledby="nav-tci-tab"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<settings_tci />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-group input-group-sm mb-1">
|
<hr class="m-2" />
|
||||||
<span class="input-group-text" style="width: 180px">TCI port</span>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
placeholder="TCI port"
|
|
||||||
id="rigcontrol_tci_port"
|
|
||||||
aria-label="Device Port"
|
|
||||||
@change="onChange"
|
|
||||||
v-model="settings.remote.TCI.tci_port"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
34
gui/src/components/settings_tci.vue
Normal file
34
gui/src/components/settings_tci.vue
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { settingsStore as settings, onChange } from "../store/settingsStore.js";
|
||||||
|
import { serialDeviceOptions } from "../js/deviceFormHelper";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<hr class="m-2" />
|
||||||
|
|
||||||
|
<div class="input-group input-group-sm mb-1">
|
||||||
|
<span class="input-group-text" style="width: 180px">TCI IP Address</span>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
placeholder="TCI IP"
|
||||||
|
id="rigcontrol_tci_ip"
|
||||||
|
aria-label="Device IP"
|
||||||
|
@change="onChange"
|
||||||
|
v-model="settings.remote.TCI.tci_ip"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group input-group-sm mb-1">
|
||||||
|
<span class="input-group-text" style="width: 180px">TCI port</span>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
placeholder="TCI port"
|
||||||
|
id="rigcontrol_tci_port"
|
||||||
|
aria-label="Device Port"
|
||||||
|
@change="onChange"
|
||||||
|
v-model="settings.remote.TCI.tci_port"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -117,12 +117,13 @@ export function getModemState() {
|
||||||
return apiGet("/modem/state");
|
return apiGet("/modem/state");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setModemFrequency(newFrequency) {
|
export function setRadioParameters(frequency, mode, rf_level) {
|
||||||
console.error("setModemFrequency needs implemented");
|
return apiPost("/radio", {
|
||||||
|
radio_frequency: frequency,
|
||||||
|
radio_mode: mode,
|
||||||
|
radio_rf_level: rf_level,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
export function setModemRigMode(mode) {
|
export function getRadioStatus() {
|
||||||
console.error("setModemRigMode needs implemented");
|
return apiGet("/radio");
|
||||||
}
|
|
||||||
export function setModemRigPowerLvl(power) {
|
|
||||||
console.error("setModemRigPowerLvl needs implemented");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,12 @@ export function stateDispatcher(data) {
|
||||||
stateStore.dbfs_level_percent = Math.round(
|
stateStore.dbfs_level_percent = Math.round(
|
||||||
Math.pow(10, data["audio_dbfs"] / 20) * 100,
|
Math.pow(10, data["audio_dbfs"] / 20) * 100,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
stateStore.s_meter_strength_raw = Math.round(data["s_meter_strength"]);
|
||||||
|
stateStore.s_meter_strength_percent = Math.round(
|
||||||
|
Math.pow(10, data["s_meter_strength"] / 20) * 100,
|
||||||
|
);
|
||||||
|
|
||||||
stateStore.channel_busy_slot = data["channel_busy_slot"];
|
stateStore.channel_busy_slot = data["channel_busy_slot"];
|
||||||
stateStore.beacon_state = data["is_beacon_running"];
|
stateStore.beacon_state = data["is_beacon_running"];
|
||||||
stateStore.radio_status = data["radio_status"];
|
stateStore.radio_status = data["radio_status"];
|
||||||
|
|
|
@ -7,4 +7,4 @@ class TestCommand(TxCommand):
|
||||||
return self.frame_factory.build_test()
|
return self.frame_factory.build_test()
|
||||||
|
|
||||||
def get_tx_mode(self):
|
def get_tx_mode(self):
|
||||||
return codec2.FREEDV_MODE.datac13.value
|
return codec2.FREEDV_MODE.datac3
|
|
@ -43,7 +43,7 @@ class explorer():
|
||||||
version = str(self.app.MODEM_VERSION)
|
version = str(self.app.MODEM_VERSION)
|
||||||
bandwidth = str(self.config['MODEM']['enable_low_bandwidth_mode'])
|
bandwidth = str(self.config['MODEM']['enable_low_bandwidth_mode'])
|
||||||
beacon = str(self.states.is_beacon_running)
|
beacon = str(self.states.is_beacon_running)
|
||||||
strength = str(self.states.radio_strength)
|
strength = str(self.states.s_meter_strength)
|
||||||
|
|
||||||
log.info("[EXPLORER] publish", frequency=frequency, band=band, callsign=callsign, gridsquare=gridsquare, version=version, bandwidth=bandwidth)
|
log.info("[EXPLORER] publish", frequency=frequency, band=band, callsign=callsign, gridsquare=gridsquare, version=version, bandwidth=bandwidth)
|
||||||
|
|
||||||
|
|
|
@ -31,11 +31,12 @@ class RF:
|
||||||
|
|
||||||
log = structlog.get_logger("RF")
|
log = structlog.get_logger("RF")
|
||||||
|
|
||||||
def __init__(self, config, event_manager, fft_queue, service_queue, states) -> None:
|
def __init__(self, config, event_manager, fft_queue, service_queue, states, radio_manager) -> None:
|
||||||
self.config = config
|
self.config = config
|
||||||
self.service_queue = service_queue
|
self.service_queue = service_queue
|
||||||
self.states = states
|
self.states = states
|
||||||
self.event_manager = event_manager
|
self.event_manager = event_manager
|
||||||
|
self.radio = radio_manager
|
||||||
self.sampler_avg = 0
|
self.sampler_avg = 0
|
||||||
self.buffer_avg = 0
|
self.buffer_avg = 0
|
||||||
|
|
||||||
|
@ -108,7 +109,6 @@ class RF:
|
||||||
|
|
||||||
# Initialize codec2, rig control, and data threads
|
# Initialize codec2, rig control, and data threads
|
||||||
self.init_codec2()
|
self.init_codec2()
|
||||||
self.init_rig_control()
|
|
||||||
self.init_data_threads()
|
self.init_data_threads()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
@ -423,73 +423,3 @@ class RF:
|
||||||
else:
|
else:
|
||||||
sd.play(audio_48k, blocksize=4096, blocking=True)
|
sd.play(audio_48k, blocksize=4096, blocking=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
def init_rig_control(self):
|
|
||||||
# Check how we want to control the radio
|
|
||||||
if self.radiocontrol == "rigctld":
|
|
||||||
import rigctld as rig
|
|
||||||
elif self.radiocontrol == "tci":
|
|
||||||
self.radio = self.tci_module
|
|
||||||
else:
|
|
||||||
import rigdummy as rig
|
|
||||||
|
|
||||||
if not self.radiocontrol in ["tci"]:
|
|
||||||
self.radio = rig.radio()
|
|
||||||
self.radio.open_rig(
|
|
||||||
rigctld_ip=self.rigctld_ip,
|
|
||||||
rigctld_port=self.rigctld_port,
|
|
||||||
)
|
|
||||||
hamlib_thread = threading.Thread(
|
|
||||||
target=self.update_rig_data, name="HAMLIB_THREAD", daemon=True
|
|
||||||
)
|
|
||||||
hamlib_thread.start()
|
|
||||||
|
|
||||||
hamlib_set_thread = threading.Thread(
|
|
||||||
target=self.set_rig_data, name="HAMLIB_SET_THREAD", daemon=True
|
|
||||||
)
|
|
||||||
hamlib_set_thread.start()
|
|
||||||
|
|
||||||
def set_rig_data(self) -> None:
|
|
||||||
"""
|
|
||||||
Set rigctld parameters like frequency, mode
|
|
||||||
THis needs to be processed in a queue
|
|
||||||
"""
|
|
||||||
while True:
|
|
||||||
cmd = RIGCTLD_COMMAND_QUEUE.get()
|
|
||||||
if cmd[0] == "set_frequency":
|
|
||||||
# [1] = Frequency
|
|
||||||
self.radio.set_frequency(cmd[1])
|
|
||||||
if cmd[0] == "set_mode":
|
|
||||||
# [1] = Mode
|
|
||||||
self.radio.set_mode(cmd[1])
|
|
||||||
|
|
||||||
def update_rig_data(self) -> None:
|
|
||||||
"""
|
|
||||||
Request information about the current state of the radio via hamlib
|
|
||||||
"""
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
# this looks weird, but is necessary for avoiding rigctld packet colission sock
|
|
||||||
#threading.Event().wait(0.1)
|
|
||||||
self.states.set("radio_status", self.radio.get_status())
|
|
||||||
#threading.Event().wait(0.25)
|
|
||||||
self.states.set("radio_frequency", self.radio.get_frequency())
|
|
||||||
threading.Event().wait(0.1)
|
|
||||||
self.states.set("radio_mode", self.radio.get_mode())
|
|
||||||
threading.Event().wait(0.1)
|
|
||||||
self.states.set("radio_bandwidth", self.radio.get_bandwidth())
|
|
||||||
threading.Event().wait(0.1)
|
|
||||||
if self.states.isTransmitting():
|
|
||||||
self.radio_alc = self.radio.get_alc()
|
|
||||||
threading.Event().wait(0.1)
|
|
||||||
self.states.set("radio_rf_power", self.radio.get_level())
|
|
||||||
threading.Event().wait(0.1)
|
|
||||||
self.states.set("radio_strength", self.radio.get_strength())
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
self.log.warning(
|
|
||||||
"[MDM] error getting radio data",
|
|
||||||
e=e,
|
|
||||||
)
|
|
||||||
threading.Event().wait(1)
|
|
||||||
|
|
||||||
|
|
59
modem/radio_manager.py
Normal file
59
modem/radio_manager.py
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import rigctld
|
||||||
|
import tci
|
||||||
|
import rigdummy
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
|
class RadioManager:
|
||||||
|
def __init__(self, config, state_manager, event_manager):
|
||||||
|
self.config = config
|
||||||
|
self.state_manager = state_manager
|
||||||
|
self.event_manager = event_manager
|
||||||
|
|
||||||
|
self.radiocontrol = config['RADIO']['control']
|
||||||
|
self.rigctld_ip = config['RIGCTLD']['ip']
|
||||||
|
self.rigctld_port = config['RIGCTLD']['port']
|
||||||
|
|
||||||
|
self.refresh_rate = 1
|
||||||
|
self.stop_event = threading.Event()
|
||||||
|
self.update_thread = threading.Thread(target=self.update_parameters, daemon=True)
|
||||||
|
self._init_rig_control()
|
||||||
|
|
||||||
|
def _init_rig_control(self):
|
||||||
|
# Check how we want to control the radio
|
||||||
|
if self.radiocontrol == "rigctld":
|
||||||
|
self.radio = rigctld.radio(self.state_manager, hostname=self.rigctld_ip,port=self.rigctld_port)
|
||||||
|
elif self.radiocontrol == "tci":
|
||||||
|
raise NotImplementedError
|
||||||
|
# self.radio = self.tci_module
|
||||||
|
else:
|
||||||
|
self.radio = rigdummy.radio()
|
||||||
|
|
||||||
|
self.update_thread.start()
|
||||||
|
|
||||||
|
def set_ptt(self, state):
|
||||||
|
self.radio.set_ptt(state)
|
||||||
|
|
||||||
|
def set_frequency(self, frequency):
|
||||||
|
self.radio.set_frequency(frequency)
|
||||||
|
|
||||||
|
def set_mode(self, mode):
|
||||||
|
self.radio.set_mode(mode)
|
||||||
|
|
||||||
|
def set_rf_level(self, level):
|
||||||
|
self.radio.set_rf_level(level)
|
||||||
|
|
||||||
|
def update_parameters(self):
|
||||||
|
while not self.stop_event.is_set():
|
||||||
|
parameters = self.radio.get_parameters()
|
||||||
|
self.state_manager.set("radio_frequency", parameters['frequency'])
|
||||||
|
self.state_manager.set("radio_mode", parameters['mode'])
|
||||||
|
self.state_manager.set("radio_bandwidth", parameters['bandwidth'])
|
||||||
|
self.state_manager.set("radio_rf_level", parameters['rf'])
|
||||||
|
|
||||||
|
if self.state_manager.isTransmitting():
|
||||||
|
self.radio_alc = parameters['alc']
|
||||||
|
self.state_manager.set("s_meter_strength", parameters['strength'])
|
||||||
|
time.sleep(self.refresh_rate)
|
||||||
|
def stop(self):
|
||||||
|
self.radio.disconnect()
|
||||||
|
self.stop_event.set()
|
480
modem/rigctld.py
480
modem/rigctld.py
|
@ -1,12 +1,6 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
# class taken from darksidelemm
|
|
||||||
# rigctl - https://github.com/darksidelemm/rotctld-web-gui/blob/master/rotatorgui.py#L35
|
|
||||||
#
|
|
||||||
# modified and adjusted to FreeDATA needs by DJ2LS
|
|
||||||
|
|
||||||
import contextlib
|
|
||||||
import socket
|
import socket
|
||||||
import structlog
|
import structlog
|
||||||
|
import time
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
class radio:
|
class radio:
|
||||||
|
@ -14,332 +8,198 @@ class radio:
|
||||||
|
|
||||||
log = structlog.get_logger("radio (rigctld)")
|
log = structlog.get_logger("radio (rigctld)")
|
||||||
|
|
||||||
def __init__(self, hostname="localhost", port=4532, poll_rate=5, timeout=5):
|
def __init__(self, states, hostname="localhost", port=4532, timeout=5):
|
||||||
"""Open a connection to rigctld, and test it for validity"""
|
|
||||||
self.ptt_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
self.data_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
|
|
||||||
self.ptt_connected = False
|
|
||||||
self.data_connected = False
|
|
||||||
self.hostname = hostname
|
self.hostname = hostname
|
||||||
self.port = port
|
self.port = port
|
||||||
self.connection_attempts = 5
|
self.timeout = timeout
|
||||||
|
self.states = states
|
||||||
|
|
||||||
# class wide variable for some parameters
|
self.connection = None
|
||||||
self.bandwidth = ''
|
self.connected = False
|
||||||
self.frequency = ''
|
self.await_response = threading.Event()
|
||||||
self.mode = ''
|
self.await_response.set()
|
||||||
self.alc = ''
|
|
||||||
self.strength = ''
|
|
||||||
self.rf = ''
|
|
||||||
|
|
||||||
def open_rig(
|
self.parameters = {
|
||||||
self,
|
'frequency': '---',
|
||||||
rigctld_ip,
|
'mode': '---',
|
||||||
rigctld_port
|
'alc': '---',
|
||||||
):
|
'strength': '---',
|
||||||
"""
|
'bandwidth': '---',
|
||||||
|
'rf': '---',
|
||||||
|
'ptt': False # Initial PTT state is set to False
|
||||||
|
}
|
||||||
|
|
||||||
Args:
|
# connect to radio
|
||||||
rigctld_ip:
|
self.connect()
|
||||||
rigctld_port:
|
|
||||||
|
|
||||||
Returns:
|
def connect(self):
|
||||||
|
try:
|
||||||
|
self.connection = socket.create_connection((self.hostname, self.port), timeout=self.timeout)
|
||||||
|
self.connected = True
|
||||||
|
self.states.set("radio_status", True)
|
||||||
|
self.log.info(f"[RIGCTLD] Connected to rigctld at {self.hostname}:{self.port}")
|
||||||
|
except Exception as err:
|
||||||
|
self.log.warning(f"[RIGCTLD] Failed to connect to rigctld: {err}")
|
||||||
|
self.connected = False
|
||||||
|
self.states.set("radio_status", False)
|
||||||
|
|
||||||
"""
|
def disconnect(self):
|
||||||
self.hostname = rigctld_ip
|
self.connected = False
|
||||||
self.port = int(rigctld_port)
|
self.connection.close()
|
||||||
|
del self.connection
|
||||||
|
self.connection = None
|
||||||
|
self.states.set("radio_status", False)
|
||||||
|
self.parameters = {
|
||||||
|
'frequency': '---',
|
||||||
|
'mode': '---',
|
||||||
|
'alc': '---',
|
||||||
|
'strength': '---',
|
||||||
|
'bandwidth': '---',
|
||||||
|
'rf': '---',
|
||||||
|
'ptt': False # Initial PTT state is set to False
|
||||||
|
}
|
||||||
|
|
||||||
# _ptt_connect = self.ptt_connect()
|
def send_command(self, command) -> str:
|
||||||
# _data_connect = self.data_connect()
|
if self.connected:
|
||||||
|
# wait if we have another command awaiting its response...
|
||||||
ptt_thread = threading.Thread(target=self.ptt_connect, args=[], daemon=True)
|
self.await_response.wait()
|
||||||
ptt_thread.start()
|
|
||||||
|
|
||||||
data_thread = threading.Thread(target=self.data_connect, args=[], daemon=True)
|
|
||||||
data_thread.start()
|
|
||||||
|
|
||||||
# wait some time
|
|
||||||
threading.Event().wait(0.5)
|
|
||||||
|
|
||||||
if self.ptt_connected and self.data_connected:
|
|
||||||
self.log.debug("Rigctl DATA/PTT initialized")
|
|
||||||
return True
|
|
||||||
|
|
||||||
self.log.error(
|
|
||||||
"[RIGCTLD] Can't connect!", ip=self.hostname, port=self.port
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
|
|
||||||
def ptt_connect(self):
|
|
||||||
"""Connect to rigctld instance"""
|
|
||||||
while True:
|
|
||||||
|
|
||||||
if not self.ptt_connected:
|
|
||||||
try:
|
|
||||||
self.ptt_connection = socket.create_connection((self.hostname, self.port))
|
|
||||||
self.ptt_connected = True
|
|
||||||
self.log.info(
|
|
||||||
"[RIGCTLD] Connected PTT instance to rigctld!", ip=self.hostname, port=self.port
|
|
||||||
)
|
|
||||||
except Exception as err:
|
|
||||||
# ConnectionRefusedError: [Errno 111] Connection refused
|
|
||||||
self.close_rig()
|
|
||||||
self.log.warning(
|
|
||||||
"[RIGCTLD] PTT Reconnect...",
|
|
||||||
ip=self.hostname,
|
|
||||||
port=self.port,
|
|
||||||
e=err,
|
|
||||||
)
|
|
||||||
|
|
||||||
threading.Event().wait(0.5)
|
|
||||||
|
|
||||||
def data_connect(self):
|
|
||||||
"""Connect to rigctld instance"""
|
|
||||||
while True:
|
|
||||||
if not self.data_connected:
|
|
||||||
try:
|
|
||||||
self.data_connection = socket.create_connection((self.hostname, self.port))
|
|
||||||
self.data_connected = True
|
|
||||||
self.log.info(
|
|
||||||
"[RIGCTLD] Connected DATA instance to rigctld!", ip=self.hostname, port=self.port
|
|
||||||
)
|
|
||||||
except Exception as err:
|
|
||||||
# ConnectionRefusedError: [Errno 111] Connection refused
|
|
||||||
self.close_rig()
|
|
||||||
self.log.warning(
|
|
||||||
"[RIGCTLD] DATA Reconnect...",
|
|
||||||
ip=self.hostname,
|
|
||||||
port=self.port,
|
|
||||||
e=err,
|
|
||||||
)
|
|
||||||
threading.Event().wait(0.5)
|
|
||||||
|
|
||||||
def close_rig(self):
|
|
||||||
""" """
|
|
||||||
self.ptt_sock.close()
|
|
||||||
self.data_sock.close()
|
|
||||||
self.ptt_connected = False
|
|
||||||
self.data_connected = False
|
|
||||||
|
|
||||||
def send_ptt_command(self, command, expect_answer) -> bytes:
|
|
||||||
"""Send a command to the connected rotctld instance,
|
|
||||||
and return the return value.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
command:
|
|
||||||
|
|
||||||
"""
|
|
||||||
if self.ptt_connected:
|
|
||||||
try:
|
|
||||||
self.ptt_connection.sendall(command + b"\n")
|
|
||||||
except Exception:
|
|
||||||
self.log.warning(
|
|
||||||
"[RIGCTLD] Command not executed!",
|
|
||||||
command=command,
|
|
||||||
ip=self.hostname,
|
|
||||||
port=self.port,
|
|
||||||
)
|
|
||||||
self.ptt_connected = False
|
|
||||||
return b""
|
|
||||||
|
|
||||||
def send_data_command(self, command, expect_answer) -> bytes:
|
|
||||||
"""Send a command to the connected rotctld instance,
|
|
||||||
and return the return value.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
command:
|
|
||||||
|
|
||||||
"""
|
|
||||||
if self.data_connected:
|
|
||||||
self.data_connection.setblocking(False)
|
|
||||||
#Allow a little more time for a response from rigctld before generating a timeout, seems to have no ill effects on a well behaving setup and fixes Issue #373
|
|
||||||
self.data_connection.settimeout(0.30)
|
|
||||||
try:
|
|
||||||
self.data_connection.sendall(command + b"\n")
|
|
||||||
|
|
||||||
|
|
||||||
except Exception:
|
|
||||||
self.log.warning(
|
|
||||||
"[RIGCTLD] Command not executed!",
|
|
||||||
command=command,
|
|
||||||
ip=self.hostname,
|
|
||||||
port=self.port,
|
|
||||||
)
|
|
||||||
self.data_connected = False
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# recv seems to be blocking so in case of ptt we don't need the response
|
self.await_response = threading.Event()
|
||||||
# maybe this speeds things up and avoids blocking states
|
self.connection.sendall(command.encode('utf-8') + b"\n")
|
||||||
recv = True
|
response = self.connection.recv(1024)
|
||||||
data = b''
|
self.await_response.set()
|
||||||
|
return response.decode('utf-8').strip()
|
||||||
|
except Exception as err:
|
||||||
|
self.log.warning(f"[RIGCTLD] Error sending command [{command}] to rigctld: {err}")
|
||||||
|
self.connected = False
|
||||||
|
|
||||||
while recv:
|
|
||||||
try:
|
|
||||||
|
|
||||||
data = self.data_connection.recv(4800)
|
return ""
|
||||||
|
|
||||||
except socket.timeout:
|
|
||||||
recv = False
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
# return self.data_connection.recv(64) if expect_answer else True
|
|
||||||
except Exception:
|
|
||||||
self.log.warning(
|
|
||||||
"[RIGCTLD] No command response!",
|
|
||||||
command=command,
|
|
||||||
ip=self.hostname,
|
|
||||||
port=self.port,
|
|
||||||
)
|
|
||||||
self.data_connected = False
|
|
||||||
return b""
|
|
||||||
|
|
||||||
def get_status(self):
|
|
||||||
""" """
|
|
||||||
return True if self.data_connected and self.ptt_connected else False
|
|
||||||
|
|
||||||
def get_level(self):
|
|
||||||
try:
|
|
||||||
data = self.send_data_command(b"l RF", True)
|
|
||||||
data = data.split(b"\n")
|
|
||||||
rf = data[0].decode("utf-8")
|
|
||||||
if 'RPRT' not in rf:
|
|
||||||
try:
|
|
||||||
self.rf = str(rf)
|
|
||||||
except ValueError:
|
|
||||||
self.rf = str(rf)
|
|
||||||
|
|
||||||
return self.rf
|
|
||||||
except Exception:
|
|
||||||
return self.rf
|
|
||||||
|
|
||||||
def get_strength(self):
|
|
||||||
try:
|
|
||||||
data = self.send_data_command(b"l STRENGTH", True)
|
|
||||||
data = data.split(b"\n")
|
|
||||||
strength = data[0].decode("utf-8")
|
|
||||||
if 'RPRT' not in strength:
|
|
||||||
try:
|
|
||||||
self.strength = str(strength)
|
|
||||||
except ValueError:
|
|
||||||
self.strength = str(strength)
|
|
||||||
|
|
||||||
return self.strength
|
|
||||||
except Exception:
|
|
||||||
return self.strength
|
|
||||||
|
|
||||||
def get_alc(self):
|
|
||||||
try:
|
|
||||||
data = self.send_data_command(b"l ALC", True)
|
|
||||||
data = data.split(b"\n")
|
|
||||||
alc = data[0].decode("utf-8")
|
|
||||||
if 'RPRT' not in alc:
|
|
||||||
try:
|
|
||||||
alc = float(alc)
|
|
||||||
except ValueError:
|
|
||||||
self.alc = 0.0
|
|
||||||
|
|
||||||
return self.alc
|
|
||||||
except Exception:
|
|
||||||
return self.alc
|
|
||||||
|
|
||||||
def get_mode(self):
|
|
||||||
""" """
|
|
||||||
try:
|
|
||||||
data = self.send_data_command(b"m", True)
|
|
||||||
data = data.split(b"\n")
|
|
||||||
data = data[0].decode("utf-8")
|
|
||||||
if 'RPRT' not in data:
|
|
||||||
try:
|
|
||||||
data = int(data)
|
|
||||||
except ValueError:
|
|
||||||
self.mode = str(data)
|
|
||||||
|
|
||||||
return self.mode
|
|
||||||
except Exception:
|
|
||||||
return self.mode
|
|
||||||
|
|
||||||
def get_bandwidth(self):
|
|
||||||
""" """
|
|
||||||
try:
|
|
||||||
data = self.send_data_command(b"m", True)
|
|
||||||
data = data.split(b"\n")
|
|
||||||
data = data[1].decode("utf-8")
|
|
||||||
|
|
||||||
if 'RPRT' not in data and data not in ['']:
|
|
||||||
with contextlib.suppress(ValueError):
|
|
||||||
self.bandwidth = int(data)
|
|
||||||
return self.bandwidth
|
|
||||||
except Exception:
|
|
||||||
return self.bandwidth
|
|
||||||
|
|
||||||
def get_frequency(self):
|
|
||||||
""" """
|
|
||||||
try:
|
|
||||||
data = self.send_data_command(b"f", True)
|
|
||||||
data = data.decode("utf-8")
|
|
||||||
if 'RPRT' not in data and data not in [0, '0', '']:
|
|
||||||
with contextlib.suppress(ValueError):
|
|
||||||
data = int(data)
|
|
||||||
# make sure we have a frequency and not bandwidth
|
|
||||||
if data >= 10000:
|
|
||||||
self.frequency = data
|
|
||||||
return self.frequency
|
|
||||||
except Exception:
|
|
||||||
return self.frequency
|
|
||||||
|
|
||||||
def get_ptt(self):
|
|
||||||
""" """
|
|
||||||
try:
|
|
||||||
return self.send_data_command(b"t", True)
|
|
||||||
except Exception:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def set_ptt(self, state):
|
def set_ptt(self, state):
|
||||||
"""
|
"""Set the PTT (Push-to-Talk) state.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
state:
|
state (bool): True to enable PTT, False to disable.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
bool: True if the PTT state was set successfully, False otherwise.
|
||||||
"""
|
"""
|
||||||
try:
|
if self.connected:
|
||||||
if state:
|
try:
|
||||||
self.send_ptt_command(b"T 1", False)
|
if state:
|
||||||
else:
|
self.send_command('T 1') # Enable PTT
|
||||||
self.send_ptt_command(b"T 0", False)
|
else:
|
||||||
return state
|
self.send_command('T 0') # Disable PTT
|
||||||
except Exception:
|
self.parameters['ptt'] = state # Update PTT state in parameters
|
||||||
return False
|
return True
|
||||||
|
except Exception as err:
|
||||||
def set_frequency(self, frequency):
|
self.log.warning(f"[RIGCTLD] Error setting PTT state: {err}")
|
||||||
"""
|
self.connected = False
|
||||||
|
return False
|
||||||
Args:
|
|
||||||
frequency:
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
command = bytes(f"F {frequency}", "utf-8")
|
|
||||||
self.send_data_command(command, False)
|
|
||||||
except Exception:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def set_mode(self, mode):
|
def set_mode(self, mode):
|
||||||
"""
|
"""Set the mode.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
mode:
|
mode (str): The mode to set.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
bool: True if the mode was set successfully, False otherwise.
|
||||||
"""
|
"""
|
||||||
try:
|
if self.connected:
|
||||||
command = bytes(f"M {mode} {self.bandwidth}", "utf-8")
|
try:
|
||||||
self.send_data_command(command, False)
|
command = f"M {mode} 0"
|
||||||
except Exception:
|
self.send_command(command)
|
||||||
return False
|
self.parameters['mode'] = mode
|
||||||
|
return True
|
||||||
|
except Exception as err:
|
||||||
|
self.log.warning(f"[RIGCTLD] Error setting mode: {err}")
|
||||||
|
self.connected = False
|
||||||
|
return False
|
||||||
|
|
||||||
|
def set_frequency(self, frequency):
|
||||||
|
"""Set the frequency.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
frequency (str): The frequency to set.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if the frequency was set successfully, False otherwise.
|
||||||
|
"""
|
||||||
|
if self.connected:
|
||||||
|
try:
|
||||||
|
command = f"F {frequency}"
|
||||||
|
self.send_command(command)
|
||||||
|
self.parameters['frequency'] = frequency
|
||||||
|
return True
|
||||||
|
except Exception as err:
|
||||||
|
self.log.warning(f"[RIGCTLD] Error setting frequency: {err}")
|
||||||
|
self.connected = False
|
||||||
|
return False
|
||||||
|
|
||||||
|
def set_bandwidth(self, bandwidth):
|
||||||
|
"""Set the bandwidth.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
bandwidth (str): The bandwidth to set.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if the bandwidth was set successfully, False otherwise.
|
||||||
|
"""
|
||||||
|
if self.connected:
|
||||||
|
try:
|
||||||
|
command = f"M {self.parameters['mode']} {bandwidth}"
|
||||||
|
self.send_command(command)
|
||||||
|
self.parameters['bandwidth'] = bandwidth
|
||||||
|
return True
|
||||||
|
except Exception as err:
|
||||||
|
self.log.warning(f"[RIGCTLD] Error setting bandwidth: {err}")
|
||||||
|
self.connected = False
|
||||||
|
return False
|
||||||
|
|
||||||
|
def set_rf_level(self, rf):
|
||||||
|
"""Set the RF.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
rf (str): The RF to set.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if the RF was set successfully, False otherwise.
|
||||||
|
"""
|
||||||
|
if self.connected:
|
||||||
|
try:
|
||||||
|
command = f"L RFPOWER {rf/100}" #RF RFPOWER --> RFPOWER == IC705
|
||||||
|
self.send_command(command)
|
||||||
|
self.parameters['rf'] = rf
|
||||||
|
return True
|
||||||
|
except Exception as err:
|
||||||
|
self.log.warning(f"[RIGCTLD] Error setting RF: {err}")
|
||||||
|
self.connected = False
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_parameters(self):
|
||||||
|
if not self.connected:
|
||||||
|
self.connect()
|
||||||
|
|
||||||
|
if self.connected:
|
||||||
|
self.parameters['frequency'] = self.send_command('f')
|
||||||
|
response = self.send_command(
|
||||||
|
'm').strip() # Get the mode/bandwidth response and remove leading/trailing spaces
|
||||||
|
try:
|
||||||
|
mode, bandwidth = response.split('\n', 1) # Split the response into mode and bandwidth
|
||||||
|
except ValueError:
|
||||||
|
print(response)
|
||||||
|
mode = 'err'
|
||||||
|
bandwidth = 'err'
|
||||||
|
|
||||||
|
self.parameters['mode'] = mode
|
||||||
|
self.parameters['bandwidth'] = bandwidth
|
||||||
|
|
||||||
|
self.parameters['alc'] = self.send_command('l ALC')
|
||||||
|
self.parameters['strength'] = self.send_command('l STRENGTH')
|
||||||
|
self.parameters['rf'] = self.send_command('l RFPOWER') # RF, RFPOWER
|
||||||
|
|
||||||
|
"""Return the latest fetched parameters."""
|
||||||
|
return self.parameters
|
||||||
|
|
|
@ -1,13 +1,30 @@
|
||||||
hamlib_version = 0
|
|
||||||
|
|
||||||
|
|
||||||
class radio:
|
class radio:
|
||||||
""" """
|
""" """
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
self.parameters = {
|
||||||
|
'frequency': '---',
|
||||||
|
'mode': '---',
|
||||||
|
'alc': '---',
|
||||||
|
'strength': '---',
|
||||||
|
'bandwidth': '---',
|
||||||
|
'rf': '---',
|
||||||
|
'ptt': False # Initial PTT state is set to False
|
||||||
|
}
|
||||||
|
|
||||||
def open_rig(self, **kwargs):
|
def connect(self, **kwargs):
|
||||||
|
"""
|
||||||
|
|
||||||
|
Args:
|
||||||
|
**kwargs:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def disconnect(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -98,3 +115,7 @@ class radio:
|
||||||
def close_rig(self):
|
def close_rig(self):
|
||||||
""" """
|
""" """
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def get_parameters(self):
|
||||||
|
return self.parameters
|
|
@ -18,6 +18,7 @@ import command_feq
|
||||||
import command_test
|
import command_test
|
||||||
import command_arq_raw
|
import command_arq_raw
|
||||||
import event_manager
|
import event_manager
|
||||||
|
import radio_manager
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
CORS(app)
|
CORS(app)
|
||||||
|
@ -58,6 +59,7 @@ app.state_manager = state_manager.StateManager(app.state_queue)
|
||||||
# start service manager
|
# start service manager
|
||||||
app.service_manager = service_manager.SM(app)
|
app.service_manager = service_manager.SM(app)
|
||||||
|
|
||||||
|
|
||||||
# start modem service
|
# start modem service
|
||||||
app.modem_service.put("start")
|
app.modem_service.put("start")
|
||||||
|
|
||||||
|
@ -240,15 +242,21 @@ def post_modem_send_raw_stop():
|
||||||
|
|
||||||
return api_response(request.json)
|
return api_response(request.json)
|
||||||
|
|
||||||
|
@app.route('/radio', methods=['GET', 'POST'])
|
||||||
|
def get_post_radio():
|
||||||
|
if request.method in ['POST']:
|
||||||
|
app.radio_manager.set_frequency(request.json['radio_frequency'])
|
||||||
|
app.radio_manager.set_mode(request.json['radio_mode'])
|
||||||
|
app.radio_manager.set_rf_level(int(request.json['radio_rf_level']))
|
||||||
|
|
||||||
|
return api_response(request.json)
|
||||||
|
elif request.method == 'GET':
|
||||||
|
return api_response(app.state_manager.get_radio_status())
|
||||||
|
|
||||||
# @app.route('/modem/arq_connect', methods=['POST'])
|
# @app.route('/modem/arq_connect', methods=['POST'])
|
||||||
# @app.route('/modem/arq_disconnect', methods=['POST'])
|
# @app.route('/modem/arq_disconnect', methods=['POST'])
|
||||||
# @app.route('/modem/send_raw', methods=['POST'])
|
# @app.route('/modem/send_raw', methods=['POST'])
|
||||||
# @app.route('/modem/stop_transmission', methods=['POST'])
|
|
||||||
# @app.route('/modem/listen', methods=['POST']) # not needed if we are restarting modem on changing settings
|
|
||||||
# @app.route('/modem/record_audio', methods=['POST'])
|
# @app.route('/modem/record_audio', methods=['POST'])
|
||||||
# @app.route('/modem/responde_to_call', methods=['POST']) # not needed if we are restarting modem on changing settings
|
|
||||||
# @app.route('/modem/responde_to_cq', methods=['POST']) # not needed if we are restarting modem on changing settings
|
|
||||||
# @app.route('/modem/audio_levels', methods=['POST']) # tx and rx # not needed if we are restarting modem on changing settings
|
# @app.route('/modem/audio_levels', methods=['POST']) # tx and rx # not needed if we are restarting modem on changing settings
|
||||||
# @app.route('/modem/mesh_ping', methods=['POST'])
|
# @app.route('/modem/mesh_ping', methods=['POST'])
|
||||||
# @app.route('/mesh/routing_table', methods=['GET'])
|
# @app.route('/mesh/routing_table', methods=['GET'])
|
||||||
|
|
|
@ -6,20 +6,21 @@ import audio
|
||||||
import ujson as json
|
import ujson as json
|
||||||
import explorer
|
import explorer
|
||||||
import beacon
|
import beacon
|
||||||
|
import radio_manager
|
||||||
|
|
||||||
|
|
||||||
class SM:
|
class SM:
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
self.log = structlog.get_logger("service")
|
self.log = structlog.get_logger("service")
|
||||||
|
self.app = app
|
||||||
self.modem = False
|
self.modem = False
|
||||||
self.beacon = False
|
self.beacon = False
|
||||||
self.explorer = False
|
self.explorer = False
|
||||||
self.app = app
|
self.app.radio_manager = False
|
||||||
self.config = self.app.config_manager.read()
|
self.config = self.app.config_manager.read()
|
||||||
self.modem_fft = app.modem_fft
|
self.modem_fft = app.modem_fft
|
||||||
self.modem_service = app.modem_service
|
self.modem_service = app.modem_service
|
||||||
self.states = app.state_manager
|
self.state_manager = app.state_manager
|
||||||
self.event_manager = app.event_manager
|
self.event_manager = app.event_manager
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,22 +35,31 @@ class SM:
|
||||||
if cmd in ['start'] and not self.modem:
|
if cmd in ['start'] and not self.modem:
|
||||||
self.log.info("------------------ FreeDATA ------------------")
|
self.log.info("------------------ FreeDATA ------------------")
|
||||||
self.log.info("------------------ MODEM ------------------")
|
self.log.info("------------------ MODEM ------------------")
|
||||||
|
self.config = self.app.config_manager.read()
|
||||||
|
self.start_radio_manager()
|
||||||
self.start_modem()
|
self.start_modem()
|
||||||
self.start_explorer_publishing()
|
self.start_explorer_publishing()
|
||||||
|
|
||||||
elif cmd in ['stop'] and self.modem:
|
elif cmd in ['stop'] and self.modem:
|
||||||
self.stop_modem()
|
self.stop_modem()
|
||||||
self.stop_explorer_publishing()
|
self.stop_explorer_publishing()
|
||||||
|
self.stop_radio_manager()
|
||||||
# we need to wait a bit for avoiding a portaudio crash
|
# we need to wait a bit for avoiding a portaudio crash
|
||||||
threading.Event().wait(0.5)
|
threading.Event().wait(0.5)
|
||||||
|
|
||||||
elif cmd in ['restart']:
|
elif cmd in ['restart']:
|
||||||
self.stop_modem()
|
self.stop_modem()
|
||||||
self.stop_explorer_publishing()
|
self.stop_explorer_publishing()
|
||||||
|
self.stop_radio_manager()
|
||||||
# we need to wait a bit for avoiding a portaudio crash
|
# we need to wait a bit for avoiding a portaudio crash
|
||||||
threading.Event().wait(0.5)
|
threading.Event().wait(0.5)
|
||||||
|
|
||||||
|
self.config = self.app.config_manager.read()
|
||||||
|
self.start_radio_manager()
|
||||||
|
|
||||||
if self.start_modem():
|
if self.start_modem():
|
||||||
self.event_manager.modem_restarted()
|
self.event_manager.modem_restarted()
|
||||||
|
self.start_explorer_publishing()
|
||||||
elif cmd in ['start_beacon']:
|
elif cmd in ['start_beacon']:
|
||||||
self.start_beacon()
|
self.start_beacon()
|
||||||
|
|
||||||
|
@ -59,37 +69,34 @@ class SM:
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.log.warning("[SVC] modem command processing failed", cmd=cmd, state=self.states.is_modem_running)
|
self.log.warning("[SVC] modem command processing failed", cmd=cmd, state=self.state_manager.is_modem_running)
|
||||||
|
|
||||||
|
|
||||||
def start_modem(self):
|
def start_modem(self):
|
||||||
# read config
|
if self.state_manager.is_modem_running:
|
||||||
self.config = self.app.config_manager.read()
|
|
||||||
|
|
||||||
if self.states.is_modem_running:
|
|
||||||
self.log.warning("modem already running")
|
self.log.warning("modem already running")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# test audio devices
|
# test audio devices
|
||||||
audio_test = self.test_audio()
|
audio_test = self.test_audio()
|
||||||
|
|
||||||
if False in audio_test or None in audio_test or self.states.is_modem_running:
|
if False in audio_test or None in audio_test or self.state_manager.is_modem_running:
|
||||||
self.log.warning("starting modem failed", input_test=audio_test[0], output_test=audio_test[1])
|
self.log.warning("starting modem failed", input_test=audio_test[0], output_test=audio_test[1])
|
||||||
self.states.set("is_modem_running", False)
|
self.state_manager.set("is_modem_running", False)
|
||||||
self.event_manager.modem_failed()
|
self.event_manager.modem_failed()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.log.info("starting modem....")
|
self.log.info("starting modem....")
|
||||||
self.modem = modem.RF(self.config, self.event_manager, self.modem_fft, self.modem_service, self.states)
|
self.modem = modem.RF(self.config, self.event_manager, self.modem_fft, self.modem_service, self.state_manager, self.app.radio_manager)
|
||||||
|
|
||||||
self.frame_dispatcher = frame_dispatcher.DISPATCHER(self.config,
|
self.frame_dispatcher = frame_dispatcher.DISPATCHER(self.config,
|
||||||
self.event_manager,
|
self.event_manager,
|
||||||
self.states,
|
self.state_manager,
|
||||||
self.modem)
|
self.modem)
|
||||||
self.frame_dispatcher.start()
|
self.frame_dispatcher.start()
|
||||||
|
|
||||||
self.event_manager.modem_started()
|
self.event_manager.modem_started()
|
||||||
self.states.set("is_modem_running", True)
|
self.state_manager.set("is_modem_running", True)
|
||||||
self.modem.start_modem()
|
self.modem.start_modem()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
@ -98,7 +105,7 @@ class SM:
|
||||||
self.log.info("stopping modem....")
|
self.log.info("stopping modem....")
|
||||||
del self.modem
|
del self.modem
|
||||||
self.modem = False
|
self.modem = False
|
||||||
self.states.set("is_modem_running", False)
|
self.state_manager.set("is_modem_running", False)
|
||||||
self.event_manager.modem_stopped()
|
self.event_manager.modem_stopped()
|
||||||
|
|
||||||
def test_audio(self):
|
def test_audio(self):
|
||||||
|
@ -113,7 +120,7 @@ class SM:
|
||||||
return [False, False]
|
return [False, False]
|
||||||
|
|
||||||
def start_beacon(self):
|
def start_beacon(self):
|
||||||
self.beacon = beacon.Beacon(self.config, self.states, self.event_manager, self.log, self.modem)
|
self.beacon = beacon.Beacon(self.config, self.state_manager, self.event_manager, self.log, self.modem)
|
||||||
self.beacon.start()
|
self.beacon.start()
|
||||||
|
|
||||||
def stop_beacon(self):
|
def stop_beacon(self):
|
||||||
|
@ -123,9 +130,17 @@ class SM:
|
||||||
try:
|
try:
|
||||||
# optionally start explorer module
|
# optionally start explorer module
|
||||||
if self.config['STATION']['enable_explorer']:
|
if self.config['STATION']['enable_explorer']:
|
||||||
self.explorer = explorer.explorer(self.app, self.config, self.states)
|
self.explorer = explorer.explorer(self.app, self.config, self.state_manager)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.warning("[EXPLORER] Publishing not started because of error", e=e)
|
self.log.warning("[EXPLORER] Publishing not started because of error", e=e)
|
||||||
|
|
||||||
def stop_explorer_publishing(self):
|
def stop_explorer_publishing(self):
|
||||||
del self.explorer
|
if self.config['STATION']['enable_explorer']:
|
||||||
|
del self.explorer
|
||||||
|
|
||||||
|
def start_radio_manager(self):
|
||||||
|
self.app.radio_manager = radio_manager.RadioManager(self.config, self.state_manager, self.event_manager)
|
||||||
|
|
||||||
|
def stop_radio_manager(self):
|
||||||
|
self.app.radio_manager.stop()
|
||||||
|
del self.app.radio_manager
|
|
@ -43,8 +43,8 @@ class StateManager:
|
||||||
self.radio_frequency = 0
|
self.radio_frequency = 0
|
||||||
self.radio_mode = None
|
self.radio_mode = None
|
||||||
self.radio_bandwidth = 0
|
self.radio_bandwidth = 0
|
||||||
self.radio_rf_power = 0
|
self.radio_rf_level = 0
|
||||||
self.radio_strength = 0
|
self.s_meter_strength = 0
|
||||||
# Set rig control status regardless or rig control method
|
# Set rig control status regardless or rig control method
|
||||||
self.radio_status = False
|
self.radio_status = False
|
||||||
|
|
||||||
|
@ -85,6 +85,7 @@ class StateManager:
|
||||||
"radio_status": self.radio_status,
|
"radio_status": self.radio_status,
|
||||||
"radio_frequency": self.radio_frequency,
|
"radio_frequency": self.radio_frequency,
|
||||||
"radio_mode": self.radio_mode,
|
"radio_mode": self.radio_mode,
|
||||||
|
"s_meter_strength": self.s_meter_strength,
|
||||||
"channel_busy_slot": self.channel_busy_slot,
|
"channel_busy_slot": self.channel_busy_slot,
|
||||||
"audio_dbfs": self.audio_dbfs,
|
"audio_dbfs": self.audio_dbfs,
|
||||||
"activities": self.activities_list,
|
"activities": self.activities_list,
|
||||||
|
@ -177,3 +178,12 @@ class StateManager:
|
||||||
else:
|
else:
|
||||||
self.channel_busy_condition_codec2 = threading.Event()
|
self.channel_busy_condition_codec2 = threading.Event()
|
||||||
self.calculate_channel_busy_state()
|
self.calculate_channel_busy_state()
|
||||||
|
|
||||||
|
def get_radio_status(self):
|
||||||
|
return {
|
||||||
|
"radio_status": self.radio_status,
|
||||||
|
"radio_frequency": self.radio_frequency,
|
||||||
|
"radio_mode": self.radio_mode,
|
||||||
|
"radio_rf_level": self.radio_rf_level,
|
||||||
|
"s_meter_strength": self.s_meter_strength,
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ from command_ping import PingCommand
|
||||||
from command_cq import CQCommand
|
from command_cq import CQCommand
|
||||||
import modem
|
import modem
|
||||||
import frame_handler
|
import frame_handler
|
||||||
|
from radio_manager import RadioManager
|
||||||
|
|
||||||
class TestProtocols(unittest.TestCase):
|
class TestProtocols(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -27,9 +27,10 @@ class TestProtocols(unittest.TestCase):
|
||||||
cls.event_queue = queue.Queue()
|
cls.event_queue = queue.Queue()
|
||||||
cls.event_manager = EventManager([cls.event_queue])
|
cls.event_manager = EventManager([cls.event_queue])
|
||||||
|
|
||||||
|
cls.radio_manager = RadioManager(cls.config, cls.state_manager, cls.event_manager)
|
||||||
cls.modem_transmit_queue = queue.Queue()
|
cls.modem_transmit_queue = queue.Queue()
|
||||||
|
|
||||||
cls.modem = modem.RF(cls.config, cls.event_queue, queue.Queue(), queue.Queue(), cls.state_manager)
|
cls.modem = modem.RF(cls.config, cls.event_queue, queue.Queue(), queue.Queue(), cls.state_manager, cls.radio_manager)
|
||||||
modem.TESTMODE = True
|
modem.TESTMODE = True
|
||||||
frame_handler.TESTMODE = True
|
frame_handler.TESTMODE = True
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue