TypeError: Converting circular structure to JSON

Hi,
I could use some help and, if possible, a little explanation.

After quite a struggle, I managed to configure a Tuya smart plug and, with node-red-contrib-tuya-smart-device, the following flow works fine manually:

Flow
[
    {
        "id": "d79d91df60007d08",
        "type": "tuya-smart-device",
        "z": "2b2676f81a6deb7d",
        "deviceName": "Tuya Smart PLug",
        "disableAutoStart": false,
        "deviceId": "",
        "deviceKey": "",
        "storeAsCreds": true,
        "deviceIp": "192.168.42.189",
        "retryTimeout": "1001",
        "findTimeout": "2000",
        "tuyaVersion": "3.1",
        "eventMode": "event-both",
        "x": 930,
        "y": 800,
        "wires": [
            [],
            []
        ]
    },
    {
        "id": "2a21969c0c2b6363",
        "type": "function",
        "z": "2b2676f81a6deb7d",
        "name": "On/Off",
        "func": "msg.payload = {\n    \"dps\": 1,\n    \"set\": msg.payload\n}\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 710,
        "y": 800,
        "wires": [
            [
                "d79d91df60007d08"
            ]
        ]
    },
    {
        "id": "2435c40669d586b8",
        "type": "inject",
        "z": "2b2676f81a6deb7d",
        "name": "Turn On",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "true",
        "payloadType": "bool",
        "x": 520,
        "y": 780,
        "wires": [
            [
                "2a21969c0c2b6363"
            ]
        ]
    },
    {
        "id": "43b7394eecac0612",
        "type": "inject",
        "z": "2b2676f81a6deb7d",
        "name": "Turn Off",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "false",
        "payloadType": "bool",
        "x": 510,
        "y": 820,
        "wires": [
            [
                "2a21969c0c2b6363"
            ]
        ]
    }
]

So I set out to make it work with a voice command.
It seemed simple enough, so I simply did this:

Try...
[
    {
        "id": "e2f84d07b8024614",
        "type": "switch",
        "z": "2b2676f81a6deb7d",
        "name": "tuya - ON",
        "property": "payload.intent.name",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "tuyaON",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 500,
        "y": 940,
        "wires": [
            [
                "318239d590da3a83"
            ]
        ]
    },
    {
        "id": "14d0beacaa37b179",
        "type": "switch",
        "z": "2b2676f81a6deb7d",
        "name": "tuya - OFF",
        "property": "payload.intent.name",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "tuyaOFF",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 510,
        "y": 980,
        "wires": [
            [
                "77744660066f4cd9"
            ]
        ]
    },
    {
        "id": "f697fd60bbd64d66",
        "type": "function",
        "z": "2b2676f81a6deb7d",
        "name": "On/Off",
        "func": "msg.payload = {\n    \"dps\": 1,\n    \"set\": msg.payload\n}\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1030,
        "y": 960,
        "wires": [
            [
                "e920facd44b706fa"
            ]
        ]
    },
    {
        "id": "e920facd44b706fa",
        "type": "tuya-smart-device",
        "z": "2b2676f81a6deb7d",
        "deviceName": "Tuya Smart PLug",
        "disableAutoStart": false,
        "deviceId": "",
        "deviceKey": "",
        "storeAsCreds": true,
        "deviceIp": "192.168.42.189",
        "retryTimeout": "1001",
        "findTimeout": "2000",
        "tuyaVersion": "3.1",
        "eventMode": "event-both",
        "x": 1230,
        "y": 960,
        "wires": [
            [],
            []
        ]
    },
    {
        "id": "318239d590da3a83",
        "type": "change",
        "z": "2b2676f81a6deb7d",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload.intent.name",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 780,
        "y": 940,
        "wires": [
            [
                "f697fd60bbd64d66"
            ]
        ]
    },
    {
        "id": "77744660066f4cd9",
        "type": "change",
        "z": "2b2676f81a6deb7d",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload.intent.name",
                "pt": "msg",
                "to": "false",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 780,
        "y": 980,
        "wires": [
            [
                "f697fd60bbd64d66"
            ]
        ]
    }
]

But I think the payload is not converted to the right format, because I get the error :

TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Socket'
    |     property 'parser' -> object with constructor 'HTTPParser'
    --- property 'socket' closes the circle

What is this subtlety that escapes the clumsy beginner in me?

Thanks

I don't use that node so cannot comment on the format of data however it is related to the tuya node: Version 4.1.1 error Base64 string Ā· Issue #66 Ā· vinodsr/node-red-contrib-tuya-smart-device Ā· GitHub

Looking at your function:

msg.payload = {
 "dps": 1,
 "set": msg.payload
}
return msg

I can see how you are creating the circular object (assuming msg.payload going in to the function is an object)

If you really mean to include the data from the incoming msg payload into the payload of the outgoing msg them you could clone it e.g...

const clone = RED.util.cloneMessage(msg.payload)
msg.payload = {
 "dps": 1,
 "set": clone
}
return msg

I don't know if this is the right approach, but my aim is just to inject a "true" payload into the function, as the manual injection via "Turn ON/OFF" does.
I don't understand the difference between this manuel payload injection, which works, and the one I get via the "change" node, in which I was thinking of giving it this boolean "true" value.

I hope I'm making myself clear...

Otherwise, I've tried to replace my function with the one you're giving me, but I get the same error message.

Thanks for your time

Put a debug node after the change node and check that you are actually getting msg.payload = true / false

No, that's not what I get...
(intent is in French : "switch on the plug")

Summary
29/02/2024 22:50:39noeud: debug 12
msg.payload : Object
object
intent: object
name: true
confidence: 1
entities: array[0]
slots: object
empty
text: "allume la prise"
raw_text: "allume la prise"
tokens: array[3]
0: "allume"
1: "la"
2: "prise"
raw_tokens: array[3]
0: "allume"
1: "la"
2: "prise"
wakeword_id: "jarvis_raspberry-pi"
site_id: "Rhasspy"

Assuming you are supposed to be sending true or false, then that's your issue.

Ps, please use the copy value button when copying messages/payloads and please use code blocks

copying data

Thereā€™s a great page in the docs (Working with messages : Node-RED) that will explain how to use the debug panel to find the right path to any data item.

Pay particular attention to the part about the buttons that appear under your mouse pointer when you over hover a debug message property in the sidebar.

BX00Cy7yHi

posting code

In order to make code readable and usable it is necessary to surround your code with three backticks (also known as a left quote or backquote ```)

``` 
   code goes here 
```

You can edit and correct your post by clicking the pencil :pencil2: icon.

See this post for more details - How to share code or flow json

Sorry for the mess, I'll be more rigorous.

So I'm really missing something...

The manual flow

Summary
[
    {
        "id": "d79d91df60007d08",
        "type": "tuya-smart-device",
        "z": "2b2676f81a6deb7d",
        "d": true,
        "deviceName": "Tuya Smart PLug",
        "disableAutoStart": false,
        "deviceId": "",
        "deviceKey": "",
        "storeAsCreds": true,
        "deviceIp": "192.168.42.189",
        "retryTimeout": "1001",
        "findTimeout": "2000",
        "tuyaVersion": "3.1",
        "eventMode": "event-both",
        "x": 930,
        "y": 800,
        "wires": [
            [],
            []
        ]
    },
    {
        "id": "2a21969c0c2b6363",
        "type": "function",
        "z": "2b2676f81a6deb7d",
        "d": true,
        "name": "On/Off",
        "func": "msg.payload = {\n    \"dps\": 1,\n    \"set\": msg.payload\n}\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 730,
        "y": 800,
        "wires": [
            [
                "d79d91df60007d08",
                "837be6af93271176"
            ]
        ]
    },
    {
        "id": "2435c40669d586b8",
        "type": "inject",
        "z": "2b2676f81a6deb7d",
        "d": true,
        "name": "Turn On",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "true",
        "payloadType": "bool",
        "x": 520,
        "y": 780,
        "wires": [
            [
                "303cac8eee413937",
                "2a21969c0c2b6363"
            ]
        ]
    },
    {
        "id": "43b7394eecac0612",
        "type": "inject",
        "z": "2b2676f81a6deb7d",
        "d": true,
        "name": "Turn Off",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "false",
        "payloadType": "bool",
        "x": 510,
        "y": 820,
        "wires": [
            [
                "2a21969c0c2b6363"
            ]
        ]
    },
    {
        "id": "303cac8eee413937",
        "type": "debug",
        "z": "2b2676f81a6deb7d",
        "d": true,
        "name": "debug 11",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 700,
        "y": 740,
        "wires": []
    },
    {
        "id": "837be6af93271176",
        "type": "debug",
        "z": "2b2676f81a6deb7d",
        "d": true,
        "name": "debug 14",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 940,
        "y": 740,
        "wires": []
    }
]

Give this

01/03/2024 00:11:51 [noeud: debug 11]
msg.payload : boolean
true

01/03/2024 00:11:51[noeud: debug 14]
msg.payload : Object

object
dps: 1
set: true

The voice command

Summary
[
    {
        "id": "153b40c3716557f4",
        "type": "function",
        "z": "2b2676f81a6deb7d",
        "name": "On/Off",
        "func": "msg.payload = {\n    \"dps\": 1,\n    \"set\": msg.payload\n}\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 730,
        "y": 980,
        "wires": [
            [
                "60c8606a7013a1fc",
                "a0cc2f0a7d98d338"
            ]
        ]
    },
    {
        "id": "a0cc2f0a7d98d338",
        "type": "tuya-smart-device",
        "z": "2b2676f81a6deb7d",
        "deviceName": "Tuya Smart PLug",
        "disableAutoStart": false,
        "deviceId": "",
        "deviceKey": "",
        "storeAsCreds": true,
        "deviceIp": "192.168.42.189",
        "retryTimeout": "1001",
        "findTimeout": "2000",
        "tuyaVersion": "3.1",
        "eventMode": "event-both",
        "x": 1150,
        "y": 980,
        "wires": [
            [],
            []
        ]
    },
    {
        "id": "60c8606a7013a1fc",
        "type": "debug",
        "z": "2b2676f81a6deb7d",
        "name": "debug 16",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 940,
        "y": 940,
        "wires": []
    },
    {
        "id": "167827b4722ff60b",
        "type": "debug",
        "z": "2b2676f81a6deb7d",
        "name": "debug 17",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 740,
        "y": 940,
        "wires": []
    },
    {
        "id": "6eaf08e4d166d62c",
        "type": "change",
        "z": "2b2676f81a6deb7d",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 540,
        "y": 980,
        "wires": [
            [
                "167827b4722ff60b",
                "153b40c3716557f4"
            ]
        ]
    }
]

Give this

01/03/2024 00:15:50 [noeud: debug 17]
msg.payload : boolean
true

01/03/2024 00:15:50[noeud: debug 16]
msg.payload : Object

object
dps: 1
set: true

TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Socket'
    |     property 'parser' -> object with constructor 'HTTPParser'
    --- property 'socket' closes the circle

Ok, I think somewhere there must be a http request in your flow and your msg has a .res object. That tuya node is probably cloning (attempting to clone) the whole message but is NOT using the built in cloning routine and therefore falling foul of this fact.

Try setting the function to...

const m = {
  payload: {
    dps: 1,
    set: msg.payload
  }
}
return m

Note: if this works, you should report this to the node author at the link I provided in my first reply.

1 Like

Indeed, it works.

I'm having trouble understanding your explanation and I'm not sure I can clearly present the problem to the plugin's author, but at worst I'll provide him with a link to this topic.

Thanks a lot for your help !

1 Like

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