mirror of
https://github.com/aljazceru/meshcore-web.git
synced 2025-12-18 08:34:21 +01:00
add ability to configure radio settings
This commit is contained in:
@@ -26,7 +26,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
|
||||||
<!-- disconnect button -->
|
<!-- action buttons -->
|
||||||
<div v-else class="flex space-x-1">
|
<div v-else class="flex space-x-1">
|
||||||
<button @click="sendFloodAdvert" type="button" class="my-auto bg-gray-500 text-white px-2 py-1 p-1 rounded shadow hover:bg-gray-400">
|
<button @click="sendFloodAdvert" type="button" class="my-auto bg-gray-500 text-white px-2 py-1 p-1 rounded shadow hover:bg-gray-400">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||||
@@ -51,6 +51,16 @@
|
|||||||
<span>Set Name</span>
|
<span>Set Name</span>
|
||||||
</DropDownMenuItem>
|
</DropDownMenuItem>
|
||||||
|
|
||||||
|
<!-- set name -->
|
||||||
|
<RouterLink :to="{ name: 'settings.radio' }">
|
||||||
|
<DropDownMenuItem>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9.348 14.652a3.75 3.75 0 0 1 0-5.304m5.304 0a3.75 3.75 0 0 1 0 5.304m-7.425 2.121a6.75 6.75 0 0 1 0-9.546m9.546 0a6.75 6.75 0 0 1 0 9.546M5.106 18.894c-3.808-3.807-3.808-9.98 0-13.788m13.788 0c3.808 3.807 3.808 9.98 0 13.788M12 12h.008v.008H12V12Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" />
|
||||||
|
</svg>
|
||||||
|
<span>Set Frequency</span>
|
||||||
|
</DropDownMenuItem>
|
||||||
|
</RouterLink>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</DropDownMenu>
|
</DropDownMenu>
|
||||||
<button @click="disconnect" type="button" class="my-auto bg-gray-500 text-white px-2 py-1 p-1 rounded shadow hover:bg-gray-400">
|
<button @click="disconnect" type="button" class="my-auto bg-gray-500 text-white px-2 py-1 p-1 rounded shadow hover:bg-gray-400">
|
||||||
|
|||||||
15
src/components/SaveButton.vue
Normal file
15
src/components/SaveButton.vue
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<button :disabled="isSaving" type="button" class="text-white font-semibold px-2 py-1 rounded shadow" :class="[ isSaving ? 'bg-gray-400' : 'bg-blue-500 hover:bg-blue-400' ]">
|
||||||
|
<span v-if="isSaving">Saving...</span>
|
||||||
|
<span v-else>Save</span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'SaveButton',
|
||||||
|
props: {
|
||||||
|
isSaving: Boolean,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
134
src/components/pages/RadioSettingsPage.vue
Normal file
134
src/components/pages/RadioSettingsPage.vue
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
<template>
|
||||||
|
<Page>
|
||||||
|
|
||||||
|
<!-- app bar -->
|
||||||
|
<AppBar title="Radio Settings" :subtitle="GlobalState.selfInfo?.name">
|
||||||
|
<template v-slot:trailing>
|
||||||
|
<SaveButton @click="save"/>
|
||||||
|
</template>
|
||||||
|
</AppBar>
|
||||||
|
|
||||||
|
<!-- loaded -->
|
||||||
|
<div class="flex h-full w-full overflow-hidden">
|
||||||
|
|
||||||
|
<div class="w-full overflow-y-auto">
|
||||||
|
|
||||||
|
<div class="bg-white divide-y">
|
||||||
|
|
||||||
|
<div class="w-full p-2">
|
||||||
|
<div class="block mb-2 text-sm font-medium text-gray-900">Frequency (kHz)</div>
|
||||||
|
<input v-model="radioFreq" type="number" placeholder="e.g: 917375" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="w-full p-2">
|
||||||
|
<div class="block mb-2 text-sm font-medium text-gray-900">Bandwidth (kHz)</div>
|
||||||
|
<input v-model="radioBw" type="number" placeholder="e.g: 250000" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="w-full p-2">
|
||||||
|
<div class="block mb-2 text-sm font-medium text-gray-900">Spreading Factor</div>
|
||||||
|
<input v-model="radioSf" type="number" placeholder="e.g: 7" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="w-full p-2">
|
||||||
|
<div class="block mb-2 text-sm font-medium text-gray-900">Coding Rate</div>
|
||||||
|
<input v-model="radioCr" type="number" placeholder="e.g: 5" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="w-full p-2">
|
||||||
|
<div class="block mb-2 text-sm font-medium text-gray-900">Transmit Power (dBm)</div>
|
||||||
|
<input v-model="txPower" type="number" placeholder="e.g: 22" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</Page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Connection from "../../js/Connection.js";
|
||||||
|
import GlobalState from "../../js/GlobalState.js";
|
||||||
|
import AppBar from "../AppBar.vue";
|
||||||
|
import SaveButton from "../SaveButton.vue";
|
||||||
|
import Page from "./Page.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'RadioSettingsPage',
|
||||||
|
components: {Page, SaveButton, AppBar},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
radioFreq: null,
|
||||||
|
radioBw: null,
|
||||||
|
radioSf: null,
|
||||||
|
radioCr: null,
|
||||||
|
txPower: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.load();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async load() {
|
||||||
|
await Connection.loadSelfInfo();
|
||||||
|
this.radioFreq = GlobalState.selfInfo?.radioFreq;
|
||||||
|
this.radioBw = GlobalState.selfInfo?.radioBw;
|
||||||
|
this.radioSf = GlobalState.selfInfo?.radioSf;
|
||||||
|
this.radioCr = GlobalState.selfInfo?.radioCr;
|
||||||
|
this.txPower = GlobalState.selfInfo?.txPower;
|
||||||
|
},
|
||||||
|
async save() {
|
||||||
|
try {
|
||||||
|
|
||||||
|
// ensure frequency provided
|
||||||
|
if(!this.radioFreq){
|
||||||
|
alert("Frequency is required!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure bandwidth provided
|
||||||
|
if(!this.radioBw){
|
||||||
|
alert("Bandwidth is required!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure spreading factor provided
|
||||||
|
if(!this.radioSf){
|
||||||
|
alert("Spreading Factor is required!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure coding rate provided
|
||||||
|
if(!this.radioCr){
|
||||||
|
alert("Coding Rate is required!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure transmit power provided
|
||||||
|
if(!this.txPower){
|
||||||
|
alert("Transmit Power is required!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// save settings
|
||||||
|
await Connection.setRadioParams(this.radioFreq, this.radioBw, this.radioSf, this.radioCr, this.txPower);
|
||||||
|
|
||||||
|
// show success alert
|
||||||
|
alert("Settings saved.");
|
||||||
|
|
||||||
|
} catch(e) {
|
||||||
|
console.log(e);
|
||||||
|
// DialogUtils.showErrorAlert(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
GlobalState() {
|
||||||
|
return GlobalState;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -64,6 +64,11 @@ class Connection {
|
|||||||
await GlobalState.connection.sendCommandSetAdvertName(name);
|
await GlobalState.connection.sendCommandSetAdvertName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async setRadioParams(radioFreq, radioBw, radioSf, radioCr, txPower) {
|
||||||
|
await GlobalState.connection.sendCommandSetTxPower(txPower);
|
||||||
|
await GlobalState.connection.sendCommandSetRadioParams(radioFreq, radioBw, radioSf, radioCr);
|
||||||
|
}
|
||||||
|
|
||||||
static async syncDeviceTime() {
|
static async syncDeviceTime() {
|
||||||
const timestamp = Math.floor(Date.now() / 1000);
|
const timestamp = Math.floor(Date.now() / 1000);
|
||||||
await GlobalState.connection.sendCommandSetDeviceTime(timestamp);
|
await GlobalState.connection.sendCommandSetDeviceTime(timestamp);
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ const router = createRouter({
|
|||||||
path: '/connect',
|
path: '/connect',
|
||||||
component: () => import("./components/pages/ConnectPage.vue"),
|
component: () => import("./components/pages/ConnectPage.vue"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "settings.radio",
|
||||||
|
path: '/settings/radio',
|
||||||
|
component: () => import("./components/pages/RadioSettingsPage.vue"),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user