Tuya Smart Device wont hold dps values

I'm attempting to change the color of my light from its current setting to blue. When i try to set it to blue it sets dps 21 to "colour", then it sets dps 21 to "white", then it sets dps 24 to "333303E803E8" which is blue. When i stand alone set dps 21 it works fine but when i try to pass it while setting the color it does not work.

[
    {
        "id": "743e6a9b8f1b9fdb",
        "type": "tab",
        "label": "Flow 3",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "409b64dd2bad8dd4",
        "type": "tuya-smart-device",
        "z": "743e6a9b8f1b9fdb",
        "deviceName": "Bulb 1",
        "disableAutoStart": false,
        "deviceId": "ebf0dc9fa05d7ef0adhgxj",
        "deviceKey": "a9ecc12e4cfeb715",
        "storeAsCreds": false,
        "deviceIp": "",
        "retryTimeout": 1000,
        "findTimeout": 10000,
        "tuyaVersion": "3.3",
        "eventMode": "event-both",
        "x": 850,
        "y": 300,
        "wires": [
            [
                "4b8255b97dd9ae05"
            ],
            []
        ]
    },
    {
        "id": "4b8255b97dd9ae05",
        "type": "debug",
        "z": "743e6a9b8f1b9fdb",
        "name": "debug 24",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1120,
        "y": 300,
        "wires": []
    },
    {
        "id": "e189b267d15c7d3e",
        "type": "inject",
        "z": "743e6a9b8f1b9fdb",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{     multiple: true,     data: {         '20': true,         '22': Brightness,         '24': \"666603E803E8\"              } }",
        "payloadType": "jsonata",
        "x": 370,
        "y": 300,
        "wires": [
            [
                "0313a49d46ca1cbb"
            ]
        ]
    },
    {
        "id": "0313a49d46ca1cbb",
        "type": "function",
        "z": "743e6a9b8f1b9fdb",
        "name": "function 6",
        "func": "msg.payload = {\n    multiple: true,\n    data: {\n        '20': true,\n        '21': \"colour\",\n        '22': 1000,\n        '24': \"333303E803E8\"\n\n    }\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 540,
        "y": 300,
        "wires": [
            [
                "409b64dd2bad8dd4",
                "7c0284c86cb1a8a8"
            ]
        ]
    },
    {
        "id": "7c0284c86cb1a8a8",
        "type": "debug",
        "z": "743e6a9b8f1b9fdb",
        "name": "debug 25",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 940,
        "y": 240,
        "wires": []
    }
]

Here is the debug log

Mine does the same. I hadn't noticed because I always send the commands individually

[Edit] I just realised why the problem occurs. Omit the brightness value (22) and you can then send the rest of the values. This is because the Tuya colour includes a brightness factor.

The Tuya colour is defined as Color: hexstring - h:0-360, s:0-1000, v:0-1000 or hsv (s & v * 10)

HSV (for hue, saturation, value ; also known as HSB , for hue, saturation, brightness )

I’ve tried passing an HSV value to the Bulb before however it wouldn’t take it and I had to find a “HSVtoTuya” function on discord and it finally worked. Do you mind sending your node for setting color?

You can't just pass an HSV Object to a Tuya lamp (it HAS to be a string), you have to do as you have already done, use an HSVtoTuya function. These are the functions that I use, but as I said they are probably the same, or similar, to the one you already found.

To use;

let colour = TuyaColourToHSV({h: 360, s: 100, v: 100})

or

let colour = TuyaColourToHSV(360, 100, 100})
	/******************************************************************************
	* Description	Converts an HSV colour value to Tuya hexadecimal colour.
	* 
	* 				Assumes Hue in set [0, 360], Saturation and Value in the set [0, 100] and
	* 				returns Tuya colour as 12 character hexadecimal string
	* 
	*
	* @param   {Object | number} hue    - The hue as an integer or an HSV Object {hue, saturation, value})
	* @param   {number} [saturation]	- The saturation
	* @param   {number} [value]       	- The value
	* 
	* @returns {string}             	- A 12 character hexadecimal string as used by Tuya devices for colour
	* 
	* Note: To convert RGB colour to Tuya colour use RGBtoHSV() as input
	*/

	function HSVtoTuyaColour(hue, saturation, value) {
		// Note: hue = hue.hue MUST go last
		if (arguments.length === 1) {
			saturation = hue.saturation;
			value = hue.value;
			hue = hue.hue;

		}

		// Increase saturation & value to correct set [0, 1000]
		saturation = saturation * 10;
		value = value * 10;

		return HSVtoHexStr(hue, saturation, value);

	} // End Function HSVtoTuyaColour()


	/******************************************************************************
	* Description	Converts a Tuya hexadecimal colour to an HSV colour .
	* 
	* 				Assumes Tuya colour hexadecimal representation: Hue in set [0, 360], Saturation and Value in the set [0, 1000]
	* 				returns an Object containing HSV hue, saturation and value
	* 
	*
	* @param   {string}	tuyaString	- Tuya colour as 12 character hexadecimal string
	* 
	* @returns {object}           	- The HSV representation of the tuya colour string
	* 
	* Note: To convert Tuya colour to RGB use HSVtoRGB()
	*/

	function TuyaColourToHSV(tuyaString) {
		let hue = hexToInteger(tuyaString.slice(0, 4), 4);
		let saturation = hexToInteger(tuyaString.slice(4, 8), 4) / 10;
		let value = hexToInteger(tuyaString.slice(8, 12), 4) / 10;

		return { hue: hue, saturation: saturation, value: value };

	} // End Function TuyaColourToHSV()


	/******************************************************************************
	* Helper functions for HSVtoTuyaColour. Internal function only
	*/
	/******************************************************************************
	* Description	Converts an HSV colour value to hexadecimal string.
	* 
	* 				Assumes Hue in set [0, 360], Saturation and Value in the set [0, 100]
	* 				returns a 12 digit containing HSV hue, saturation and value
	* 
	*
	* @param   {number}	hue			- HSV hue
	* @param   {number}	saturation	- HSV saturation
	* @param   {number} value		- HSV value (brightness)
	* 
	* @returns {object}           	- The HSV representation
	* 
	* Note: To convert Tuya colour to RGB use HSVtoRGB()
	*/

	function HSVtoHexStr(hue, saturation, value) {
		let a = integerToHex(hue, 4);
		let b = integerToHex(saturation, 4);
		let c = integerToHex(value, 4);

		return a + b + c;

	} // End Function HSVtoHexStr()

ok here's another one you can help with with dsp values if you don't mind.

ive set up the below code and it will only work one time after setting the light from "white" to "colour". Once you select another color it set the light to red. If i change the light from "colour" to "white" and the back to "colour" it works once and then goes back to red.

[
    {
        "id": "12f06957174e6d8b",
        "type": "ui_iro-color-picker",
        "z": "743e6a9b8f1b9fdb",
        "group": "01b31b4514201e32",
        "order": 2,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Color",
        "placement": "above",
        "hAlign": "center",
        "vAlign": "flex-start",
        "stateField": "payload",
        "enableField": "enable",
        "layoutDirection": "vertical",
        "widgetIndent": "3",
        "buttonWidth": "2",
        "pickerType": "widget",
        "popupWidth": 0,
        "popupHeight": 0,
        "pickerSize": "100",
        "backgroundDim": "50",
        "backgroundColor": "#000000",
        "backgroundVariable": false,
        "components": [
            {
                "options": {
                    "borderColor": "#000000",
                    "borderWidth": 0,
                    "sliderType": "hue"
                },
                "componentId": "slider"
            }
        ],
        "format": "hex",
        "outFormat": "hsva",
        "dynOutput": "input:move",
        "outputConfirmed": false,
        "outputLimit": "10",
        "passthru": false,
        "topic": "topic",
        "topicType": "msg",
        "iroColorValue": "#ff0000",
        "x": 210,
        "y": 120,
        "wires": [
            [
                "32c150bb75d17a47"
            ]
        ]
    },
    {
        "id": "32c150bb75d17a47",
        "type": "function",
        "z": "743e6a9b8f1b9fdb",
        "name": "",
        "func": "const colourValue = msg.payload\n\nmsg.payload = HSVtoTuyaColour(colourValue.h, colourValue.s * 100, colourValue.v * 100)\n\nreturn msg;\n\nfunction HSVtoTuyaColour(hue, saturation, value) {\n\t\t// Note: hue = hue.hue MUST go last\n\t\tif (arguments.length === 1) {\n\t\t\tsaturation = hue.saturation;\n\t\t\tvalue = hue.value;\n\t\t\thue = hue.hue;\n\n\t\t}\n\n\t\t// Increase saturation & value to correct set [0, 1000]\n\t\tsaturation = saturation * 10;\n\t\tvalue = value * 10;\n\n\t\treturn HSVtoHexStr(hue, saturation, value);\n}\n\nfunction HSVtoHexStr(hue, saturation, value) {\n\t\tlet a = decimalToHex(hue, 4);\n\t\tlet b = decimalToHex(saturation, 4);\n\t\tlet c = decimalToHex(value, 4);\n\n\t\treturn a + b + c;\n\n\t}\n\t\nfunction decimalToHex(decimal, padCount = 2) {\n\t\treturn (decimal + Math.pow(16, padCount)).toString(16).slice(-padCount).toUpperCase();\n\n\t}",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 440,
        "y": 140,
        "wires": [
            [
                "4e5355d07b165ffe"
            ]
        ]
    },
    {
        "id": "4e5355d07b165ffe",
        "type": "function",
        "z": "743e6a9b8f1b9fdb",
        "name": "Change Color",
        "func": "msg.payload = { \n    dps : 24,\n    set: msg.payload\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 660,
        "y": 160,
        "wires": [
            [
                "409b64dd2bad8dd4"
            ]
        ]
    },
    {
        "id": "409b64dd2bad8dd4",
        "type": "tuya-smart-device",
        "z": "743e6a9b8f1b9fdb",
        "deviceName": "Bulb 1",
        "disableAutoStart": false,
        "deviceId": "ebf0dc9fa05d7ef0adhgxj",
        "deviceKey": "a9ecc12e4cfeb715",
        "storeAsCreds": false,
        "deviceIp": "",
        "retryTimeout": 1000,
        "findTimeout": 10000,
        "tuyaVersion": "3.3",
        "eventMode": "event-both",
        "x": 850,
        "y": 300,
        "wires": [
            [
                "4b8255b97dd9ae05"
            ],
            []
        ]
    },
    {
        "id": "4b8255b97dd9ae05",
        "type": "debug",
        "z": "743e6a9b8f1b9fdb",
        "name": "debug 24",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1120,
        "y": 300,
        "wires": []
    },
    {
        "id": "01b31b4514201e32",
        "type": "ui_group",
        "name": "Group 2",
        "tab": "55fc523dff6802a8",
        "order": 2,
        "disp": true,
        "width": 6
    },
    {
        "id": "55fc523dff6802a8",
        "type": "ui_tab",
        "name": "Debug",
        "icon": "dashboard",
        "order": 2,
        "disabled": false,
        "hidden": false
    }
]

After a quick look (will look further tomorrow) you have

msg.payload = HSVtoTuyaColour(colourValue.h, colourValue.s * 100, colourValue.v * 100)

should be

msg.payload = HSVtoTuyaColour(colourValue.h, colourValue.s, colourValue.v)

The HSVtoTuyaColour function takes care of any changes in range Increase saturation & value to correct set [0, 1000]

Also set the ouput of the color picker to HSV Object

That did not work but Here's something crazy. This works perfectly. It even has the *100 in HSVtoTuyaColour

[
    {
        "id": "948f1d9dcb7b24b1",
        "type": "ui_colour_picker",
        "z": "be4e3b92d92b72d9",
        "name": "",
        "label": "",
        "group": "722dc5ec2ff5657f",
        "format": "hsv",
        "outformat": "object",
        "showSwatch": false,
        "showPicker": true,
        "showValue": false,
        "showHue": false,
        "showAlpha": false,
        "showLightness": true,
        "square": "false",
        "dynOutput": "false",
        "order": 12,
        "width": 4,
        "height": 4,
        "passthru": true,
        "topic": "24",
        "topicType": "str",
        "className": "",
        "x": 450,
        "y": 500,
        "wires": [
            [
                "a09ebfae54e4e6af"
            ]
        ]
    },
    {
        "id": "a09ebfae54e4e6af",
        "type": "function",
        "z": "be4e3b92d92b72d9",
        "name": "",
        "func": "const colourValue = msg.payload\n\nmsg.payload = HSVtoTuyaColour(colourValue.h, colourValue.s * 100, colourValue.v * 100)\n\nreturn msg;\n\nfunction HSVtoTuyaColour(hue, saturation, value) {\n\t\t// Note: hue = hue.hue MUST go last\n\t\tif (arguments.length === 1) {\n\t\t\tsaturation = hue.saturation;\n\t\t\tvalue = hue.value;\n\t\t\thue = hue.hue;\n\n\t\t}\n\n\t\t// Increase saturation & value to correct set [0, 1000]\n\t\tsaturation = saturation * 10;\n\t\tvalue = value * 10;\n\n\t\treturn HSVtoHexStr(hue, saturation, value);\n}\n\nfunction HSVtoHexStr(hue, saturation, value) {\n\t\tlet a = decimalToHex(hue, 4);\n\t\tlet b = decimalToHex(saturation, 4);\n\t\tlet c = decimalToHex(value, 4);\n\n\t\treturn a + b + c;\n\n\t}\n\t\nfunction decimalToHex(decimal, padCount = 2) {\n\t\treturn (decimal + Math.pow(16, padCount)).toString(16).slice(-padCount).toUpperCase();\n\n\t}",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 620,
        "y": 500,
        "wires": [
            [
                "63e40fa5c3b4c0c4"
            ]
        ]
    },
    {
        "id": "63e40fa5c3b4c0c4",
        "type": "function",
        "z": "be4e3b92d92b72d9",
        "name": "Set light",
        "func": "var Brightness = global.get(\"Brightness\")\nmsg.payload = {\n    multiple: true,\n    data: {\n        '20': true,\n        '21':\"colour\",\n        '24': msg.payload\n        \n    }\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 780,
        "y": 500,
        "wires": [
            [
                "409b64dd2bad8dd4"
            ]
        ]
    },
    {
        "id": "409b64dd2bad8dd4",
        "type": "tuya-smart-device",
        "z": "be4e3b92d92b72d9",
        "deviceName": "Bulb 1",
        "disableAutoStart": false,
        "deviceId": "ebf0dc9fa05d7ef0adhgxj",
        "deviceKey": "a9ecc12e4cfeb715",
        "storeAsCreds": false,
        "deviceIp": "",
        "retryTimeout": 1000,
        "findTimeout": 10000,
        "tuyaVersion": "3.3",
        "eventMode": "event-both",
        "x": 490,
        "y": 180,
        "wires": [
            [
                "8a6f19527949c9d5",
                "2ad67d1f8552c299"
            ],
            []
        ]
    },
    {
        "id": "722dc5ec2ff5657f",
        "type": "ui_group",
        "name": "Light Control",
        "tab": "af4513c95a06c32e",
        "order": 3,
        "disp": true,
        "width": "6",
        "collapse": true,
        "className": ""
    },
    {
        "id": "af4513c95a06c32e",
        "type": "ui_tab",
        "name": "Day Room",
        "icon": "dashboard",
        "order": 1,
        "disabled": false,
        "hidden": false
    }
]

There must be something differnt about the other slider

Once I adjusted the first one, it worked for me although the colours were wrong. The standard colour picker in the second one was a much better match. (had to remove the *100 to get the right colour though)

Glad you got something that works :wink:

About colors
I have only one Tuya device that acceps color setting. For my device I use the following decode/encode functions:

context.global.datadecode.STRUCTCOLOUR = function (value) {
    //  Transforms  RRGGBB0000FFFF to object:
    //      {   "hex":"RRGGBBHHHHSSVV" }
    //  or: {   "r": RR,
    //          "g": GG,
    //          "b": BB
    //          "h":HHHH,
    //          "s": SS,
    //          "v": VV  }
    // 100% = 0x64
    // required by humidifier led
    const b = Buffer.from(value, 'hex');
    var result = {
        hex: value,
    };
    result["r"] = b.readUInt8(0);
    result["g"] = b.readUInt8(1);
    result["b"] = b.readUInt8(2);
    result["h"] = b.readUInt16BE(3)
    result["s"] = b.readUInt8(5);
    result["v"] = b.readUInt8(6);
    return (result);
};
context.global.dataencode.STRUCTCOLOUR = function (value) {
    // accepts: JSON or object
    // encode:
    //      {   "hex":"RRGGBBHHHHSSVV" }
    //  or: {   "r": RR,
    //          "g": GG,
    //          "b": BB
    //        ( "h":HHHH,
    //          "s": SS,
    //          "v": VV )  }
    // 100% = 0x64
    //  required by humidifier led
    var o = value;
    if (typeof value === 'string')
        o = JSON.parse(value);
    if ((o.hex !== undefined) && (typeof o.hex === 'string') && (o.hex.length == 14))
        return (o.hex);
    if ((o.r === undefined) || (o.g === undefined) || (o.b === undefined)) {
        throw "'value' is not valid hex|rgb object!";
    }
    var buf = Buffer.alloc(7);
    buf.writeUInt8(o.r, 0);
    buf.writeUInt8(o.g, 1);
    buf.writeUInt8(o.b, 2);
    if (o.h !== undefined) {
        buf.writeUInt16BE(o.h, 3);
        buf.writeUInt8(o.s, 5);
        buf.writeUInt8(o.v, 6);
    } else {
        buf.writeUInt16BE(0, 3);
        buf.writeUInt8(255, 5); //fixed ?
        buf.writeUInt8(255, 6); //fixed ?
    }
    return buf.toString('hex');
};

I hope that helps.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.