Light template

I have a problem getting the light template to work.
How do i get the level_template and value_template from a sensor?
I tried everything, but I can’t get it to work.

When I follow the guide on https://www.home-assistant.io/components/light.template/ I get a bunch of errors in my logfile.
This seems to have something to do with sensor.mysensor / ‘sensor.mysensor’. When I put no quotes, the error appears that sensor has no state, and mysensor has no state. When i do put the quotes, this error is gone, but I cant get it to work properly.

Please post what you have. If you don’t show us that, or the errors you’re seeing, it’s really hard to help. You’ve obviously already read the documentation, so chances are it’s something simple which we can spot if we can see exactly what you’ve done.

Here is what I’ve tried so far:

sensor:

- platform: ads
  adsvar: gvlBus.arrDMXData[2]
  adstype: byte
  units_of_measurement: '%'
  name: brightness_licht_fornuis

The sensor is receiving it’s value, this has been verified.

light:

- platform: template
  lights:
    # Licht fornuis
    bediening_licht_fornuis:
      friendly_name: "Licht fornuis"
      level_template: "{{ 'sensor.brightness_licht_fornuis.state' }}"
      value_template: "{{ 'sensor.brightness_licht_fornuis.state'|int > 1}}"
          
      turn_on:
        service: ads.write_data_by_name
        data:
          adsvar: gvlHomeAssistant.bBedLichtFornuis
          adstype: byte
          value: 1
      turn_off:
        service: ads.write_data_by_name
        data:
          adsvar: gvlHomeAssistant.bBedLichtFornuis
          adstype: byte
          value: 0
      set_level:
        service: ads.write_data_by_name
        data:
          adsvar: gvlHomeAssistant.iDimLichtFornuis
          adstype: byte
          value: "{{ brightness }}"

Gives me the following error in the log (every x seconds):

ValueError: invalid literal for int() with base 10: 'sensor.brightness_licht_fornuis.state'
2019-01-17 14:20:45 ERROR (MainThread) [homeassistant.helpers.entity] Update for light.bediening_licht_fornuis fails
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 221, in async_update_ha_state
    await self.async_device_update()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 347, in async_device_update
    await self.async_update()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/light/template.py", line 257, in async_update
    if 0 <= int(brightness) <= 255:
ValueError: invalid literal for int() with base 10: 'sensor.brightness_licht_fornuis.state'

When I change the code to (for the sake of readability I only post the updated part, the rest stays the same):

level_template: “{{ sensor.brightness_licht_fornuis }}”
value_template: “{{ sensor.brightness_licht_fornuis|int > 1}}”

I get this in the log:

2019-01-17 14:23:32 ERROR (MainThread) [homeassistant.components.light.template] UndefinedError: 'sensor' is undefined
2019-01-17 14:23:32 ERROR (MainThread) [homeassistant.helpers.entity] Update for light.bediening_licht_fornuis fails
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 221, in async_update_ha_state
    await self.async_device_update()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 347, in async_device_update
    await self.async_update()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/light/template.py", line 242, in async_update
    if state in _VALID_STATES:
UnboundLocalError: local variable 'state' referenced before assignment
2019-01-17 14:23:32 ERROR (MainThread) [homeassistant.components.light.template] UndefinedError: 'sensor' is undefined
2019-01-17 14:23:32 ERROR (MainThread) [homeassistant.helpers.entity] Update for light.bediening_licht_fornuis fails
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 221, in async_update_ha_state
    await self.async_device_update()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 347, in async_device_update
    await self.async_update()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/light/template.py", line 242, in async_update
    if state in _VALID_STATES:
UnboundLocalError: local variable 'state' referenced before assignment

Then I tried quotes with no .state:

  level_template: "{{ 'sensor.brightness_licht_fornuis' }}"
  value_template: "{{ 'sensor.brightness_licht_fornuis'|int > 1}}"

And the log replied:

2019-01-17 14:25:37 ERROR (MainThread) [homeassistant.helpers.entity] Update for light.bediening_licht_fornuis fails
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 221, in async_update_ha_state
    await self.async_device_update()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 347, in async_device_update
    await self.async_update()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/light/template.py", line 257, in async_update
    if 0 <= int(brightness) <= 255:
ValueError: invalid literal for int() with base 10: 'sensor.brightness_licht_fornuis'
2019-01-17 14:25:37 ERROR (MainThread) [homeassistant.helpers.entity] Update for light.bediening_licht_fornuis fails
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 221, in async_update_ha_state
    await self.async_device_update()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 347, in async_device_update
    await self.async_update()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/light/template.py", line 257, in async_update
    if 0 <= int(brightness) <= 255:
ValueError: invalid literal for int() with base 10: 'sensor.brightness_licht_fornuis'

So, then I did this:

  level_template: "{{ get_state('sensor.brightness_licht_fornuis') }}"
  value_template: "{{ is_state('sensor.brightness_licht_fornuis', '>1')}}"

And the log bugged me with this:

2019-01-17 14:30:58 ERROR (MainThread) [homeassistant.components.light.template] UndefinedError: 'get_state' is undefined
2019-01-17 14:30:58 ERROR (MainThread) [homeassistant.helpers.entity] Update for light.bediening_licht_fornuis fails
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 221, in async_update_ha_state
    await self.async_device_update()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 347, in async_device_update
    await self.async_update()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/light/template.py", line 257, in async_update
    if 0 <= int(brightness) <= 255:
UnboundLocalError: local variable 'brightness' referenced before assignment
2019-01-17 14:30:58 ERROR (MainThread) [homeassistant.components.light.template] UndefinedError: 'get_state' is undefined
2019-01-17 14:30:58 ERROR (MainThread) [homeassistant.helpers.entity] Update for light.bediening_licht_fornuis fails
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 221, in async_update_ha_state
    await self.async_device_update()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 347, in async_device_update
    await self.async_update()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/light/template.py", line 257, in async_update
    if 0 <= int(brightness) <= 255:
UnboundLocalError: local variable 'brightness' referenced before assignment

I’m out of options…

Try:

      level_template: "{{ states('sensor.brightness_licht_fornuis') }}"
      value_template: "{{ states('sensor.brightness_licht_fornuis')|int > 1}}"

Hurray! That one nailed it :smiley:
Tnx a lot!.

One problem still remains:

It seems that the set_level is passing the {{ brightness }} as a string to the service.
How can I pass this as an integer? Now my log says:

2019-01-17 17:27:11 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection.1746806832] Error handling message: {'domain': 'light', 'service_data': {'brightness': 255, 'entity_id': 'light.bediening_licht_fornuis'}, 'type': 'call_service', 'service': 'turn_on', 'id': 16}
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/websocket_api/decorators.py", line 17, in _handle_async_response
    await func(hass, connection, msg)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/websocket_api/commands.py", line 148, in handle_call_service
    connection.context(msg))
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/core.py", line 1121, in async_call
    self._execute_service(handler, service_call))
  File "/usr/lib/python3.5/asyncio/futures.py", line 380, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.5/asyncio/tasks.py", line 304, in _wakeup
    future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
    raise self._exception
  File "/usr/lib/python3.5/asyncio/tasks.py", line 241, in _step
    result = coro.throw(exc)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/core.py", line 1143, in _execute_service
    await handler.func(service_call)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/light/__init__.py", line 287, in async_handle_light_on_service
    await light.async_turn_on(**pars)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/light/template.py", line 219, in async_turn_on
    {"brightness": kwargs[ATTR_BRIGHTNESS]}, context=self._context)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/script.py", line 131, in async_run
    await self._handle_action(action, variables, context)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/script.py", line 210, in _handle_action
    action, variables, context)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/script.py", line 299, in _async_call_service
    context=context
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/service.py", line 85, in async_call_from_config
    domain, service_name, service_data, blocking=blocking, context=context)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/core.py", line 1121, in async_call
    self._execute_service(handler, service_call))
  File "/usr/lib/python3.5/asyncio/futures.py", line 380, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.5/asyncio/tasks.py", line 304, in _wakeup
    future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
    raise self._exception
  File "/usr/lib/python3.5/asyncio/tasks.py", line 241, in _step
    result = coro.throw(exc)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/core.py", line 1145, in _execute_service
    await self._hass.async_add_executor_job(handler.func, service_call)
  File "/usr/lib/python3.5/asyncio/futures.py", line 380, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.5/asyncio/tasks.py", line 304, in _wakeup
    future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
    raise self._exception
  File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/ads/__init__.py", line 96, in handle_write_data_by_name
    ads.write_by_name(ads_var, value, ads.ADS_TYPEMAP[ads_type])
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/ads/__init__.py", line 153, in write_by_name
    return self._client.write_by_name(name, value, plc_datatype)
  File "/srv/homeassistant/lib/python3.5/site-packages/pyads/ads.py", line 533, in write_by_name
    value, plc_datatype)
  File "/srv/homeassistant/lib/python3.5/site-packages/pyads/pyads_ex.py", line 502, in adsSyncWriteByNameEx
    port, address, ADSIGRP_SYM_VALBYHND, handle, value, data_type
  File "/srv/homeassistant/lib/python3.5/site-packages/pyads/pyads_ex.py", line 301, in adsSyncWriteReqEx
    data = plc_data_type(value)
TypeError: an integer is required (got type str)

At the very least, you probably need to change data to data_template:

      set_level:
        service: ads.write_data_by_name
        data_template:
          adsvar: gvlHomeAssistant.iDimLichtFornuis
          adstype: byte
          value: "{{ brightness }}"

As it was it was actually sending the string {{ brightness }} instead of rendering the template and sending the value of brightness. Still, templates always return strings (even if they look like numbers.) I haven’t dug into the details of ads (whatever that is), so hopefully somewhere along the way the value of brightness (which will be a number represented in a string) will actually get converted from a string to a number, otherwise you may still have the same problem, in which case, the only solution is fixing the ads component.

ADS is the communications platform for Beckhoff automation devices.
Since its implemented in Home Assistant, it’s a big advantage that I don’t need to write custom scripts.
The let-down is this issue, if it expects an integer, or other nummeric value, it doesn’t do a parse on the string value.
For the moment I’m able to bypass this issue with a python script, that calls the ADS service in home assistant.

It’s a pitty that the data_template always returns string…

I just checked the ads code. The service “schema” does coerce the value parameter into an int. The issue, though, is that this uses the Python int function to do it. And that function can take an int, a float, or a string the represents an int, but not a string that represents a float. My guess is the brightness variable is holding a float (which gets turned into a string representation of that float value) when you get the error. So, you might try this:

          value: "{{ brightness|int }}"

That uses the Jina int filter, which will convert brightness to an int (in case it’s a float), before it gets turned into a string. Therefore, this template should always result in a string representation of an int, which will allow the service schema to convert it back to an int without error.

Hi @pnbruckner

Unfortunatly, it doesn’t work.
The error logs the same problem: integer required, got string.
Maybe another approach?

2019-01-17 21:15:42 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection.1704907376] Error handling message: {'id': 20, 'type': 'call_service', 'service_data': {'brightness': 61, 'entity_id': 'light.bediening_licht_fornuis'}, 'domain': 'light', 'service': 'turn_on'}
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/websocket_api/decorators.py", line 17, in _handle_async_response
    await func(hass, connection, msg)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/websocket_api/commands.py", line 148, in handle_call_service
    connection.context(msg))
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/core.py", line 1121, in async_call
    self._execute_service(handler, service_call))
  File "/usr/lib/python3.5/asyncio/futures.py", line 380, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.5/asyncio/tasks.py", line 304, in _wakeup
    future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
    raise self._exception
  File "/usr/lib/python3.5/asyncio/tasks.py", line 241, in _step
    result = coro.throw(exc)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/core.py", line 1143, in _execute_service
    await handler.func(service_call)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/light/__init__.py", line 287, in async_handle_light_on_service
    await light.async_turn_on(**pars)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/light/template.py", line 219, in async_turn_on
    {"brightness": kwargs[ATTR_BRIGHTNESS]}, context=self._context)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/script.py", line 131, in async_run
    await self._handle_action(action, variables, context)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/script.py", line 210, in _handle_action
    action, variables, context)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/script.py", line 299, in _async_call_service
    context=context
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/service.py", line 85, in async_call_from_config
    domain, service_name, service_data, blocking=blocking, context=context)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/core.py", line 1121, in async_call
    self._execute_service(handler, service_call))
  File "/usr/lib/python3.5/asyncio/futures.py", line 380, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.5/asyncio/tasks.py", line 304, in _wakeup
    future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
    raise self._exception
  File "/usr/lib/python3.5/asyncio/tasks.py", line 241, in _step
    result = coro.throw(exc)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/core.py", line 1145, in _execute_service
    await self._hass.async_add_executor_job(handler.func, service_call)
  File "/usr/lib/python3.5/asyncio/futures.py", line 380, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.5/asyncio/tasks.py", line 304, in _wakeup
    future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
    raise self._exception
  File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/ads/__init__.py", line 96, in handle_write_data_by_name
    ads.write_by_name(ads_var, value, ads.ADS_TYPEMAP[ads_type])
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/ads/__init__.py", line 153, in write_by_name
    return self._client.write_by_name(name, value, plc_datatype)
  File "/srv/homeassistant/lib/python3.5/site-packages/pyads/ads.py", line 533, in write_by_name
    value, plc_datatype)
  File "/srv/homeassistant/lib/python3.5/site-packages/pyads/pyads_ex.py", line 502, in adsSyncWriteByNameEx
    port, address, ADSIGRP_SYM_VALBYHND, handle, value, data_type
  File "/srv/homeassistant/lib/python3.5/site-packages/pyads/pyads_ex.py", line 301, in adsSyncWriteReqEx
    data = plc_data_type(value)
**TypeError: an integer is required (got type str)**

I wrote a Python helper script, it’s working now:

script:

adsvariable = data.get('ads_variablename')
adsvalue = data.get('ads_value')

if adsvariable is not None:
    service_data = { 'adstype': 'byte', 'adsvar': adsvariable, 'value': int(adsvalue) }
    hass.services.call('ads', 'write_data_by_name', service_data, True)

switch:

  set_level:
    service: python_script.adswriteint
    data_template:
      ads_variablename: gvlHomeAssistant.iDimLichtFornuis
      ads_value: "{{ brightness|int }}"

It seems that the ADS code really needs a typecasted integer.

Well, I’m glad it’s working for you. I’ve just been browsing through the HA ads component, as well as pyads, which it uses. As best I can tell you shouldn’t have had to do that. The ads component registers the write_data_by_name service with a schema that should be converting the value parameter to an int before being passed on to the lower-level pyads code (which is what is throwing the exception.) Out of curiosity, what version of HA are you using?

Well if it works out-of-the-box, with no need of extra scripts, is better of course.
But still, I can’t get it to work that way.

The version of HA I’m using is 0.85.1