If you work with modern building automation, you know that bridging the gap between a technical backend and a sleek, user-friendly frontend can sometimes require a little bit of custom engineering.
Recently, I was looking for a flawless way to control DALI2 DT8 RGBW luminaires through a graphical interface. Specifically, I needed a solution for Node-RED Dashboard 2.0 that communicates directly with the KNX Ultimate node using the 6-byte combined group object (DPT 251.600 Color Triplet).
Standard dashboard color pickers often struggle with the separate white channel or don't format the payload exactly as the KNX bus expects. To solve this, I built a custom Template node utilizing Vuetify, and I’m sharing the code so you can drop it straight into your own projects.
The ETS 6 Setup
Before diving into Node-RED, ensure your actuator (or DALI gateway) is properly configured in ETS 6. You want to use the combined 6-byte group object for RGBW. This allows us to send the red, green, blue, and white values—along with their validity masks—in a single telegram, keeping bus traffic incredibly efficient.
The Node-RED Flow
The beauty of this setup is its simplicity. You only need two nodes:
The KNX Ultimate Device Node (Set to your group address and DPT 251.600).
You just wire the Template node directly into the KNX Ultimate node. No intermediate function nodes or payload formatting are required—the template handles all the logic.
The Custom Code
Inside your Dashboard 2.0 Template node, paste the following code. It utilizes a standard Vuetify RGB color picker alongside a dedicated slider for the White (W) channel.
<template>
<v-card flat class="bg-transparent pa-2">
<!-- Vuetify RGB Color Picker -->
<v-color-picker
v-model="color"
mode="rgb"
hide-inputs
elevation="0"
width="100%"
></v-color-picker>
<!-- Separate White Channel (W) -->
<div class="pt-4">
<div class="text-caption mb-1">Hvid Kanal (W)</div>
<v-slider
v-model="white"
min="0"
max="255"
step="1"
thumb-label
color="blue-grey-darken-1"
></v-slider>
</div>
</v-card>
</template>
<script>
export default {
data() {
return {
// Start with a HEX string, as it is most stable for Vuetify 3
color: '#ffffff',
white: 0
}
},
watch: {
// Watchers keep an eye with the changes in our data
color(newVal) {
this.sendToKNX();
},
white(newVal) {
this.sendToKNX();
}
},
methods: {
// This function makes sure we always get R,G,B no matter the format Vuetify delivers
parseColor(c) {
if (typeof c === 'object') {
return { r: c.r || 0, g: c.g || 0, b: c.b || 0 };
}
if (typeof c === 'string') {
if (c.startsWith('#')) {
let hex = c.substring(1);
if (hex.length === 3) hex = hex.split('').map(x => x + x).join('');
return {
r: parseInt(hex.substring(0, 2), 16) || 0,
g: parseInt(hex.substring(2, 4), 16) || 0,
b: parseInt(hex.substring(4, 6), 16) || 0
};
} else if (c.startsWith('rgb')) {
const vals = c.match(/\d+/g);
if (vals && vals.length >= 3) {
return {
r: parseInt(vals[0]),
g: parseInt(vals[1]),
b: parseInt(vals[2])
};
}
}
}
return { r: 0, g: 0, b: 0 }; // Fallback if anything goes wrong
},
sendToKNX() {
const rgb = this.parseColor(this.color);
const knxPayload = {
red: Math.floor(rgb.r),
green: Math.floor(rgb.g),
blue: Math.floor(rgb.b),
white: Math.floor(this.white),
mR: 1,
mG: 1,
mB: 1,
mW: 1
};
// Sends directly to the next node
this.send({
payload: knxPayload
});
}
}
}
</script>
Why This Works So Well
The magic here happens in the sendToKNX() method. KNX Ultimate requires a very specific JSON object for the 251.600 datapoint. It doesn't just need the color values (red, green, blue, white); it also requires the mask bits (mR, mG, mB, mW).
By setting these mask bits to 1, we are explicitly telling the KNX bus: "Yes, these color channel values are valid, please apply them." The Vue.js watcher functions ensure that the moment a user drags a color hue or adjusts the white slider, the parsed values are instantly packaged and fired off to the bus.
It provides an incredibly responsive, tactile experience for end-users, while remaining lightweight and reliable under the hood.
Kommentarer
Send en kommentar