Custom component to declare/set variables

Thanks for the hint! I got the value template example from next to last automation here

So I should change

  action:
    service: variable.set_variable
    data:
      variable: posta_variable
      value_template: "{{ states('sensor.cp_packages_coming_today')}}"
      attributes_template: >
        {
          "from": "{{ state_attr('sensor.cp_packages_coming_today', 'from') }}",
          "date": "{{ state_attr('sensor.cp_packages_coming_today', 'date') }}",
          "subject": "{{ state_attr('sensor.cp_packages_coming_today', 'subject') }}",
          "body": "{{ state_attr('sensor.cp_packages_coming_today', 'body') }}"
        }

To:

  action:
    service: variable.set_variable
    data:
      variable: posta_variable
      attributes_template: >
        {
          "from": "{{ state_attr('sensor.cp_packages_coming_today', 'from') }}",
          "date": "{{ state_attr('sensor.cp_packages_coming_today', 'date') }}",
          "subject": "{{ state_attr('sensor.cp_packages_coming_today', 'subject') }}",
          "body": "{{ state_attr('sensor.cp_packages_coming_today', 'body') }}"
        }
      data_template:
        value: >
          {{ states('sensor.cp_packages_coming_today') }}

Is that what you are suggesting?

Oh, actually just re-read it and it looks like you mean instead to change:

  action:
    service: variable.set_variable
    data:
      variable: posta_variable
      value_template: "{{ states('sensor.cp_packages_coming_today')}}"
      attributes_template: >
        {
          "from": "{{ state_attr('sensor.cp_packages_coming_today', 'from') }}",
          "date": "{{ state_attr('sensor.cp_packages_coming_today', 'date') }}",
          "subject": "{{ state_attr('sensor.cp_packages_coming_today', 'subject') }}",
          "body": "{{ state_attr('sensor.cp_packages_coming_today', 'body') }}"
        }

To:

  action:
    service: variable.set_variable
    data_template:
      variable: posta_variable
      value_template: "{{ states('sensor.cp_packages_coming_today')}}"
      attributes_template: >
        {
          "from": "{{ state_attr('sensor.cp_packages_coming_today', 'from') }}",
          "date": "{{ state_attr('sensor.cp_packages_coming_today', 'date') }}",
          "subject": "{{ state_attr('sensor.cp_packages_coming_today', 'subject') }}",
          "body": "{{ state_attr('sensor.cp_packages_coming_today', 'body') }}"
        }

Is that right? Strange it’s not documented anywhere.

Can someone please help me using this variables to have an history of recent zones? I will use it for custom messages based on device tracking.

@scstraus The second one looks correct (at least for the value).

I use input_select for this purpose and it works well.

- id: zone_to_dropdown
  alias: 'Zone to Dropdown'
  hide_entity: true
  initial_state: 'true'
  trigger:
    platform: state
    entity_id: device_tracker.seans_iphone_x
  action:
    service: input_select.select_option
    entity_id: input_select.sean_last_zone_dropdown
    data_template:
      option: '{{ states.device_tracker.seans_iphone_x.state }}'

This is sufficient to create a vector of my movement like so:

- id: left_work_1
  alias: 'Left Work 1'
  hide_entity: true
  initial_state: 'true'
  trigger:
    platform: state
    entity_id: device_tracker.seans_iphone_x
    to: 'not_home'
  condition:
    - condition: and
      conditions:
        - condition: time
          after: '18:00:00'
          weekday:
          - mon
          - tue
          - wed
          - thu
          - fri
        - condition: state
          entity_id: 'input_select.sean_last_zone_dropdown'
          state: 'Work'
  action:
    service: input_select.select_option
    data:
      entity_id: input_select.sean_location_dropdown
      option: Left Work

Only hassle is that you have to define the zones

input_select:
  sean_last_zone_dropdown:
    name: Sean Last Zone
    options:
      - home
      - ToAndel
      - Andel
      - Lazarska
      - ToCenter
      - Work
      - SmichovskeNad 
      - ToWineFood
      - WineFood
      - ToHornbachP5
      - HornbachP5
      - FromHornbachP5
      - BioStore
      - Yoga
      - Billa
      - Posta
      - IkeaZlicin
      - ToP6
      - FromP6HomeHighway
      - FromP6HomeBackWay
      - ToHornbachP6
      - FromHornbachP6
      - HornbachP6
    initial: home

My full config is available here

Location automations are here

Unfortunately the change from data to data_template didn’t fix it :frowning:. Any other ideas?

this is the format I use, and it works just perfectly:

a script, recieving variable {{tostate}} from the calling automation:

  set_daylight_variables:
    alias: 'Set Daylight variables'
    sequence:
      - service: variable.set_variable
        data:
          variable: virtual_light_daylight
          attributes_template: >
            {
                  "history_1": "{{ variable.state }}",
                  "history_2": "{{ variable.attributes.history_1 }}",
                  "history_3": "{{ variable.attributes.history_2 }}",
                  "history_4": "{{ variable.attributes.history_3 }}",
                  "history_5": "{{ variable.attributes.history_4 }}"
            }
        data_template:
          value: >
            {{tostate}} : {{states('sensor.virtual_light')}} : 
            {{states('sensor.poort_buiten_motion_sensor_light_level')}}

or a standalone automation action part:

    action:
      service: variable.set_variable
      data:
        variable: last_motion
        attributes_template: >
          {
                "history_1": "{{ variable.state }}",
                "history_2": "{{ variable.attributes.history_1 }}",
                "history_3": "{{ variable.attributes.history_2 }}",
                "history_4": "{{ variable.attributes.history_3 }}",
                "history_5": "{{ variable.attributes.history_4 }}",
                "history_6": "{{ variable.attributes.history_5 }}",
                "history_7": "{{ variable.attributes.history_6 }}",
                "history_8": "{{ variable.attributes.history_7 }}",
                "history_9": "{{ variable.attributes.history_8 }}",
                "history_10": "{{ variable.attributes.history_9 }}"
          }
      data_template:
        value: >
          {{ trigger.to_state.attributes.friendly_name|replace('motion sensor','') }}:
          {{as_timestamp(states.variable.last_motion.last_changed)| timestamp_custom('%X') }}

Below is the code that I have (and it works perfectly):

  - service: variable.set_variable
    data_template:
      variable: router_temp_high_alert
      value_template: >-
        {% if states.sensor.t_router.state != 'unknown' and states.sensor.t_router.state | float > 85 %}
        on
        {% else %}
        off
        {% endif %}

that code only sets a value, no attribute history. Why use the variable in the first place then, and not simply a template sensor?

Thanks @Mariusthvdb, that was a big help!

That worked to make the template for the main value of the sensor work (which in and of itself is a big help) when I take out the attributes like this:

- id: posta_state_change
  alias: 'Posta state change'
  hide_entity: true
  initial_state: 'true'
  trigger:
    platform: state
    entity_id: sensor.cp_packages_coming_today
  condition:
    condition: state
    entity_id: 'sensor.cp_packages_coming_today'
    state: 'delivery'
  action:
    service: variable.set_variable
    data:
      variable: posta_variable
    data_template:
      value: >
          {{ states('sensor.cp_packages_coming_today')}}

But when I put the attributes back in like this:

- id: posta_state_change
  alias: 'Posta state change'
  hide_entity: true
  initial_state: 'true'
  trigger:
    platform: state
    entity_id: sensor.cp_packages_coming_today
  condition:
    condition: state
    entity_id: 'sensor.cp_packages_coming_today'
    state: 'delivery'
  action:
    service: variable.set_variable
    data:
      variable: posta_variable
      attributes_template: >
        {
          "from": "{{ state_attr('sensor.cp_packages_coming_today', 'from') }}",
          "date": "{{ state_attr('sensor.cp_packages_coming_today', 'date') }}",
          "subject": "{{ state_attr('sensor.cp_packages_coming_today', 'subject') }}",
          "body": "{{ state_attr('sensor.cp_packages_coming_today', 'body') }}"
        }
    data_template:
      value: >
          {{ states('sensor.cp_packages_coming_today')}}

I get this:

2019-05-15 23:47:16 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/config/custom_components/variable/__init__.py", line 179, in async_set_variable
    attributes = json.loads(attributes_template.async_render({ 'variable': current_state }))
  File "/usr/local/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/usr/local/lib/python3.7/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/lib/python3.7/json/decoder.py", line 353, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Invalid control character at: line 5 column 50 (char 188)

I’m guessing it’s choking on some characters in the attributes and crashing?

looking at the docs try removing “data_template:” and change value to “value_template”.

Like this:

action:
    service: variable.set_variable
    data:
      variable: posta_variable
      attributes_template: >
        {
          "from": "{{ state_attr('sensor.cp_packages_coming_today', 'from') }}",
          "date": "{{ state_attr('sensor.cp_packages_coming_today', 'date') }}",
          "subject": "{{ state_attr('sensor.cp_packages_coming_today', 'subject') }}",
          "body": "{{ state_attr('sensor.cp_packages_coming_today', 'body') }}"
        }
      value_template: >
        {{ states('sensor.cp_packages_coming_today')}}

EDIT: sorry, I forgot to change the thing I told you to change. :man_facepalming:

one could of course try that, but this is the format that been working for me ever since I started using CC variable, posted above at:

yes, and its doing so in variable while getting the ‘current state’ of the entity_id.

must confess the templates renders fine in my dev-template.
You do have quotes around the entity_id in the condition though, which shouldn’t be there… seems a long shot, but please take these out and see what gives.

or maybe even better change the condition to:

condition: template
value_template: >
  {{'is_state('sensor.cp_packages_coming_today','delivery')}}

which can be checked in the dev-template …

So, I’ve got some of the attributes working. In the case of all 4 variables I was using, it was the body of the email that was causing the problem (in addition to the wrong syntax I had before). It’s quite obvious to me now that the body of the email is just too big for the string that the variable uses to hold it’s data. So, for now I will use it without the body of the email. The below syntax works:

- id: posta_state_change
  alias: 'Posta state change'
  hide_entity: true
  initial_state: 'true'
  trigger:
    platform: state
    entity_id: sensor.cp_packages_coming_today
  condition:
    condition: state
    entity_id: 'sensor.cp_packages_coming_today'
    state: 'Delivery'
  action:
    service: variable.set_variable
    data:
      variable: posta_variable
      attributes_template: >
        {
          "from": "{{ state_attr('sensor.cp_packages_coming_today', 'from') }}",
          "date": "{{ state_attr('sensor.cp_packages_coming_today', 'date') }}",
          "subject": "{{ state_attr('sensor.cp_packages_coming_today', 'subject') }}"
        }
    data_template:
      value: >
          {{ states('sensor.cp_packages_coming_today')}}

States are limeted to 255 chars, but attributes dont have this limitation.

There’s something special about the bodies of each of those 4 different emails sent to 4 different variable’s attributes that’s making it blow up whereas the subject, from and to do not… Either length or some characters in them… Either way, I can’t use it for email bodies the way it is now…

I’ve been trying to get this working, with no luck. Most all of the instructions and posts I’ve read, say to copy the “variable.py” to “custom_components”. So I did. But that file is not on github, I just happened to find it posted here, and a also or more recent version. Which is odd, since the readme on github specifically states to use “variable.py”. Where is it??

I then read on another thread to copy the three files in the “variable” folder on github into “custom_components/variable/”, so I did that. It still does not work. I am getting an error:

Setup failed for variable: No setup function defined.

I show no “variable” service.

I have a very simple variable set up in my configuration, nothing complicated.

I have custom updater running in that folder, so I know that much isn’t the problem. Reading through the posts here, it seems so simple, but after looking at github, and reading other posts, it’s incredibly confusing. I am by no means knowledgeable about home assistant, but I’m learning, and this is the first thing haven’t been able to get working.

Help. Please…

The three files should be in custom_components/variable folder.

.homeassistant/custom_components/variable/
├── __init__.py
├── manifest.json
└── services.yaml

Be sure to download the files in raw mode.

2 Likes

Well, thanks to this example, I realized I only had single underscores in init.py. :upside_down_face:

All seems to be working now! thank you.

Also I found a related SQL error… sensor.dpd_packages_coming_today is the exact same sensor, just with different email content for a different shipping provider. Here’s the error:

Error executing query: (MySQLdb._exceptions.DataError) (1406, “Data too long for column ‘event_data’ at row 1”) [SQL: ‘INSERT INTO events (event_type, event_data, origin, time_fired, created, context_id, context_user_id) VALUES (%s, %s, %s, %s, %s, %s, %s)’] [parameters: (‘state_changed’, ‘{“entity_id”: “sensor.dpd_packages_coming_today”, “old_state”: {“entity_id”: “sensor.dpd_packages_coming_today”, “state”: “Delivery”, “attributes”: { … (72419 characters truncated) … :00", “last_updated”: “2019-05-31T06:45:12.660235+00:00”, “context”: {“id”: “3daf7b0e44124eb59eb2f765fa277ae7”, “parent_id”: null, “user_id”: null}}}’, ‘LOCAL’, datetime.datetime(2019, 5, 31, 6, 45, 12, 660283, tzinfo=), datetime.datetime(2019, 5, 31, 6, 45, 12, 670672), ‘3daf7b0e44124eb59eb2f765fa277ae7’, None)] (Background on this error at: Error Messages — SQLAlchemy 2.0 Documentation)

What’s the max length a variable can be? Is it 256 chars? Thanks