As a general tip, if you ask for help with a Node-RED problem, it assists everyone if you post
- what you are trying to do
- what the symptoms of the problem are
- your flow: a picture is nice, the exported flow is better
- the data you are working with (both input and output)
So, we fixed the first problem - the code I provided is working. Now I can see your flow (picture) I can see the big problem with the flow itself.
When you have multiple lines coming out from a node, Node-RED makes copies of the message and sends one copy down each path. These messages run through the rest of the flow, individually, and do not ‘join up’ unless you specifically join them with a ‘join node’.
So, your inject node is sending one message to pick up the ‘number’, and another separate message to pick up the ‘message’ variables.
When these messages arrive at your service call - they each run a service call and do so without any knowledge of the other message.
If you hard code your values, then it works, but effectively you are calling the service twice.
When each message arrives on its own, the service call has either ‘number’ or ‘message’ but not both. Hence the JSONata code builds an incomplete object, and naturally the service call complains because it gets either the temp_low, or the temp_high, but not both as it requires. So you get two error messages.
You need to join the messages up, so as to have both values in the same message (before using them) or just one message flow and collect both values as you go.
My suggestion:
Link from your inject node to your first current:state node.
Set this to output msg.temp_low as ‘entity state’
Remove the msg.data output (you don’t need this)
Join the output to your second current:state node.
Set this one to output msg.temp_high as ‘entity state’
Remove the msg.data output
Make sure both current:state nodes have ‘state type’ set to ‘number’ to ensure you are getting the state values out as integers and not strings.
Join the output directly to your call service node.
Use the following JSONata for Data
{ "target_temp_low": temp_low, "target_temp_high": temp_high}
The single message will collect the low temperature setting in the first current state node, and keep this in msg.temp_low. This will pass through the second current state node, which also collects the high temperature setting, and adds this in msg.temp_high.
Now, when this single message arrives at the call service node, the JSONata above has both msg.temp_low and msg.temp_high, and can correctly build the data object you need.
This should work.
To help you, and others reading this later, it is worth noting that whilst most nodes work on msg.payload, some have more flexibility. Clearly two nodes in sequence outputting to msg.payload would have the second overwrite the work of the first node. However, the current:state node allows you to build a list of msg.output_fields, and as long as what you use does not get recognised as input or overwritten as output in the next node, it should ‘pass through’ the next node unscathed. For nodes that just work on / output to msg.payload, you can always use a following change node to move msg.payload to something else.