CommandsWidget working at a bare minimum level
This commit is contained in:
parent
566f02ede4
commit
97870827e7
@ -7,6 +7,7 @@ import RecentActivityWidget from "./components/dashboard/RecentActivityWidget.vu
|
|||||||
import ProductOverviewWidget from "./components/dashboard/ProductOverviewWidget.vue";
|
import ProductOverviewWidget from "./components/dashboard/ProductOverviewWidget.vue";
|
||||||
|
|
||||||
import PropertiesWidget from "./components/dashboard/PropertiesWidget.vue";
|
import PropertiesWidget from "./components/dashboard/PropertiesWidget.vue";
|
||||||
|
import CommandsWidget from "./components/dashboard/CommandsWidget.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -14,6 +15,7 @@ import PropertiesWidget from "./components/dashboard/PropertiesWidget.vue";
|
|||||||
<AppTopbar />
|
<AppTopbar />
|
||||||
<div class="layout-grid">
|
<div class="layout-grid">
|
||||||
<PropertiesWidget device-id="example-gps-fedora" />
|
<PropertiesWidget device-id="example-gps-fedora" />
|
||||||
|
<CommandsWidget device-id="example-gps-fedora" />
|
||||||
<StatsWidget />
|
<StatsWidget />
|
||||||
<!-- <div class="layout-grid-row">
|
<!-- <div class="layout-grid-row">
|
||||||
<SalesTrendWidget />
|
<SalesTrendWidget />
|
||||||
|
|||||||
114
console/src/components/dashboard/CommandsWidget.vue
Normal file
114
console/src/components/dashboard/CommandsWidget.vue
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<script setup>
|
||||||
|
import { ref, reactive, watch, onMounted } from 'vue'
|
||||||
|
import MQTTService from '../../services/mqtt.js'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
deviceId: String
|
||||||
|
})
|
||||||
|
|
||||||
|
const mqtt2 = new MQTTService()
|
||||||
|
|
||||||
|
const filters = ref({})
|
||||||
|
const filterMode = ref({ label: 'Lenient', value: 'lenient' });
|
||||||
|
|
||||||
|
const commands = ref([])
|
||||||
|
|
||||||
|
const commandMap = reactive({})
|
||||||
|
|
||||||
|
function rebuildList() {
|
||||||
|
commands.value = Object.values(commandMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCommand(device, name, field, value) {
|
||||||
|
if (!commandMap[name]) {
|
||||||
|
commandMap[name] = {
|
||||||
|
name,
|
||||||
|
description: '',
|
||||||
|
input: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commandMap[name][field] = value
|
||||||
|
rebuildList()
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendCommand(cmd) {
|
||||||
|
|
||||||
|
const topic = `device/${props.deviceId}/command/${cmd.name}`
|
||||||
|
|
||||||
|
mqtt2.publish(topic, JSON.stringify(cmd.input))
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => props.deviceId, () => {
|
||||||
|
Object.keys(commandMap).forEach(k => delete commandMap[k])
|
||||||
|
commands.value = []
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
|
||||||
|
mqtt2.subscribe('device/+/command/#', (payload, topic) => {
|
||||||
|
|
||||||
|
console.log(topic)
|
||||||
|
|
||||||
|
const parts = topic.split('/')
|
||||||
|
|
||||||
|
const device = parts[1]
|
||||||
|
if (device !== props.deviceId) return
|
||||||
|
|
||||||
|
const command = parts[3]
|
||||||
|
const field = parts[4]
|
||||||
|
|
||||||
|
if (field === 'description') {
|
||||||
|
updateCommand(device, command, 'description', payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="layout-card">
|
||||||
|
<DataView :value="commands">
|
||||||
|
<template #header>
|
||||||
|
<div class="flex products-header">
|
||||||
|
<span class="products-title">Commands</span>
|
||||||
|
<IconField class="search-field">
|
||||||
|
<InputIcon class="pi pi-search" />
|
||||||
|
<InputText v-model="filters['global']" placeholder="Filter by..." />
|
||||||
|
</IconField>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #empty> No commands available.</template>
|
||||||
|
<template #list="slotProps">
|
||||||
|
<div
|
||||||
|
v-for="cmd in slotProps.items"
|
||||||
|
:key="cmd.name"
|
||||||
|
class="p-card p-mb-3"
|
||||||
|
style="padding:1rem"
|
||||||
|
>
|
||||||
|
|
||||||
|
<h3>{{ cmd.name }}</h3>
|
||||||
|
|
||||||
|
<p>{{ cmd.description }}</p>
|
||||||
|
|
||||||
|
<Textarea
|
||||||
|
v-model="cmd.input"
|
||||||
|
rows="3"
|
||||||
|
style="width:100%"
|
||||||
|
placeholder="JSON arguments..."
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
label="Send Command"
|
||||||
|
icon="pi pi-send"
|
||||||
|
class="p-mt-2"
|
||||||
|
@click="sendCommand(cmd)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</DataView>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@ -96,7 +96,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="card">
|
<div class="layout-card">
|
||||||
<TreeTable :value="nodes" :filters="filters" :filterMode="filterMode.value">
|
<TreeTable :value="nodes" :filters="filters" :filterMode="filterMode.value">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="flex products-header">
|
<div class="flex products-header">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user