From ba0b5cdf5c49a54d8bc6248b73a9b7858509b73b Mon Sep 17 00:00:00 2001 From: Jono Targett Date: Sun, 15 Mar 2026 23:05:23 +1030 Subject: [PATCH] frontend is fucked --- dashboard/src/App.vue | 142 +++++++++++++-------------------- dashboard/src/PropertyTree.vue | 70 ++++++++++++++++ dashboard/src/services/mqtt.js | 20 ++++- 3 files changed, 140 insertions(+), 92 deletions(-) create mode 100644 dashboard/src/PropertyTree.vue diff --git a/dashboard/src/App.vue b/dashboard/src/App.vue index 28c0f95..6bbbc0e 100644 --- a/dashboard/src/App.vue +++ b/dashboard/src/App.vue @@ -1,119 +1,85 @@ - \ No newline at end of file + handleStatus(payload, topic) { + const deviceId = topic.split('/')[1] + if (!this.devices[deviceId]) this.devices[deviceId] = { property: {}, status: null } + this.devices[deviceId].status = payload + }, + + handleProperty(payload, topic) { + const parts = topic.split('/') + const deviceId = parts[1] + const propertyPath = parts.slice(3) // after asset/device/property/... + if (!this.devices[deviceId]) this.devices[deviceId] = { property: {}, status: null } + + // traverse/create tree + let node = this.devices[deviceId].property + propertyPath.forEach((p, i) => { + if (i === propertyPath.length - 1) { + // leaf + node[p] = { value: payload, updated: Date.now() } // flash on update + } else { + if (!node[p]) node[p] = {} + node = node[p] + } + }) + }, + }, +} + \ No newline at end of file diff --git a/dashboard/src/PropertyTree.vue b/dashboard/src/PropertyTree.vue new file mode 100644 index 0000000..0dbe009 --- /dev/null +++ b/dashboard/src/PropertyTree.vue @@ -0,0 +1,70 @@ + + + \ No newline at end of file diff --git a/dashboard/src/services/mqtt.js b/dashboard/src/services/mqtt.js index 6f8879a..c3d8018 100644 --- a/dashboard/src/services/mqtt.js +++ b/dashboard/src/services/mqtt.js @@ -1,23 +1,35 @@ import mqtt from 'mqtt' export default class MQTTService { - constructor(brokerUrl = 'ws://localhost: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.client = mqtt.connect(brokerUrl, { clientId: this.clientId }) - this.subscriptions = {} + this.subscriptions = [] // array of {topic, callback} this.client.on('connect', () => console.log('Connected to MQTT broker')) this.client.on('message', (topic, payload) => { - if (this.subscriptions[topic]) this.subscriptions[topic](payload.toString(), topic) + // iterate over subscriptions and check for matches + this.subscriptions.forEach(({topic: subTopic, callback}) => { + if (mqttMatch(subTopic, topic)) { + callback(payload.toString(), topic) + } + }) }) } subscribe(topic, callback) { - this.subscriptions[topic] = callback + this.subscriptions.push({topic, callback}) this.client.subscribe(topic) } publish(topic, message, options = {}) { this.client.publish(topic, message, options) } +} + +// helper function for MQTT wildcards +function mqttMatch(subTopic, topic) { + // replace MQTT wildcards with RegExp + const regex = '^' + subTopic.replace('+', '[^/]+').replace('#', '.+') + '$' + return new RegExp(regex).test(topic) } \ No newline at end of file