Added command responses success/failure to web UI
This commit is contained in:
parent
a3c9d053aa
commit
58de012af6
@ -11,6 +11,8 @@ import CommandsWidget from "./components/dashboard/CommandsWidget.vue";
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<Toast position="bottom-right" />
|
||||||
|
|
||||||
<div class="layout-container">
|
<div class="layout-container">
|
||||||
<AppTopbar />
|
<AppTopbar />
|
||||||
<div class="layout-grid">
|
<div class="layout-grid">
|
||||||
|
|||||||
@ -6,10 +6,15 @@ import Accordion from 'primevue/accordion';
|
|||||||
import AccordionPanel from 'primevue/accordionpanel';
|
import AccordionPanel from 'primevue/accordionpanel';
|
||||||
import AccordionHeader from 'primevue/accordionheader';
|
import AccordionHeader from 'primevue/accordionheader';
|
||||||
import AccordionContent from 'primevue/accordioncontent';
|
import AccordionContent from 'primevue/accordioncontent';
|
||||||
|
import Dialog from 'primevue/dialog'
|
||||||
|
|
||||||
import { JsonForms } from "@jsonforms/vue";
|
import { JsonForms } from "@jsonforms/vue";
|
||||||
import { primeVueRenderers } from 'jsonforms-primevue'
|
import { primeVueRenderers } from 'jsonforms-primevue'
|
||||||
|
|
||||||
|
import { useToast } from 'primevue/usetoast'
|
||||||
|
|
||||||
|
const toast = useToast()
|
||||||
|
|
||||||
const renderers = Object.freeze([
|
const renderers = Object.freeze([
|
||||||
...primeVueRenderers,
|
...primeVueRenderers,
|
||||||
// here you can add custom renderers
|
// here you can add custom renderers
|
||||||
@ -24,6 +29,7 @@ const mqtt2 = new MQTTService()
|
|||||||
const filters = ref({})
|
const filters = ref({})
|
||||||
const commands = ref([])
|
const commands = ref([])
|
||||||
const commandMap = reactive({})
|
const commandMap = reactive({})
|
||||||
|
const commandByResponseId = reactive({})
|
||||||
|
|
||||||
function rebuildList() {
|
function rebuildList() {
|
||||||
commands.value = Object.values(commandMap)
|
commands.value = Object.values(commandMap)
|
||||||
@ -35,7 +41,8 @@ function updateCommand(device, name, field, value) {
|
|||||||
name,
|
name,
|
||||||
description: "No description provided.",
|
description: "No description provided.",
|
||||||
schema: {},
|
schema: {},
|
||||||
input: {}
|
input: {},
|
||||||
|
response: null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,12 +51,27 @@ function updateCommand(device, name, field, value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function sendCommand(cmd) {
|
function sendCommand(cmd) {
|
||||||
|
cmd.responseId = null
|
||||||
|
cmd.response = {}
|
||||||
|
|
||||||
const topic = `device/${props.deviceId}/command/${cmd.name}`
|
const topic = `device/${props.deviceId}/command/${cmd.name}`
|
||||||
var payload = JSON.stringify(cmd.input, null, 2)
|
var payload = JSON.stringify(cmd.input, null, 2)
|
||||||
mqtt2.publish(topic, payload || '{}')
|
|
||||||
|
var responseId = generateId()
|
||||||
|
commandByResponseId[responseId] = cmd
|
||||||
|
|
||||||
|
mqtt2.publish(topic, payload || '{}', {
|
||||||
|
qos: 1,
|
||||||
|
properties: {
|
||||||
|
responseTopic: `client/${mqtt2.clientId}/responses`,
|
||||||
|
correlationData: new TextEncoder().encode(responseId)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
import Dialog from 'primevue/dialog'
|
function generateId() {
|
||||||
|
return Math.random().toString(16).substr(2, 8)
|
||||||
|
}
|
||||||
|
|
||||||
const schemaDialog = reactive({
|
const schemaDialog = reactive({
|
||||||
visible: false,
|
visible: false,
|
||||||
@ -67,7 +89,7 @@ function showSchema(cmd) {
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
||||||
mqtt2.subscribe('device/+/command/#', (payload, topic) => {
|
mqtt2.subscribe('device/+/command/#', (payload, topic) => {
|
||||||
|
|
||||||
const parts = topic.split('/')
|
const parts = topic.split('/')
|
||||||
|
|
||||||
@ -86,6 +108,26 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mqtt2.subscribe(`client/${mqtt2.clientId}/responses`, (payload, topic) => {
|
||||||
|
let response = JSON.parse(payload)
|
||||||
|
|
||||||
|
const responseId = response.correlation
|
||||||
|
const cmd = commandByResponseId[responseId]
|
||||||
|
|
||||||
|
if (cmd) {
|
||||||
|
cmd.response = response
|
||||||
|
|
||||||
|
toast.add({
|
||||||
|
severity: response.success ? 'success' : 'error',
|
||||||
|
summary: cmd.name,
|
||||||
|
detail: response.message !== 'None' ? response.message : (response.success ? 'Success' : 'Failed'),
|
||||||
|
life: 4000
|
||||||
|
})
|
||||||
|
|
||||||
|
delete commandByResponseId[responseId]
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const jsonFormsConfig = {
|
const jsonFormsConfig = {
|
||||||
@ -146,6 +188,13 @@ const jsonFormsConfig = {
|
|||||||
|
|
||||||
<!-- Right: Buttons -->
|
<!-- Right: Buttons -->
|
||||||
<div class="button-container">
|
<div class="button-container">
|
||||||
|
<Button
|
||||||
|
v-if="cmd.response"
|
||||||
|
:icon="cmd.response.success ? 'pi pi-check' : 'pi pi-times'"
|
||||||
|
class="p-button-rounded p-button-text"
|
||||||
|
:class="cmd.response.success ? 'p-button-success' : 'p-button-danger'"
|
||||||
|
v-tooltip="cmd.response.message !== 'None' ? cmd.response.message : null"
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
icon="pi pi-question-circle"
|
icon="pi pi-question-circle"
|
||||||
class="p-mb-2"
|
class="p-mb-2"
|
||||||
|
|||||||
@ -5,6 +5,8 @@ import PrimeVue from "primevue/config";
|
|||||||
import App from "./App.vue";
|
import App from "./App.vue";
|
||||||
import Aura from "@primeuix/themes/aura";
|
import Aura from "@primeuix/themes/aura";
|
||||||
|
|
||||||
|
import ToastService from 'primevue/toastservice'
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
app.use(PrimeVue, {
|
app.use(PrimeVue, {
|
||||||
@ -16,4 +18,6 @@ app.use(PrimeVue, {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.use(ToastService)
|
||||||
|
|
||||||
app.mount("#app");
|
app.mount("#app");
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import mqtt from 'mqtt'
|
|||||||
export default class MQTTService {
|
export default class MQTTService {
|
||||||
constructor(brokerUrl = 'ws://127.0.0.1:8083/mqtt', clientId = null) {
|
constructor(brokerUrl = 'ws://127.0.0.1:8083/mqtt', clientId = null) {
|
||||||
this.clientId = clientId || 'vue-client-' + Math.random().toString(16).substr(2, 8)
|
this.clientId = clientId || 'vue-client-' + Math.random().toString(16).substr(2, 8)
|
||||||
this.client = mqtt.connect(brokerUrl, { clientId: this.clientId })
|
this.client = mqtt.connect(brokerUrl, { clientId: this.clientId, protocolVersion: 5})
|
||||||
this.subscriptions = [] // array of {topic, callback}
|
this.subscriptions = [] // array of {topic, callback}
|
||||||
|
|
||||||
this.client.on('connect', () => console.log('Connected to MQTT broker'))
|
this.client.on('connect', () => console.log('Connected to MQTT broker'))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user