enkama / hass-variables

Home Assistant variables component
91 stars 11 forks source link

Service "variable.set_variable" not working with template. #22

Closed muellthosbutler closed 1 year ago

muellthosbutler commented 1 year ago

Service "variable.set_variable" not working with template.

I tried this: image but no state change occured. But when I use Service "variable.set_entity" it works as expected: service: variable.set_entity data: entity: variable.setztest value: "{{(states('variable.preis_ltr') | float() / 2.19) | round(4)}}"

enkama commented 1 year ago

Hey. Not really sure what to tell you. This template works just fine for me.

      - service: variable.set_variable
        data:
          variable: blank_birthday_days2go
          value: >
            {% set year = states('sensor.date').split('-')[0] %}
            {% set month = states('sensor.date').split('-')[1] %}
            {% set date = states('sensor.date').split('-')[2] %}
            {% if states('variable.blank_birthday') != "unknown" %}
              {%- set bDayMonth = states('variable.blank_birthday').split('-')[0] -%}
              {%- set bDayDate = states('variable.blank_birthday').split('-')[1] -%}
              {%- set numOfDays = ((as_timestamp(strptime(year ~ '-' ~ bDayMonth ~ '-' ~ bDayDate , '%Y-%m-%d')) | timestamp_custom('%j', true) | int ) - (as_timestamp(strptime(year ~ '-' ~ month~ '-' ~ date , '%Y-%m-%d')) | timestamp_custom('%j', true) | int)) -%}
              {%- if numOfDays < 0 -%}
                {{ numOfDays + 365 }}
              {%- else -%}
                {{ numOfDays }}
              {%- endif -%}
            {% else %}
              -
            {% endif %}
enkama commented 1 year ago

So its nothing really I can do.

7ooL commented 1 year ago

I'm having same issue

how vars are defined variable: office_motion_last_motion: value: 'Not set' restore: true attributes: icon: mdi:motion-sensor

first service call

service: variable.set_variable data: variable: variable.office_motion_last_motion attributes: history_1: '{{ states(''variable.office_motion_last_motion'') }}' history_2: '{{ state_attr(''variable.office_motion_last_motion'',''history_1'') }}' history_3: '{{ state_attr(''variable.office_motion_last_motion'',''history_2'') }}' history_4: '{{ state_attr(''variable.office_motion_last_motion'',''history_3'') }}' history_5: '{{ state_attr(''variable.office_motion_last_motion'',''history_4'') }}' history_6: '{{ state_attr(''variable.office_motion_last_motion'',''history_5'') }}' history_7: '{{ state_attr(''variable.office_motion_last_motion'',''history_6'') }}' history_8: '{{ state_attr(''variable.office_motion_last_motion'',''history_7'') }}' history_9: '{{ state_attr(''variable.office_motion_last_motion'',''history_8'') }}' history_10: '{{ state_attr(''variable.office_motion_last_motion'',''history_9'') }}' second service call

service: variable.set_variable data: variable: variable.office_motion_last_motion value: > {{ trigger.to_state.attributes.friendly_name }} : {{ as_timestamp(trigger.to_state.last_changed)| timestamp_custom('%x, %X') }}

7ooL commented 1 year ago

also can confirm that changing the same service calls to set_entity and chaging the data attributes works.

VikingGer commented 1 year ago

Maybe, my issue stems from the same problem. When initialising a variable with a template, the template is not interpreted but simply taken as a string, like:

variable:
  temp_delta:
    value: "{{ states('sensor.temperature_warm_water') }}"

Template editor:

{{ states.variable.temp_delta.state }} {{ states('sensor.temperature_warm_water') }}

Result type: string {{ states('sensor.temperature_warm_water') }} 15.2

Edit: When setting the variable manually, The set_variable works flawlessly:

  - service: variable.set_variable
    data:
      variable: temp_delta
      value: '{{ states.sensor.temperature_warm_water.state }}'

BTW, I tried it with both object and value type of sensor.temperature_warm_water

VikingGer commented 1 year ago

I got a not too deep look into the code and I guess, it has something to do with the removal of the value_template option.

ATTR_VALUE = "value"
ATTR_VALUE_TEMPLATE = "value_template"
        vol.Optional(ATTR_VALUE): cv.match_all,
        vol.Optional(ATTR_VALUE_TEMPLATE): cv.template,

In "https://github.com/home-assistant/core/blob/dev/homeassistant/helpers/config_validation.py" the function are defined as:

def template(value: Any | None) -> template_helper.Template:
    """Validate a jinja2 template."""
    if value is None:
        raise vol.Invalid("template value is None")
    if isinstance(value, (list, dict, template_helper.Template)):
        raise vol.Invalid("template value should be a string")

    template_value = template_helper.Template(str(value))

    try:
        template_value.ensure_valid()
        return template_value
    except TemplateError as ex:
        raise vol.Invalid(f"invalid template ({ex})") from ex

def match_all(value: _T) -> _T:
    """Validate that matches all values."""
    return value

This leads to my assumption that in the old code the template syntax was properly processed which is not anymore now. Therefore I assume things could go awry somewhere on the processing path. Thus I suggest to reimplement the value_template option to be able to properly use template code again.

enkama commented 1 year ago

Hey!

Feel free to do a pull request. I sadly dont have the time right now or in the next weeks. Gonna be pretty busy.

VikingGer commented 1 year ago

Hi I think, I was generally wrong and likely mixed things up. It's probably not due to the removed "value_template". I tried putting some old code into yours and it didn't work either; maybe cause my code implementation wasn't correct. It seems to me that the value when initializing the variable may always be converted to a string, but the value from "variable.set_variable" value isn't. However, I haven't found anything obvious, analyzing your code. I did some workaround with setting the variable via automation, which is not nice, but works:

- id: '1672407865800'
  alias: Set WW temp variable
  description: Since initiation cannot done with a template, we init with 0 and change it
  trigger:
  - platform: template
    value_template: '{{ states.variable.temp_delta.state == 0 }}'
  condition: []
  action:
  - service: variable.set_variable
    data:
      variable: temp_delta
      value: '{{ states.sensor.temperature_warm_water.state }}'
  mode: single
pickonedev commented 1 year ago

Service "variable.set_variable" not working with template.

I tried this: image but no state change occured. But when I use Service "variable.set_entity" it works as expected: service: variable.set_entity data: entity: variable.setztest value: "{{(states('variable.preis_ltr') | float() / 2.19) | round(4)}}"

Try like this:

          - service: variable.set_variable
            data:
              variable: entrance_switch_battery
              value: >-
                {{trigger.payload_json['ZbReceived']['Entrance_Switch']['BatteryPercentage']}}

For me it is working very good if you want to store a number, not a string. Seems that you store as a string, in the value of the variable

enkama commented 1 year ago

Will close this for now.