Automation template - how to detect slider last and new state and compare it in action template

Python script is now working. Thanks :slight_smile:

When I add automation:

- alias: 'kitchen_light_set_dimm'
  trigger:
    platform: state
    entity_id: input_number.kitchen_light_dimm
  action:
    service: python_script.dimm_control
    data_template:
      command: >-
        {% set to = trigger.to_state.state | int %}
        {% set from = trigger.from_state.state | int %}
        {% set diff = (from - to) | round(0) %}
        {% set slider = states('input_number.kitchen_light_dimm') | round(0) %}
        {% set step = diff / 10 | round(0) %}
        {% if slider == 0 %}
          0
        {% elif slider == 100 %}
          11
        {% else %}
          {{step}}
        {% endif %}

Only on and off working.

When I move slider from 10 to 0 light turns off when I move slider from 10-90 nothing hapeneds here is error:

Error executing script: invalid literal for int() with base 10: '1.0'
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/homeassistant/components/python_script/__init__.py", line 159, in execute
    exec(compiled.code, restricted_globals, local)
  File "dimm_control.py", line 10, in <module>
ValueError: invalid literal for int() with base 10: '1.0'

when I move slider from 90 to 100 light turns on.

Change this:

        {% set step = diff / 10 | round(0) %}

to this:

        {% set step = (diff / 10) | round(0) %}

Thanks. Now is working.

One more question. How can I call two commands at once with python script.

I try like this but not working and no error:

elif cmd == 1:
  loop = 1
  rfc = rf['ON'],
  rfc = rf['MOON']

I try to solve problem when I move slider from 0 to 10 not working. In this case python script must send two commands ON(turn on light) and MOON(set brightness to 10% or ON and 10xDOWN?

If you use elif cmd==1 to send ‘ON’ and ‘MOON’, you lose the ability to increase the brightness by just one step (cmd==1 represents an increase of one brightness step). If the light is already on and you press the button once to increment the brightness, it won’t do that, it will change to ‘MOON’ mode. Is that what you want?

If that’s the behavior you want, then the python_script changes to the following example. It adds a ‘MOON’ item to the list and adds a test for cmd==1 where it sends the ‘ON’ command before sending the ‘MOON’ command.

rf = { "ON":"JgBQAAABJZMSExE3EhMRExE4ETgRExE4ETgRExI3EjcSEhISEjcSEhISEjcSEhISEhISExETETgRNhMTETgROBE4ETgROBETEgAFJgABJUYSAA0FAAAAAAAAAAA=",
       "OFF":"JgBQAAABJpITERM2ExESEhM2EzYTERM2EzYTERM2EjcTERMSEjcSEhETERMROBI3EjcSEhI3EjcSNxI3EhISEhISEjcTERMREgAFJgABJUYSAA0FAAAAAAAAAAA=",
       "UP":"JgBQAAABKJMSEhI3EhISExE4ETgRExE4ETgRExE4ETgRExETEjcSEhISEjcSEhI3EhIUEBQ1FDUUNRQQFDUUEBQ1FDUUEBQREwAFJAABKEQUAA0FAAAAAAAAAAA=",
       "DOWN":"JgBQAAABJpIUEBQ1FBAUEBQ1FDUUEBQ1FDUUEBQ1EzYUERISEjcSEhISEjYTEhMREzYTERM2EzYTNhMREzYTNhMREzYTERMREwAFJQABJ0UUAA0FAAAAAAAAAAA=",
       "MOON":"JgBQAAABJJQRExE4ERMRExI3EjcSEhI3EjcSEhI3EjcSEhISEjcSEhISEhISExETERMRExETETgROBE4ETgROBE4ETgROBETEgAFJgABJEcSAA0FAAAAAAAAAAA="
     }

cmd = data.get('command')

if cmd is not None:
  cmd = int(cmd)
  if -10 <= cmd <= 11:
    if cmd == 0:
      loop = 1
      rfc = rf['OFF']
    elif cmd == 1:
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['ON'])}
      hass.services.call('broadlink', 'send', service_data, False)
      loop = 1
      rfc = rf['MOON']
    elif cmd == 11:
      loop = 1
      rfc = rf['ON']
    else:
      if cmd > 0:
        rfc = rf['UP']
      else:
        rfc = rf['DOWN']
      loop = abs(cmd)

    service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rfc)}
    for i in range(loop):
      hass.services.call('broadlink', 'send', service_data, False)

Thanks for tip.

But still not working as I want.

here is my full dimm_control.py and automation:

rf = { "ON":"JgBQAAABJZMSExE3EhMRExE4ETgRExE4ETgRExI3EjcSEhISEjcSEhISEjcSEhISEhISExETETgRNhMTETgROBE4ETgROBETEgAFJgABJUYSAA0FAAAAAAAAAAA=",
       "OFF":"JgBQAAABJpITERM2ExESEhM2EzYTERM2EzYTERM2EjcTERMSEjcSEhETERMROBI3EjcSEhI3EjcSNxI3EhISEhISEjcTERMREgAFJgABJUYSAA0FAAAAAAAAAAA=",
       "UP":"JgBQAAABKJMSEhI3EhISExE4ETgRExE4ETgRExE4ETgRExETEjcSEhISEjcSEhI3EhIUEBQ1FDUUNRQQFDUUEBQ1FDUUEBQREwAFJAABKEQUAA0FAAAAAAAAAAA=",
       "DOWN":"JgBQAAABJpIUEBQ1FBAUEBQ1FDUUEBQ1FDUUEBQ1EzYUERISEjcSEhISEjYTEhMREzYTERM2EzYTNhMREzYTNhMREzYTERMREwAFJQABJ0UUAA0FAAAAAAAAAAA=",
       "SUN":"JgBUAAABJZITEhI3EhISEhI3EjcSEhI3EjcSEhI3EjcSEhMREzYTERMREzYTNhM2ExETERM2EzYTNhMRExISEhI3EjcSEhISEgAFJgABJUYTAAWLFwANBQAAAAA=",
       "MOON":"JgBQAAABJJQRExE4ERMRExI3EjcSEhI3EjcSEhI3EjcSEhISEjcSEhISEhISExETERMRExETETgROBE4ETgROBE4ETgROBETEgAFJgABJEcSAA0FAAAAAAAAAAA="
     }

cmd = data.get('command')

if cmd is not None:
  cmd = int(cmd)
  if -10 <= cmd <= 12:
    if cmd == 0:
      loop = 1
      rfc = rf['OFF']
    elif cmd == 12:
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['ON'])}
      hass.services.call('broadlink', 'send', service_data, False)
      loop = 1
      rfc = rf['MOON']
    elif cmd == 11:
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['ON'])}
      hass.services.call('broadlink', 'send', service_data, False)
      loop = 1
      rfc = rf['SUN']
    else:
      if cmd > 0:
        rfc = rf['DOWN']
      else:
        rfc = rf['UP']
      loop = abs(cmd)

    service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rfc)}
    for i in range(loop):
      hass.services.call('broadlink', 'send', service_data, False)

- alias: 'kitchen_light_set_dimm'
  trigger:
    platform: state
    entity_id: input_number.kitchen_light_dimm
  action:
    service: python_script.dimm_control
    data_template:
      command: >-
        {% set to = trigger.to_state.state | int %}
        {% set from = trigger.from_state.state | int %}
        {% set diff = (from - to) | round(0) %}
        {% set slider = states('input_number.kitchen_light_dimm') | round(0) %}
        {% set step = (diff / 10) | round(0) %}
        {% if slider == 0 %}
          0
        {% elif slider == 100 %}
          11
        {% elif slider == 10 %}
          12
        {% else %}
          {{step}}
        {% endif %}

I think this is part of py script that not working:

elif cmd == 12:
  service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['ON'])}
  hass.services.call('broadlink', 'send', service_data, False)
  loop = 1
  rfc = rf['MOON']

I try to call 12 as service:

python_script.dimm_control {"command":12}

I must call service two times to work properly. Whe I call first time light is ON and when I call second time light goes to MOON mode. Why?

I don’t know and I can’t test it because I don’t have this device.

Maybe the second command (‘MOON’) arrives while the first one (‘ON’) is still being transmitted so it’s ignored. Maybe there needs to be a slight delay between consecutive commands. Try inserting time.sleep(0.25) after each service call.

For example, here:

    elif cmd == 12:
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['ON'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.25)
      loop = 1
      rfc = rf['MOON']

and here:

    for i in range(loop):
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.25)

That will make the script pause for 250 milliseconds after each service call.

If that doesn’t work, I don’t know what else to suggest.

Yes. Sleep time is problem.

I must add:

time.sleep(0.50)

Now slider working as it should:)

What this error mean:

Error executing script: name 'rfc' is not defined
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/homeassistant/components/python_script/__init__.py", line 159, in execute
    exec(compiled.code, restricted_globals, local)
  File "ct_control.py", line 110, in <module>
NameError: name 'rfc' is not defined

Here is ct_control.py:

rf = { "C":"JgBQAAABJpIUEBQ1FBAUEBQ1FDUUERM1FDUUERQ1FDUUEBQQFDUUEBQ1FBAUEBQ1FDUUEBQQFDUUEBQ1FDUUEBQQFDUUNRQQFAAFJAABJ0UUAA0FAAAAAAAAAAA=",
       "W":"JgBQAAABJ5EUEBQ1FBAUEBQ1FDUUERM1FDUVEBQ1FDUUEBQQFDUUEBQ1FBAUEBQQFBAUEBQ1FDUUEBQ1FDUUNRQ1FDUUERMRFAAFJAABJ0QUAA0FAAAAAAAAAAA="
     }

cmd = data.get('command')

if cmd is not None:
  cmd = int(cmd)
  if -10 <= cmd <= 12:
    if cmd == 0:
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
    elif cmd == 12:
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
    elif cmd == 11:
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['W'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['W'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['W'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['W'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['W'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['W'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['W'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['W'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['W'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
      service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['W'])}
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)
    else:
      if cmd > 0:
        rfc = rf['C']
      else:
        rfc = rf['W']
      loop = abs(cmd)

    service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rfc)}
    for i in range(loop):
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)

here is automation:

####################################################
# CAOLOUR TEMPERATURE
####################################################

- alias: 'ir_kitchen_light_set_ct'
  trigger:
    platform: state
    entity_id: input_number.kitchen_light_ct
  action:
    service: python_script.ct_control
    data_template:
      command: >-
        {% set to = trigger.to_state.state | int %}
        {% set from = trigger.from_state.state | int %}
        {% set diff = (from - to) | round(0) %}
        {% set slider = states('input_number.kitchen_light_ct') | round(0) %}
        {% set step = (diff / 10) | round(0) %}
        {% if slider == 0 %}
          0
        {% elif slider == 100 %}
          11
        {% elif slider == 10 %}
          12
        {% else %}
          {{step}}
        {% endif %}

At the risk of sounding blunt, it means exactly what it says. Your code refers to the variable rfc but it has not been defined yet when it is needed.

Review your code. Where does it define rfc when cmd is 0, 12, or 11? It doesn’t. So when it reaches the statement that creates service_data, where rfc is needed, rfc is not defined.

The whole purpose of showing you the python_script was to demonstrate how you can use a for-loop to simplify the code. You can do this:

# do things several times
for i to 7
  do something

as opposed to multiple repeated statements like this:

do something
do something
do something
do something
do something
do something
do something
do something

Your latest code suggests you have either not understood that concept or chosen to ignore it; the code continues to use multiple repeated statements. Basically, it reverts to the technique you used when you created multiple scripts thereby rendering the use of a python_script completely pointless.

You are, of course, free to code the python_script any way you see fit. There are many good python coding references to assist you (here’s one).

I try to loop like you suggested but I get error:

Error loading script ct_control.py: Line 11: SyntaxError: invalid syntax at statement: 'for i to 10'

rf = { "C":"JgBQAAABJpIUEBQ1FBAUEBQ1FDUUERM1FDUUERQ1FDUUEBQQFDUUEBQ1FBAUEBQ1FDUUEBQQFDUUEBQ1FDUUEBQQFDUUNRQQFAAFJAABJ0UUAA0FAAAAAAAAAAA=",
       "W":"JgBQAAABJ5EUEBQ1FBAUEBQ1FDUUERM1FDUVEBQ1FDUUEBQQFDUUEBQ1FBAUEBQQFBAUEBQ1FDUUEBQ1FDUUNRQ1FDUUERMRFAAFJAABJ0QUAA0FAAAAAAAAAAA="
     }

cmd = data.get('command')

if cmd is not None:
  cmd = int(cmd)
  if -10 <= cmd <= 12:
    if cmd == 0:
      for i to 10
        do  service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
            hass.services.call('broadlink', 'send', service_data, False)
            time.sleep(0.55)
    elif cmd == 12:
      for i to 10
        do  service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
            hass.services.call('broadlink', 'send', service_data, False)
            time.sleep(0.55)
    elif cmd == 11:
      for i to 10
        do  service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['W'])}
            hass.services.call('broadlink', 'send', service_data, False)
            time.sleep(0.55)
    else:
      if cmd > 0:
        rfc = rf['C']
      else:
        rfc = rf['W']
      loop = abs(cmd)

    service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rfc)}
    for i in range(loop):
      hass.services.call('broadlink', 'send', service_data, False)
      time.sleep(0.55)

That’s not how I suggested to create a for-loop. Review the original code and you’ll see it is this:

for i in range(loop)

For more information:

    for i in range(10):
        service_data = {'host':'192.168.2.1', 'packet':'{}'.format(rf['C'])}
        hass.services.call('broadlink', 'send', service_data, False)
        time.sleep(0.55)

try this

cmd = data.get('command')

def call_service(hass, host, rfkey, count):
    rf = {
        "C":"JgBQAAABJpIUEBQ1FBAUEBQ1FDUUERM1FDUUERQ1FDUUEBQQFDUUEBQ1FBAUEBQ1FDUUEBQQFDUUEBQ1FDUUEBQQFDUUNRQQFAAFJAABJ0UUAA0FAAAAAAAAAAA=",
        "W":"JgBQAAABJ5EUEBQ1FBAUEBQ1FDUUERM1FDUVEBQ1FDUUEBQQFDUUEBQ1FBAUEBQQFBAUEBQ1FDUUEBQ1FDUUNRQ1FDUUERMRFAAFJAABJ0QUAA0FAAAAAAAAAAA="
        }
    for i in range(count):
        service_data = {'host':host, 'packet':'{}'.format(rf[rfkey])}
        hass.services.call('broadlink', 'send', service_data, False)
        time.sleep(0.55)
    
if cmd is not None:
    cmd = int(cmd)
    if -10 <= cmd <= 12:
        if cmd in [0, 10]:
            call_service(hass, '192.168.2.1', 'C', 10)
        elif cmd == 11:
            call_service(hass, '192.168.2.1', 'W', 10)
        else:
            rfkey = 'C' if cmd > 0 else 'W'
            count = abs(cmd)
            call_service(hass, '192.168.2.1', rfkey, count)

Hi @petro I tested your solution but not working.

Error:

Error executing script: name 'rf' is not defined
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/homeassistant/components/python_script/__init__.py", line 159, in execute
    exec(compiled.code, restricted_globals, local)
  File "ct_control.py", line 19, in <module>
  File "ct_control.py", line 9, in call_service
NameError: name 'rf' is not defined

interesting. It seems it’s limiting the scope of the definition. I edited the previous post, try it again.

Still errors:

Error executing script: name 'hass' is not defined
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/homeassistant/components/python_script/__init__.py", line 159, in execute
    exec(compiled.code, restricted_globals, local)
  File "ct_control.py", line 19, in <module>
  File "ct_control.py", line 10, in call_service
NameError: name 'hass' is not defined

It would appear you have to pass the hass object as a parameter to the call_service function in order to be able to use it within the function.

There’s an example of it in this recent post by Marius:

So you will have to change the function’s signature to this:

def call_service(hass, host, rfkey, count):

and modify every call to the function. For example, this:

call_service('192.168.2.1', 'C', 10)

changes to this:

call_service(hass, '192.168.2.1', 'C', 10)
1 Like

Kind of odd that the scope doesn’t work properly in that env.

@lpt2007 made changes again

Now is working. :slight_smile: Thanks @123 and @petro