JSON Data Decisions

I am trying to make a flow so lights dim when Plex changes to playing, but only for movies. I am pulling my hair out trying to figure out how get it to work.

I am using the 'current state node for testing, but plan to use state change node for production.

It aways processes false regardless of anything.

My flow:

[{"id":"3b22a2fc5c40b416","type":"debug","z":"fd48519939a70b11","name":"IF TRUE DIM LIGHTS","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":640,"y":1240,"wires":[]},{"id":"338e5e96313e679c","type":"inject","z":"fd48519939a70b11","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":120,"y":1280,"wires":[["52bb7394c2d56475"]]},{"id":"52bb7394c2d56475","type":"api-current-state","z":"fd48519939a70b11","name":"If Living Room Roku Plex = Movie","server":"58bff01.29ea91","version":3,"outputs":2,"halt_if":"$entity().data.attributes.media_content_type = \"tvshow\"","halt_if_type":"jsonata","halt_if_compare":"jsonata","entity_id":"media_player.plex_plex_for_roku_roku_living_room","state_type":"habool","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"seconds","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":360,"y":1280,"wires":[["3b22a2fc5c40b416"],[]]},{"id":"58bff01.29ea91","type":"server","name":"Home Assistant","addon":true}]

Point 1.

Please format your code using the </> option. Node-RED flows typically contain one or more [] which is an empty array. If you post this without code-formatting the editor turns it into which is a special singular character. This renders the code un-importable.

I am going to work on the assumption that you are using the following JSONata expression:

$entity().data.attributes.media_content_type = "tvshow"

Point 2.

The HA WebSocket nodes generally offer Output properties

  • these properties (message fields) are computed as the very last operation and appear only in the output message
  • as default settings, msg.data is set to the ‘entity’ object (msg.payload to the ‘entity state’)
  • you will therefore see msg.data only in the output message

Within the node itself, the JSONata function $entity() will return the entity object. You can use this function in either the output properties, or in the conditional state test.

In simple terms $entity().state returns the state value, and $entity().attributes returns the attributes. It is a not-uncommon but incorrect assumption that ‘data’ has to be in there somewhere. You probably need

$entity().attributes.media_content_type = "tvshow"

Point 3. (for those interested)

JSONata expression evaluation has the unusual characteristic of returning nothing whatsoever if an expression does not result in a value. Asking for an array index out of range, or for an object field that does not exist, will return nothing. No error, no ‘null’, just nothing. Hence $entity().data will return nothing as ‘data’ is (in this case) not a property field of the entity object. JSONata is also very helpful and will compare nothing to “tvshow” and return false, as clearly nothing is never equal to something (or anything for that matter).

As a bonus extra, forming a conditional test for non-existence in JSONata cannot be done by testing against ‘null’ or "", and the function $exists() exists for this purpose. $exists($entity().data) should, in this case, return false, and while JSONata has an and and an or operator, it does not have a not operator, so we have to use a function for that also

$not($exists($entity().data))

will return true.

I hope this helps you retain at least some of your hair :smiley:

Thank you for the assistance. I have updated my original post with proper formatting. I didn’t see a code option originally, but it was hiding for me.

I guess I am not entirely following. I don’t need the message data in the next node realistically. I was using the JSONata expression:

$entity().data.attributes.media_content_type = "tvshow"

for the ‘If state’ logic built into the current state node and trying to use the TRUE/FALSE outputs to drive the next nodes.

Am I not thinking about this correctly? Basically if that JSONata expression evaluates true, it uses the one link, if it evaluates false it uses the other and goes nowhere.

Do note that I am using ‘tvshows’ for testing and I am validating that it is the correct entity data using the debug output.

It sounds like I potentially just need to remove the ‘data’ part and change:

$entity().data.attributes.media_content_type = "tvshow"

to

$entity().attributes.media_content_type = "tvshow"

Am I understanding that correctly?

EDIT:

Just tried it, and not I don’t get anything from either the true or false output to my debug node.

Yup, the pesky little </> is typically hidden from the edit bar when using smart phones… You have to look in the full menu to find it.

Yes, you don’t need the message data in the next node. However, everyone uses the msg.data = ‘entity’ output option to see what is in the entity object, and then assumes they need $entity().data.attributes etc to get at the attributes when using the $entity() function in JSONata inside the node.

Yes, if you set the State condition to use JSONata expression, this must be a valid JSONata expression that returns either true or false, and this outcome will direct the output message to either the top (true) or the bottom (false) exit.

Yes, you just need to remove the ‘data’ bit.

$entity().attributes.media_content_type = "tvshow"

should work. Assuming of course that there is an attribute ‘media_content_type’ and it has a string value of “tvshow” or similar.

If you are not getting anything from either output, then the node is probably incorrectly set up for your entity.

Note that when used, the Current State node will output the current entity state under the node in the node status flag. You should, as you are casting the state to boolean, see ‘false’ or ‘true’ and a timestamp. This relates to the entity state (and not to your test), so if this is not updating then the entity is incorrect, or the HA server WebSocket connection is not working.

You can always just put true or false into the JSONata expression, which will force the output message to either the top or bottom exit - clearly if nothing is coming out of either then something is wrong with the node operation.

The node status is a green blob, as the conditional test was true (simple ‘true’ in the JSONata) and the output comes from the top exit. The entity state is ‘false’ as the media_player is “off” and this is being cast to Boolean false. The timestamp shows an update (I have modified my HA Server status message from the default one)

I took a step back to a simpler testing platform and used the weather entity.

image

image

This is working exactly as you describe. So I will assume my issue is with the Plex entity now.
I do however have 2 questions/comments.

Is there a way to change the node status text below the node? For example the weather entity status is cloudy in my screenshot. Is there a way to make that show the current temperature or a different entity attribute?

It is surprising to me that you don’t need the ‘data’ in the JSONata string. If you go to the debug node and use the copy path function, it includes it. That is how I have been getting my entity attribute paths assuming it was right. Seems odd, but good to know.

image

Thanks for the assistance. I will keep playing with Plex, but I think I have the JSONata figured out at least.

Always a good approach to debugging - go back to something that actually works and then move forwards.

Good to know it is working for you, at least with a known entity and some JSONata code.

  1. The node status message (where there is one) comes from how the node is written to work, and will in this node show the entity state value. Weather entity state is usually ‘the general condition’ as a string, and everything else is in one or more attributes. So no you only get the state, unless you either write your own node or use a template sensor to provide a different entity where state is eg temperature…

The only thing you can change in the Status message, with the Home Assistant WebSocket nodes, is the Status date format (see the HA Server configuration node).

  1. Yes, I think everyone gets caught on this one at some point. Yes, everyone goes to the debug output to see what is in the entity, and then copies the JSON reference path from the message. The difference is that, in the message that comes out of the node, the entity object is (by default) set to reside in msg.data, as you have to put it into a field somewhere in the message object. Inside the node itself, when you use a JSONata expression, the special function $entity() returns the entity object directly, and not as a field property of the message object.

In simple terms, the output properties are, by default, equivalent to saying

msg.payload when set to 'entity state’ is the same as JSONata $entity().state

msg.data when set to ‘entity’ is the same as JSONata $entity()

I am sure that this is as clear as mud !