MQTT, payload, JSON and wanting to check

(Sort of following on from my other post/question)

What I know about MQTT:

1 - basically the payload is the only part of the message that is sent to the other end.
(that's about it)

If you want to send other stuff, you need to construct a special message where the payload is not just text.

JSON node/s.

Way back when I first started (and this may be wrong) if you wanted to send fancy mesasges through MQTT you would have to use a JSON node going in and coming out of the MQTT node. WAS (Past tense)

Seems now the newer version/s of the nodes have auto detect and so you don't need to use the JSON nodes as before.

But I've just annoyed Sean (well: he helped me) with getting something that should be easy to work.

Given I have (example) a message like this:
{"payload":"2022-12-29 12:05:09 Main - Up"}
and
{"state":"Online"}
and I want BOTH of these to go through MQTT. How do I do it?

Seems my old way works:
Put it into a function node - code:

let msg2 = {};
msg2.payload = {"payload":msg.payload,"state":msg.state};
return msg2;

Then at the other end I get:

{"topic":"test","payload":{"payload":"2022-12-29 12:05:09 Main - Up","state":"Up"},"qos":0,"retain":false,"_topic":"test","_msgid":"d7f246aadb65e10b"}

But that isn't usable to me.
I want a payload and state. Not payload.payload and payload.state.
I seem to remember that the JSON node was the answer. But it is no longer.
I have to basically do the opposite to what I did at the other end.

let msg2 = {};
msg2 = msg.payload;
return msg2;

And I guess: Fair enough.

But I can't believe that .... 4 years ago (nominal, maybe more) I got this right and BEFORE it was how to do it.

No: I'm not boasting. I'm confused.

Where's the elephant I'm missing?

This is correct - the payload can be a single value OR an object (containing more values) but only one or the other, not both.

So something like what I showed (here) is the solution?

1 Like

Personally I would try to avoid having msg.payload.payload.

"payload" is the [only] element of a message which is transmitted through MQTT, but within payload there can be any number of elements.
I think their names should describe what the data is, and another "payload" has no place here.

Further, within

{
"payload":"2022-12-29 12:05:09 Main    - Up"
}

the timestamp is one data item and "Main - Up" is another, So I would change it to something like this

msg.payload = {
   "timestamp": "2022-12-29 12:05:09", 
   "event": "Main    - Up", 
   "state": msg.state
}

When msg.payload arrives at the destination, the data is available as msg.payload.timestamp, msg.payload.event and msg.payload.state

2 Likes

Yes, and I fully agree.

But this stuff started about...... 7 years ago.

Back then, I w

Ok, what's going on in THIS case.

Every now and then a pulse is sent and a scan of WAPs happens.
I scan for mine and make reports.
So the time is .... obvious for what it is, and doing.
The event part is the WAP of interest name.
That is stuck on the end (text mode) of the timestamp.
Then the Up/Down is the state.
Again, I simply stuck it on the end of the message because back then, I only had a very basic network.

As time went on, I introduced redundancy and so things got complicated.
And I scan for multiple WAPs.
Because now I have 3 machines running a triumbrant (?) they need to share their information.
That means sharing information.

I may have to sit down and rewrite the structure but just now that is not viable as I am still rebuilding my network. As in: layout, and addresses. I've been caught out a few times already with old IP addresses not responding and wasting a bit of time trying to work out what is going on.
So I think I need to get that part working before I do this stuff.

But thanks for the idea on the structure.

What is the point of that in MQTT? state should probably be the end of a topic something like devices/mydevice01/state and it can then simple have a value of online or offline.

image

So above is an example from one of my ESP custom sensor platforms where topic ESP/D1M05 has the status showing and then lower level topics have details. That way, if you are viewing the hierarchy in something like MQTT Explorer, you don't have to expand it just to see if something is online or not.

Or another example showing switch status:

image

The important info is on the main topic with sub-topics containing more details.

Only if I want to dump a load of reference info would I output JSON to MQTT as in this example:

image

In fact, a node-red flow restructures all of that data into more useful topic structures, I only keep this raw data for debugging and out of interest to see how many 433MHz devices my RFXtrx433e dongle can pick up over time! :slight_smile:


As for the conversion, you can just output JSON direct to the MQTT out node. Then you can ask the MQTT in node to try to make sense of inputs. No JSON nodes needed any more.

That looks nice too for structure.

But I may take on what was suggested with a structured payload containing the time, device and state as objects in it.

The MQTT only came about a fair way down the track.
Reformatting the payload how @jbudd suggested looks nicer and better for my needs.

I am torn between keeping it simple - which is what I may have done here in THIS case - and over complicating things as I also do in other scenarios.

Thanks though.