JSONata expression doesn't work

Edit: my reasoning for putting it in a different category than this is moved to was wrong :slight_smile:

A bit of context: I’m pulling dynamic energy prices from an API and want some automated actions to trigger under certain conditions. One of those conditions is if time is later than 06:00 / 6 AM and earlier than 22:00 / 10 PM. Also, the energy prices needs to be over 0. So I crafted this JSONata expression but it doesn’t let anything through:

$number($moment($.payload.*.startsAt).format('H')) > 6 and $number($moment($.payload.*.startsAt).format('H')) < 22 and $.payload.*.energy > 0

  • $.payload.*.energy > 0 on itself works.
  • When I put $number($moment($.payload.*.startsAt).format('H')) in a debug field I get nice rounded numbers, up untill 23.
  • When I use the full JSONata expression nothing gets through.

I’m a bit puzzled why. Does anyone have an idea?

It is?

I was under the impression we used jinja for templating.

As you are talking about a Node Red query it may be different and I have moved your post back there where you can get relevant advice.

Oh, I guess my misconception shows how often I use JSONata outside of Node Red :smiley: Thanks.

JSONata is a separate language and integrated into Node-RED. HA knows nothing about JSONata and, for the most part, Node-RED knows nothing about Jinja2 templates. Therein lies much confusion and angst.

I am not at my PC and can’t run tests properly at the moment, so someone else will come to your aid. However I note that whilst the $moment() function does work it possibly does so without following the usual JSONata syntax, and probably invalidates a compound expression.

In JSONata $ is current context, and you may need $$.payload to get back to the top level and payload when within a sub level context.

Also I would personally open a code block and use a variable to first extract the hour, then apply the predicate at the final line. Makes testing and debugging easier too.

(
    $hour := $moment($$.payload.*.startsAt).format('H');
    $h:= $number($hour);
    $h>6 and $h<22 and payload.*.energy >0
)

As I say I can’t test this, and I wonder if your payload.*.field is returning an array rather than a value, hence the predicate will fail.

1 Like

In this case payload.*.field is part of a for x in y loop with a 3rd party node (as I couldn’t find any standard node to do the same). In that loop .field returns x.field. Tested and working. The whole functionality already does what I want it to, except that I want to use it only between certain hours.

I’ll give your suggestion a try and let you know if it works.