Unexpected token D in JSON at position 0

Generally each topic should be used for a particular piece of information, the value of a particular sensor, a status string about something and so on. It is not a good idea to have a general 'out' topic that is used to send different types of information.

Well the quick solution would be to send the original message in a JSON format, otherwise I have to change all my flows. The domoticz/out topic also receives messages from devices in domoticz (which are all in JSON format) and I need some device messages as well in this particular flow

But can I use 2 mqtt nodes in one flow? one for JSON and one for String messages then?

after this I want to create a function node which does something like:

if (msg.payload.idx == '243') {
  if (msg.payload.nvalue == '1' && msg = 'De frietpan is aangezet!'){

  }
}

You can subscribe to one topic as often as you want. What @Colin says is right in an ideal scenario each topic would be for one purpose, eg a sensor or a light state. But I also have had the circumstances where I had to use one topic as a kind of wildcard where all information from another system arrives. So if it is hard for you to change this on the domotics side than you will have to do some filtering on the Nodered side.

This doesnt work. your treating your msg object like a string and a js object at the same time. This can not be.
You are only sending a string or a json at a time right?

you can use a function node with try...catch and JSON.parse() instead of the JSON parser node to sort out the strings there.

Hoi Gerben,

De volgende links zijn de moeite waard om eerst te lezen, voordat je verder gaat.


https://nodered.org/docs/user-guide/messages

Als een payload beschikbaar is als string in JSON formaat, de mqtt out met json setting, of json node, kan deze omgezet worden in een JavaScript object. Als de string niet in json formaat is, krijg je de error die je al gezien hebt.

Een andere tip is om je (debug) nodes een naam te geven, zodat je ze makkelijk terug kan vinden en weet welk bericht in de debug zijbalk waarbij hoort zonder het ID op te hoeven

1 Like

I already noticed, the easiest way is to change my dzVents script in domoticz to send the messages to MQTT in JSON format

heel goed :+1:

Then please make sure that all messages published to the same topic arrive in the same format, you’d spare yourself a lot of work and mental struggles.

Or use something like this instead of the Json parser node:

[{"id":"9f0f80da.d115c8","type":"function","z":"ed7ded5f.9a395","name":"JSON or String","func":"try{\n    msg.payload = JSON.parse(msg.payload);\n    return [msg, null];\n}\ncatch(error){\n    return [null, msg];\n}","outputs":2,"noerr":0,"x":360,"y":580,"wires":[["2b701117.423716"],["9dbceb14.8e76b8"]]},{"id":"a235aa0e.32adb8","type":"inject","z":"ed7ded5f.9a395","name":"A JSON string","topic":"","payload":"{\"test\": \"i am a json\"}","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":540,"wires":[["9f0f80da.d115c8"]]},{"id":"6577a3e.36d2bdc","type":"inject","z":"ed7ded5f.9a395","name":"A string string","topic":"","payload":"i am a string","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":620,"wires":[["9f0f80da.d115c8"]]},{"id":"2b701117.423716","type":"debug","z":"ed7ded5f.9a395","name":"JSON","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":570,"y":540,"wires":[]},{"id":"9dbceb14.8e76b8","type":"debug","z":"ed7ded5f.9a395","name":"String","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":570,"y":620,"wires":[]}]


it’s a very simple function:

try{
    msg.payload = JSON.parse(msg.payload);
    return [msg, null];
}
catch(error){
    return [null, msg];
}

Johannes

1 Like

Hi,

I changed the message format in the domoticz script code to a JSON format.
Now I have the following incoming message (without JSON errors):

13-4-2020 09:41:49node: 728933bc.7037dc
domoticz/out : msg.payload : Object
object
bericht: "De frietpan is aangezet!"

Since I am a beginner and my node-red abilities are still under construction :wink: I have a question:
I want to write a function node which does a string comparison.
I tried this, but obviously the Debug node, does not return anything.

if (msg.payload.bericht == 'De frietpan is klaar om te frituren!') {
      
      node.send(msgFrietpanKlaar);

      setTimeout(function(){
        node.send(msgVolumeBack);
      }, 7000);
      
}

How do you compare a string value in javascript?

The string comparison looks fine. But it’s a different string than the one in the debug?

?
And I assume that the is not the whole function node. Where do you define the objects you use in the node.send() functions?

Oh sorry,

From the domoticz script actually 4 messages could be send:

local msgAan = 'De frietpan is aangezet!'
local msgKlaar = 'De frietpan is klaar om te frituren!' (send with a 15 minutes delay)
local msgWordt = 'De frietpan staat nog aan en wordt nu uitgezet!' (send with a 60 minutes delay)
local msgUit = 'De frietpan is uitgezet!'

But in the node-red flow I only want to respond on the second and the third message. (the message you saw was a test if the message correctly was incoming in JSON format.)

The idea is that when the Frietpan Switch is turned on I receive a message after 15 minutes that the 'De frietpan is klaar om te frituren!' and if the Frietpan switch is still on after 60 minutes, it will be turned off automatically. This is all working in domoticz fine. The messages above are send to Telegram, but I want to use the messages also in node-red for voice messaging to my google home devices.

The full flow looks like this:

The Function code like this:

var msgFrietpanKlaar = {
    "url": "http://192.168.1.51:1880/frietpan-klaar",
    "contentType": "audio/mp3",
    "volume": 60
}

var msgFrietpanNogAan = {
    "url": "http://192.168.1.51:1880/frietpan-nog-aan",
    "contentType": "audio/mp3",
    "volume": 60
}

var msgVolumeBack = {
    "volume": 30
}

if (msg.payload.bericht == 'De frietpan is klaar om te frituren!') {
      
      node.send(msgFrietpanKlaar);

      setTimeout(function(){
        node.send(msgVolumeBack);
      }, 7000);
      
}

if (msg.payload.bericht == 'De frietpan staat nog aan en wordt nu uitgezet!') {
      
      node.send(msgFrietpanNogAan);

      setTimeout(function(){
        node.send(msgVolumeBack);
      }, 7000);
      
}

but when I test the switch the node-red function node only returns: undefined

Have you switched your debug to show you the whole message object? You can do this in the menu of the debug node you attached to the function.

You are not returning a msg.payload so if you have a debug node set to display msg.payload it will get an 'undefined'

Ah OK, after I set the debug node to "complete msg object" I see all messages in the debug.
This seems to work corrrectly.

Do I have to change the function then to debug correctly to the msg.payload then? And if so how to do this?

There is no real need to move it to msg payload but it’s very easy to do.
instead of node.send(yourmsgobject) use node.send({payload:yourmsgobject})
Johannes

Rather than using complex stuff like setTimeout in a node you might be better to use a Switch node to route the different messages down different paths then Change nodes to setup the data and Trigger to send one message then after the interval to send the other.

1 Like

Your right, I only want to see in the debug node the messages of the cast node, which are returned correctly now thanx!