Modbus write register works in automation but only half works in script

Hey, first time writer here, I hope I picked the right category.

I’m loosing my marbles trying to setup a script to write a modbus register.
For context, I already extensively control our solar inverter and the hot water heater controller via modbus TCP. Almost everything works, even though it was a steep learning curve.

One thing doesn’t want to cooperate for the life of me:
The hot water heater controller has and analog output that can be set via modbus to Off, Manual Control, or Auto. I want to switch between Off and Auto.

This works:

automation:
  - id: "automation_smartfox_aout_mode"
    alias: "smartfox aout mode"
    description: "Set Aout mode"
    trigger:
      - platform: state
        entity_id:
          - input_select.set_sf_aout_ctrl_mode
    condition: []
    variables:
      aout_mode_off: [0x0]
      aout_mode_manual: [0x1]
      aout_mode_auto: [0x2]
    action:
      - service: modbus.write_register
        data_template:
          hub: SmartfoxPro2
          slave: !secret smartfox_modbus_slave
          address: 42206
          value: >
            {% if is_state('input_select.set_sf_aout_ctrl_mode', "Off") %}
              {{aout_mode_off}}
            {% elif is_state('input_select.set_sf_aout_ctrl_mode', "Manual") %}
              {{aout_mode_manual}}
            {% elif is_state('input_select.set_sf_aout_ctrl_mode', "Auto") %}
              {{aout_mode_auto}}
            {% else %}
              {{aout_mode_auto}}
            {% endif %}
    mode: single

together with an Input select where I can switch between the 3 options.

This doesn’t work:

script:
  set_smartfox_aout_mode:
    alias: "Set Smartfox Aout Mode"
    description: Set the Aout mode of Smartfox
    variables:
      aout_mode_off: [0x0]
      aout_mode_manual: [0x1]
      aout_mode_auto: [0x2]
    fields:
      mode_in:
        selector:
          select:
            options:
              - "Off"
              - "Manual"
              - "Auto"
            multiple: false
        required: true
        description: The Mode to set the Aout to
        name: mode_in
    sequence:
      - service: modbus.write_register
        data:
          hub: SmartfoxPro2
          slave: !secret smartfox_modbus_slave
          address: 42206
          value: >
            {% if mode_in == "Off" %}
              {{aout_mode_off}}
            {% elif mode_in == "Manual" %}
              {{aout_mode_manual}}
            {% elif mode_in == "Auto" %}
              {{aout_mode_auto}}
            {% else %}
              {{aout_mode_auto}}
            {% endif %}
    mode: single
    icon: mdi:car-cruise-control

and I don’t get why!

I can switch between all 3 options with the automation.
With the script, “Off” just switches to “Manual” - setting to “Auto” with the script works! “Manual” works, too!
But running the script and selecting “Off” sets the output to Manual.

Any help appreciated… I might be overlooking something completely obvious, but I’m so hopelessly lost right now… Thanks!

~ morgantic

EDIT: I assume it’s not a good sign the script doesn’t get pretty formatted but checking the syntax doesn’t complain…

EDIT2: I have the same issue with the Relay Outputs that can be set to the 3 states, Off doesn’t work, but I only tested that with a script, but I’d assume it also works via automation…

Can you download and share a trace of it not working?

Can you please tell me how? I only know how to get a trace for a script defined in the UI.

How/where is your script defined? Even ones that are not created in the UI I believe should still be visible in the scripts tab, and still have stored traces:

1 Like

Thanks, the button was missing, but refreshing the site worked.
I can now see the issue, I can’t seem to upload a json file here but I think these screenshots might be enough:

With value 1:

With value 0:

For comparison, the automation with value 0:

~morgantic

When did you change it to mode_in == "Deactivate" ?

Instead of sharing screenshot snippet it’s better if you download the entire trace yaml from the download button in the menu in upper right.

Sorry, I changed quite a bit around while testing and clicked back one trace too far. I only changed the value though, to make sure “Off” isn’t interpreted in any way.

I get the trace as a json and I can’t upload a json here. I would have done that, if I could :smiley:

I did a test though, and this works:

Why does the [0x0] variable work in an automation but not in a script? :thinking:

I can just skip the whole variable part all together since they’re static, anyways, but it’s confusing me right now!

~morgantic

You can share it on a codeshare site e.g.

1 Like

value 1: dpaste/WPUw0 (YAML)

value 0: dpaste/UGMAr (YAML)

~morgantic

Seems like something is eating your 0x0 variable and it’s just an empty array, but I’m not sure what. I made a similar script and I don’t see that behavior.

      "variables": {
        "aout_mode_off": [],
        "aout_mode_manual": [
          1
        ],
        "aout_mode_auto": [
          2
        ]
      },
1 Like

Ok, so at least I was right with the suspicion, I’ll use the workaround, ditch the variables and use the values in the if-else directly.

I also am a few releases behind with my HA installation, so I’ll upgrade, see if the issue persists, and if so, I might go and create a bug report.

For now, I have a solution that works, and that’s enough for me. Also learned a lot again! Thanks very much for your time!

~morgantic