mirror of
https://github.com/lehanspb/tuya-mqtt.git
synced 2025-12-18 16:17:30 +00:00
Color support for HSBHEX
This commit is contained in:
@@ -190,7 +190,7 @@ class TuyaDevice {
|
|||||||
// Process MQTT commands for all command topics at device level
|
// Process MQTT commands for all command topics at device level
|
||||||
async processCommand(message, commandTopic) {
|
async processCommand(message, commandTopic) {
|
||||||
const command = this.getCommandFromMessage(message)
|
const command = this.getCommandFromMessage(message)
|
||||||
if (commandTopic === 'command' && command === 'get-states' ) {
|
if (commandTopic === 'command' && command === 'get-states') {
|
||||||
// Handle "get-states" command to update device state
|
// Handle "get-states" command to update device state
|
||||||
debug('Received command: ', command)
|
debug('Received command: ', command)
|
||||||
await this.getStates()
|
await this.getStates()
|
||||||
@@ -324,7 +324,10 @@ class TuyaDevice {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'hsb':
|
case 'hsb':
|
||||||
tuyaCommand.set = this.convertToTuyaHsbColor(command, deviceTopic)
|
tuyaCommand.set = this.convertToTuyaHsbColor(command, deviceTopic.components)
|
||||||
|
break;
|
||||||
|
case 'hsbhex':
|
||||||
|
tuyaCommand.set = this.convertToTuyaHsbHexColor(command, deviceTopic.components)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (tuyaCommand.set === '!!!INVALID!!!') {
|
if (tuyaCommand.set === '!!!INVALID!!!') {
|
||||||
@@ -340,28 +343,31 @@ class TuyaDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Takes Tuya color value in HSB or HSBHEX format and updates
|
// Takes Tuya color value in HSB or HSBHEX format and updates
|
||||||
// cached device HSB color state
|
// cached HSB color state for device
|
||||||
updateColorState(value) {
|
updateColorState(value) {
|
||||||
let h, s, b
|
let h, s, b
|
||||||
if (this.config.colorType === 'hsbhex') {
|
if (this.config.colorType === 'hsbhex') {
|
||||||
[, h, s, b] = (value || '0000000000ffff').match(/^.{6}([0-9a-f]{4})([0-9a-f]{2})([0-9a-f]{2})$/i) || [0, '0', 'ff', 'ff'];
|
[, h, s, b] = (value || '0000000000ffff').match(/^.{6}([0-9a-f]{4})([0-9a-f]{2})([0-9a-f]{2})$/i) || [0, '0', 'ff', 'ff'];
|
||||||
|
this.state.color.h = parseInt(h, 16)
|
||||||
|
this.state.color.s = Math.round(parseInt(s, 16) / 2.55) // Convert saturation to 100 scale
|
||||||
|
this.state.color.b = Math.round(parseInt(b, 16) / .255) // Convert brightness to 1000 scale
|
||||||
} else {
|
} else {
|
||||||
[, h, s, b] = (value || '000003e803e8').match(/^([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})$/i) || [0, '0', '3e8', '3e8']
|
[, h, s, b] = (value || '000003e803e8').match(/^([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})$/i) || [0, '0', '3e8', '3e8']
|
||||||
|
// Convert from Hex to Decimal and cache values
|
||||||
|
this.state.color.h = parseInt(h, 16)
|
||||||
|
this.state.color.s = Math.round(parseInt(s, 16) / 10) // Convert saturation to 100 Scale
|
||||||
|
this.state.color.b = parseInt(b, 16) // Convert brightness to 1000 scale
|
||||||
}
|
}
|
||||||
// Convert from Hex to Decimal and cache values
|
|
||||||
this.state.color.h = parseInt(h, 16)
|
|
||||||
this.state.color.s = Math.round(parseInt(s, 16) / 10)
|
|
||||||
this.state.color.b = parseInt(b, 16)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes provided decimal HSB components from MQTT topic, combines with any
|
// Takes provided decimal HSB components from MQTT topic, combines with any
|
||||||
// cached (unchanged) component values and converts to Tuya HSB format
|
// cached (unchanged) component values and converts to Tuya HSB format
|
||||||
convertToTuyaHsbColor(value, topic) {
|
convertToTuyaHsbColor(value, components) {
|
||||||
// Start with cached color values
|
// Start with cached color values
|
||||||
const newColor = this.state.color
|
const newColor = this.state.color
|
||||||
|
|
||||||
// Update any HSB component with a changed value
|
// Update any HSB component with a changed value
|
||||||
const components = topic.components.split(',')
|
components = components.split(',')
|
||||||
const values = value.split(',')
|
const values = value.split(',')
|
||||||
for (let i in components) {
|
for (let i in components) {
|
||||||
newColor[components[i]] = Math.round(values[i])
|
newColor[components[i]] = Math.round(values[i])
|
||||||
@@ -372,6 +378,48 @@ class TuyaDevice {
|
|||||||
return hexColor
|
return hexColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
convertToTuyaHsbHexColor(value, components) {
|
||||||
|
// Start with cached color values
|
||||||
|
const newColor = this.state.color
|
||||||
|
|
||||||
|
// Update any HSB component with a changed value
|
||||||
|
components = components.split(',')
|
||||||
|
const values = value.split(',')
|
||||||
|
for (let i in components) {
|
||||||
|
newColor[components[i]] = Math.round(values[i])
|
||||||
|
}
|
||||||
|
let {h, s, b} = newColor
|
||||||
|
const hsb = h.toString(16).padStart(4, '0') + Math.round(2.55 * s).toString(16).padStart(2, '0') + Math.round(b * .255).toString(16).padStart(2, '0');
|
||||||
|
h /= 60;
|
||||||
|
s /= 100;
|
||||||
|
b *= .255;
|
||||||
|
const
|
||||||
|
i = Math.floor(h),
|
||||||
|
f = h - i,
|
||||||
|
p = b * (1 - s),
|
||||||
|
q = b * (1 - s * f),
|
||||||
|
t = b * (1 - s * (1 - f)),
|
||||||
|
rgb = (() => {
|
||||||
|
switch (i % 6) {
|
||||||
|
case 0:
|
||||||
|
return [b, t, p];
|
||||||
|
case 1:
|
||||||
|
return [q, b, p];
|
||||||
|
case 2:
|
||||||
|
return [p, b, t];
|
||||||
|
case 3:
|
||||||
|
return [p, q, b];
|
||||||
|
case 4:
|
||||||
|
return [t, p, b];
|
||||||
|
case 5:
|
||||||
|
return [b, p, q];
|
||||||
|
}
|
||||||
|
})().map(c => Math.round(c).toString(16).padStart(2, '0')),
|
||||||
|
hex = rgb.join('');
|
||||||
|
|
||||||
|
return hex + hsb;
|
||||||
|
}
|
||||||
|
|
||||||
// Set white/colour mode based on target mode
|
// Set white/colour mode based on target mode
|
||||||
async setLight(topic, command) {
|
async setLight(topic, command) {
|
||||||
let targetMode = undefined
|
let targetMode = undefined
|
||||||
|
|||||||
Reference in New Issue
Block a user