SOLVED:How to add sensor state in an array inside an automation and send it with modbus.write_register service

Hi all,
i’m trying to send order through modbus service to an equipment.
This equipment accept only write done with function 16 and in order to satisfy this requirement I must send at least 2 registers with an array.
So I created an input_boolean in order to trigger an automation and with static value is working fine:

 - alias: OnOffCtrlNilan
  trigger:
    - platform: state
      entity_id: input_boolean.accensione_nilan
      to: 'on'
  condition: []
  action:
    service: modbus.write_register
    data:
      hub: Com1
      unit: 4
      address: 1001
    data_template:
      value: [1,2,2]

Now in order to send a single “order” I’m trying to send in the second register the value of the register itself that I’m already reading with a modbus sensor entity.
I wrote the following code:

- alias: OnOffCtrlNilan
  trigger:
    - platform: state
      entity_id: input_boolean.accensione_nilan
      to: 'on'
  condition: []
  action:
    service: modbus.write_register
    data:
      hub: Com1
      unit: 4
      address: 1001
    data_template:
      value: [1,{{ states('sensor.ctrlmode')|int }},2]

but I receive this error: invalid key: “OrderedDict([(“states(‘sensor.ctrlmode’)|int”, None)])”

I checked from the developer tools the state of the sensor and it is:
image

Could you help me?
Thanks in advance
Matteo

    data_template:
      value: "[1,{{ states('sensor.ctrlmode')|int }},2]"

If i put that value template in my template editor I get:

[1,{{ states(‘sensor.ctrlmode’)|int }},2] = [1,0,2]

If I adjust for a valid output on my system I get:
[1,{{ states(‘input_number.slider1’)|int }},2] = [1,9,2]

Have you been testing your ‘value template’ on your template editor?

Are you certain that the static value you sent was resulting in the register being written? It shouldn’t because you need it to be ‘wrapped’ in double quotes to work?

@tom_l has given you the correct value template to be wrapped in double quotes but I remain unsure you need to be sending [1,9,2] to your register?

EDIT: I failed to read the top part of your post I guess @tom_l has solved it for you then.

I normally expect the register to receive ‘the value which I want to send only’ IE: 9 in the above example?

dear All,
thank you for your prompt reply, unfortunately still not working
if I insert static number is working I just checked another time (the unit change settings according parameters)
After that I tested the @tom_l solution but doesn’t work i get the following error:

Error while executing automation automation.onoffctrlnilan. Invalid data for call_service at pos 1: expected int @ data[‘value’][0]

If I understood correctly jinja docs double quote are used for indicate a string in my case I need to prepare an array of 3 int as it explained in the modbus doc:

Write register. Requires hub , unit , address and value fields. value can be either single value or an array A single value or an array of 16-bit values. Single value will call modbus function code 6. Array will call modbus function code 16. Array might need reverse ordering. E.g., to set 0x0004 you might need to set [4,0]

I tried to copy my template in the template editor and the result seems good [1,{{states(‘sensor.ctrlmode’)|int}},2] = [1,1,2]
[1,{{states(‘sensor.ctrlmode’)}},2] =[1,1,2]
[1,{{states(‘sensor.ctrlmode’)|float}},2] =[1,1.0,2]

I just found also this post https://community.home-assistant.io/t/pass-variable-to-modbus-in-automation/86613

seems a bug how can I highlight better this issue to the community?

Ok, the issue of the double quotes is this:
The double qutes are a requirement (as I understand it?) of the automation. Nothing to do with jinja.

So what you are constructing (and what @tom_l) provided was a template to add the double quotes around the required array you want to send to the modbus register.

So when you try to send a static value in your data template;

     data_template:
       value: [1,2,2]

That should fail as it is not wrapped in double quotes IE:

    data_template:
      value: "[1,2,2]"

Then you need to do more testing with a static value and ensure that the data you wish to send is actually being written to the register.

Do you have the register setup with a sensor to read its value?
If not I recommend you set that up.

If it could be a matter of how the values are ordered then try this as your static value:

    data_template:
      value: "[2,2,1]"

hi @wellsy
I’m 100% sure that with static value is working only without double quote; with double quote the request fail
I checked also by calling the service with developer tools (please see screenshot below)


Consider that I already have the equipment connected (is an HVAC) and when I change the third digit l can increase or decrease the fan speed correctly.
I just found a similar post that I mention in my previous reply, seems a common issue, @thomas-be fixed it using a “trigger” but I think that I cannot applied his solution in my case

@Bard I was going to ask you how you were setting the value you want to send but figured you had that sorted but as you mention a ‘trigger’ here is how I trigger and set the value by catching the state change of an input_number.

- id: IrrigationStartTime
  alias: Irrigation Start Time
  trigger:
    platform: state
    entity_id: input_number.slider1
  action:
    service: modbus.write_register
    data_template:
      hub: hub3
      unit: 3
      address: 3074
      value: "{{ states.input_number.slider1.state|int }}"

Maybe you can tweak that for your needs?

I create inside automations.yaml the following code:

- alias: OnOffCtrlNilan
  trigger:
    - platform: state
      entity_id: input_boolean.accensione_nilan
      to: 'on'
  condition: []
  action:
    service: modbus.write_register
    data:
      hub: Com1
      unit: 4
      address: 1001
    data_template:
      value: [1,2,2]

then inside configuration.yaml i created

input_boolean:
  accensione_nilan:
    name: Accensione Nilan
    initial: true

so from the frontend I can set the input boolean

I tried to replace the sensor with an input_number but nothing change,
i get the correct state if I test under developer tools, but when i try to test it with the service i get the error:

Failed to call service modbus/write_register. expected int @ data[‘value’][1]

Did you create an input_number as well?

@Bard try it this way

- alias: OnOffCtrlNilan
  trigger:
    - platform: state
      entity_id: input_boolean.accensione_nilan
      to: 'on'
  condition: []
  action:
    service: modbus.write_register
    data_template:
      hub: Com1
      unit: 4
      address: 1001
      value: "[1,2,2]"

Hi @wellsy finally I found the solution!!!
was a syntax error, please see below the proper syntax:

- alias: OnOffCtrlNilan
  trigger:
    - platform: state
      entity_id: input_boolean.accensione_nilan
      to: 'on'
  condition: []
  action:
    service: modbus.write_register
    data:
      hub: Com1
      unit: 4
      address: 1001
    data_template:
      value: [1,2,"{{states('sensor.ctrlmode') | int}}"]

thank you so much for your support :slight_smile:

Your welcome…

So (for clarity) you shifted the position of ‘data placement’ within the template right?

data placement doesn’t matter i can swap dynamic date with fix value, I put the double quote only between the “braces” related sensor.ctrlmode instead of the entire array
correct:

value: [1,2,“{{states(‘sensor.ctrlmode’) | int}}”]

wrong:

value: “[1,2,{{states(‘sensor.ctrlmode’) | int}}]”

@Bard Ahhh…I missed that. Well picked up! So the double quotes are required to wrap the data ONLY.

When I test that in the template editor I get:

[1,2,"{{states('sensor.ctrlmode') | int}}"] = [1,2,"0"]

OR with a value from my input_number:

[1,2,"{{states('input_number.slider1') | int}}"] = [1,2,"9"]

While for static value testing purposes it would be:

EDIT: value: [1,2,2]

Anyone else who reads this post should be able to gain some ideas to fix their own problems now.

Sorry @wellsy,
For static value you don’t need double quote, double quote are required in order to get value from entity like input_number or sensor only

1 Like

Okie…thanks for clearing that up.

This evening I’ll check if static values working also with double quotes

1 Like

I made the test: is possible to use both configurations (with or without double quote) for send static value. I’ll review the syntax starting from @wellsy 's post:

in order to send 2 static values and one dynamic value from a sensor: 
[1,2,"{{states('sensor.ctrlmode') | int}}"]
OR
["1","2","{{states('sensor.ctrlmode') | int}}"]

with a value from my input_number:

[1,2,"{{states('input_number.slider1') | int}}"]
OR
["1","2","{{states('input_number.slider1') | int}}"]

While for static value testing purposes it would be:

value: [1,2,2] or ["1","2","2"] 

Honestly I don’t know which format is better to use

please be aware that the syntax is working only inside the automation.yaml file, I try to call the service using developer tools but doesn’t work

2 Likes