Beginner - How to after splitting an array

Hi all.
Quick background - i have connected a modbus interface to give me 16 digital ins. Its all working and reporting binary true/false in a 0-15 array. I've also managed to use the split node to split it down into seperate messages, all reporting correctly in the debug window as shown below.

The purpose is it is an alarm interface that will report data into home assistant.

This is where i get stuck. In my head the code is 'if index 0 is true, go to this output, if its false go to this output; if index 2 is true etc etc'. Writing a big 'if' function with 32 outputs seems to me like i am on the wrong track. How should i go about it?

Hi IanH1, welcome to the forum.

The switch node is there for routing messages according to their properties.
You probably need two levels, first switching on msg.parts.index == 0 to 16, the second on msg.payload == true or false

Perfect - got it, thanks. I was going to post a pic of my flow but of course it just looks exactly like yours! Thanks for the help.

Actually, less screen space needed and fewer wires to draw if you switch on true/false before index.

I don't totally follow what you've done there - does the true/false node pass the full array and then index splits it into the array positions? This is how i've done it - the home assistant turn on/off section looks like it might be an inefficent way to do it to me!

I assumed with either version you would have split the message into 16 bits first.

So each message has two attributes: payload true/false and index 0-15.
I think that both should work, the second one is just a bit more compact.

It does look more like a circus big top than a computer program!

1 Like

Does this really require so much duplication?
what are the settings in this HA node?
could it not be done more dynamically like example below?

[{"id":"d59e0171.98ced","type":"inject","z":"da8a6ef0b3c9a5c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"[true,true,false,false,true]","payloadType":"json","x":90,"y":3980,"wires":[["5bdb51c8b06c2003"]]},{"id":"5bdb51c8b06c2003","type":"split","z":"da8a6ef0b3c9a5c8","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":250,"y":3980,"wires":[["f7e3199384a26e96"]]},{"id":"f7e3199384a26e96","type":"change","z":"da8a6ef0b3c9a5c8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$$.payload = true ? \"turn_on\"  : \"turn off\"","tot":"jsonata"},{"t":"set","p":"device","pt":"msg","to":"parts.index","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":440,"y":3980,"wires":[["425b8a.987c8478"]]},{"id":"425b8a.987c8478","type":"debug","z":"da8a6ef0b3c9a5c8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":610,"y":3980,"wires":[]}]

I would require more info about your HA node to help more, as I do not use HA.
I feel that you should be able to do this with 1 split, one change or function node and one HA node.

Hi E1cid,

As a beginner i've done my best to understand your flow! I've attached an image of the home assistant node below, basically it is a 'call service' ie on a certain input, it does a thing (in this case, turns on a virtual switch).

I think i can follow your flow, but the home assistant flow would then need to be able to discern between the array index's - so your arrangement is passing forward the true/false from the digital IO, i need the HA node to then say "if index 0 is true, call this service, if its false, don't do anything; if index 1 is true etc..."

Also i had to modify my flow to include a filter node which dropped the message if the state hadn't changed, otherwise in my arrangement home assistant was calling the service on every poll interval, which seemed like an unnecessary use of resources.


What does the HA node help text say about setting service and entity dynamically, can you copy the help text and paste here. If you are able to set service and entity dynamically then you should be able to use my flow.example. Is it possible to use mustache template in the service and entity inputs?

As in this example i set entities/devices in the change node. I added a template node to show how they can be set using mustache template, as i do not have HA.

[{"id":"fb404cdd59999e5d","type":"inject","z":"b7674213daf430ad","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"[true,true,false,false,true]","payloadType":"json","x":590,"y":220,"wires":[["577fe693aa471e6d"]]},{"id":"577fe693aa471e6d","type":"split","z":"b7674213daf430ad","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":750,"y":220,"wires":[["50f2beab50fdfd2e"]]},{"id":"3d6802f944e6197a","type":"inject","z":"b7674213daf430ad","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"[false,false,true,true,false]","payloadType":"json","x":590,"y":280,"wires":[["577fe693aa471e6d"]]},{"id":"50f2beab50fdfd2e","type":"switch","z":"b7674213daf430ad","name":"","property":"devices[msg.parts.index]","propertyType":"flow","rules":[{"t":"neq","v":"payload","vt":"msg"}],"checkall":"true","repair":false,"outputs":1,"x":830,"y":180,"wires":[["0101ea1687e187fa"]]},{"id":"0101ea1687e187fa","type":"change","z":"b7674213daf430ad","name":"","rules":[{"t":"set","p":"devices[msg.parts.index]","pt":"flow","to":"payload","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"$$.payload = true ? \"turn_on\"  : \"turn_off\"","tot":"jsonata"},{"t":"set","p":"device","pt":"msg","to":"(\t$devices := [\"one\",\"two\",\"three\",\"four\",\"five\"];\t$devices[$$.parts.index]\t)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":940,"y":220,"wires":[["ae9805f858649620"]]},{"id":"ae9805f858649620","type":"template","z":"b7674213daf430ad","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"service -  {{payload}} \nentity -  {{device}}","output":"str","x":880,"y":300,"wires":[["bde20f24c3bf64e0"]]},{"id":"bde20f24c3bf64e0","type":"debug","z":"b7674213daf430ad","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1110,"y":300,"wires":[]}]

[edit] Added context storage of state, only changed states are forwarded.

I have pasted the help text in below. I've downloaded your flow there and I think I can see how it is working, i'll be honest though I am at my limits of knowledge! It is really useful though and I am just about keeping up!

call service

Sends a request to home assistant for any domain and service available (light/turn_on, input_select/select_option, etc..)

Helpful Examples

Call Service Tips and Tricks

Configuration

Domain requiredstring

Service domain to call
A custom domain can be used by adding a # at the end of the domain
Service requiredstring

Service to call
Custom service can be used by adding a # at the end of the service
Areaan array of area ids

A list of area ids that will be used as targets for the service call
Custom ids can be inserted into the list by adding a # at the end of the id
Devicean array of device ids

A list of device ids that will be used as targets for the service call
Custom ids can be inserted into the list by adding a # at the end of the id
Entityan array of entity ids

A list of entity ids that will be used as targets for the service call
DataJSONata | JSON

JSON object to pass along.
Merge Contextstring
If defined will attempt to merge the global and flow context variable into the config
Alternative Template Tagsboolean
Will change the tags used for the mustache template to <% and %>
Queuenone | first | all | last
Will store the first, last, or all messages received while disconnected from Home Assistant and send them once connected again

Input

All properties need to be under msg.payload.
Sample input

{
    "domain": "homeassistant",
    "service": "turn_on",
    "target": {
        "area_id": ["kitchen"],
        "device_id": ["8932894082930482903"],
        "entity_id": ["light.kitchen", "switch.garage_light"]
    }
    "data": {
        "brightness_pct": 50
    }
}
Merging

If the incoming message has a payload property with domain, service set it will override any config values if set.
If the incoming message has a payload.data that is an object or parsable into an object these properties will be merged with any config values set.
If the node has a property value in its config for Merge Context then the flow and global contexts will be checked for this property which should be an object that will also be merged into the data payload.

Merge Resolution

As seen above the data property has a lot going on in the way of data merging, in the end, all of these are optional and the rightmost will win if a property exists in multiple objects
Config Data, Global Data, Flow Data, Payload Data ( payload data property always wins if provided
domainstring
Service domain to call
servicestring
Service service to call
dataJSON Object
Service data to send with the service call
targetJSON Object with area_id, device_id, and entity_id as array properties
Targets of the service call

Output

Value types:

  • sent data: data sent to Home Assistant
  • config: config properties of the node

So have you tried adding a HA node to my flow with
{{payload}} in service field
And
{{device}} in entity field, may need to be ["{{device}}"]
And
Setting your device/entity names in the change node, in the $devices array.
And
Remove template node.

I will give it a go - i need to spend a bit of time with those flows and letting them sink in. I can see generally how it works though. That would 'call' each HA service in turn wouldn't it as it receives the messages; I wonder if there might be some issue with one HA node trying to very quickly call several services? Perhaps i'm misunderstanding, but there's only one way to find out.. Thanks for the input, it has been really valuable!

You can rate limit the flow with a delay node in rate limit mode.

Reading the help text, it seems to say you can send a list of entities. So you could create two entity arrays, one turn_on and one turn_off, to limit calls also. My latest example flow also limits by only sending changed states.

Your latest example flow with 16 calls service nodes will send the calls just as quick, so if that is working with no issue things should be fine.

1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.