Splitting config for template:

Yeah I was way ahead of you :slight_smile:

template:
  - sensor: !include template_sensors.yaml
  - binary_sensor: !include template_binary_sensors.yaml
  - template_trigger: !include  template_triggered_sensors.yaml

I’m a little concerned about that last one though. It does not seem to follow the documentation for template triggers. https://www.home-assistant.io/integrations/template/#trigger-based-template-sensors

it needs to be -trigger: not template_trigger: and each triggered sensor/binary sensor has to start with -trigger:

EDIT: ayup,

Logger: homeassistant.config
Source: config.py:445
First occurred: 01:13:43 (1 occurrences)
Last logged: 01:13:43

Invalid config for [template]: [template_trigger] is an invalid option for [template]. Check: template->template_trigger. (See /config/configuration.yaml, line 162).

I don’t see any way to do the template triggered sensors.

My mistake :grimacing:
However if inside configuration.yaml-

template:
  - sensor: !include template_sensors.yaml
  - binary_sensor: !include template_binary_sensors.yaml
  - trigger: !include  template_triggered_sensors.yaml

Then, inside template_triggered_sensors.yaml, you write-

- trigger:
    - platform: time_pattern
      hours: 0
      minutes: 0
  sensor:
    - name: Not smoking
      state: ""
      unit_of_measurement: "Days"

Wouldn’t at the end it would be like-

template:
  - trigger:
      - trigger:
          - platform: xx
            ...

Yep. That’s the issue I can’t see a way around.

What if you add 2 lines of template:

template: !include template_triggered_sensors.yaml

template:
  - sensor: !include template_sensors.yaml
  - binary_sensor: !include template_binary_sensors.yaml

No error from Check Configuration but I’m afraid one of them will be ignored.

Pretty sure that will generate a duplicate template: key error.

I don’t actually use triggered sensors as I find automations that publish retained mqtt messages and mqtt sensors initialise better after a restart. So I might just skip them.

In the off chance that I ever do need one I can bung it in configuration.yaml.

Tested on mine.

  1. Inside /config/integrations/template.yaml -
template:
  - sensor: !include_dir_list ../entities/templates/sensors
  - binary_sensor: !include_dir_list ../entities/templates/binary_sensors
  1. Inside /config/integrations/test.yaml -
template: !include_dir_list ../entities/templates/trigger_template
  1. Inside /config/entities/templates/trigger_template/justatest.yaml-
trigger:
  - platform: time_pattern
    # This will update every night
    hours: 0
    minutes: 0
sensor:
  # Keep track how many days have past since a date
  - name: Test
    state: 'unavailable'
    unit_of_measurement: "Days"

All sensors shows up fine including the trigger template.

1 Like

That’s not a flat directory structure though. Which was the aim. All in /config.

Oh! I think this will work:

template:
  - sensor: !include template_sensors.yaml
  - binary_sensor: !include template_binary_sensors.yaml
  - !include template_triggered_sensors.yaml

I could even have:

template:
  - sensor: !include template_sensors.yaml
  - binary_sensor: !include template_binary_sensors.yaml
  - !include template_triggered_sensors.yaml
  - !include template_triggered_binary_sensors.yaml
2 Likes

Just an update-

template:
  - sensor: !include_dir_list ../entities/templates/sensors
  - binary_sensor: !include_dir_list ../entities/templates/binary_sensors
  - !include_dir_list ../entities/templates/template_trigger

The above template.yaml passes config check. However, when inside `/config/entities/templates/template_trigger/justatest.yaml, I insert-

trigger:
  - platform: time_pattern
    # This will update every night
    hours: 0
    minutes: 0
sensor:
  # Keep track how many days have past since a date
  - name: This is just a test
    state: ""
    unit_of_measurement: "Days"

Resulting in-
Invalid config for [template]: expected a dictionary. Got [OrderedDict([('trigger', [OrderedDict([('platform', 'time_pattern'), ('hours', 0), ('minutes', 0)])]), ('sensor', [OrderedDict([('name', 'This is just a test'), ('state', ''), ('unit_of_measurement', 'Days')])])])]. (See ?, line ?).

I don’t know with yours, but it does not work with packages like mine.

Maybe because at the end it will turn out like-

template:
  - 
      - trigger:
          - platform: xx
            ...
1 Like

I have this working at the moment:

template:
  - sensor: !include template_sensors.yaml
  - binary_sensor: !include template_binary_sensors.yaml
#  - !include template_triggered_sensors.yaml
#  - !include template_triggered_binary_sensors.yaml

If I change it to:

template:
  - sensor: !include template_sensors.yaml
  - binary_sensor: !include template_binary_sensors.yaml
#  - !include template_triggered_sensors.yaml
  - !include template_triggered_binary_sensors.yaml

And include Taras’s triggered binary sensor from above, it passes the config check. fails config check.

Damn. back to square one.

Though as I said, in the unlikely case that I ever need a triggered sensor I can put it in my configuration.yaml file.

1 Like

I just tried the following and got no validation errors:

configuration.yaml:

template: !include template_sensors.yaml
template binary: !include template_binary_sensors.yaml
template triggered: !include template_triggered_sensors.yaml

template_sensors.yaml:

  - sensor:
      ##...

template_binary_sensors.yaml:

  - binary_sensor:
      #...

template_triggered_sensors.yaml:

  - trigger:
      ##...
    sensor:
      ##...
    binary_sensor:
      ##...

the only caveat is that those are exactly the way the files are written. They don’t have any actual sensor code in there at all, just the headings.

But it did pass the config check.

I assume it’s just like having multiple “automation:” or “script:” by adding another label after it to differentiate the two files/code. (“automation old:” or “script second:”)

It seemed to pass the quick config check but a restart failed miserably.

Hmmm…interesting…

it looks like the “template binary:” and “template triggered:” entries in configuration.yaml are completely ignored.

If I put any code in those files the files aren’t loaded. Nothing even in the logs about it

That seems like it should be an issue report to me.

It should work for the template integration just as it does for any other integration using the old “method 1” and “method 2” references. I can’t specifically find those references in the docs anymore but the concept is still discussed and should be valid. Or at least it should be made to work that way for consistency.

1 Like

Sorry to dredge up this old thread, but this is exactly what I’m trying to do; migrate all my templates to the new format, and at the same time, split them off into a new templates.yaml file.

Without the workaround @123 suggested (adding his dummy triggered sensor to the beginning of the templates.yaml file) I get errors. Put that sensor back in and it passes the configuration test.

So, @tom_l, did you ever get it working without the triggered sensor, and if so, how?

This thread has already saved me a ton of time. This was driving me crazy until I found the trigger workaround. Thank you!!

Yes. Like this:

template:
  - binary_sensor: !include template_binary_sensors.yaml
  - sensor: !include template_sensors.yaml

The template_sensors yaml file:

- name: 'Calculated Light Brightness'
  icon: "mdi:brightness-auto"
  unit_of_measurement: "Int"
  state: >
    {% if states('sensor.weatherflow_brightness') not in ['unknown', 'unavailable'] %}
      {% if now().hour >= 20 and now().hour < 23 and states('sensor.weatherflow_brightness')|float(0) <= 841 %}
        {{ ( -63.6667 * ( now().hour + now().minute / 60 ) + 1528.3333 )|int(0) }}
      {% elif now().hour == 23 or now().hour < 6 %}
        64
      {% else %}
        {{ ( [0, (-0.0428 * states('sensor.weatherflow_brightness')|float(0) + 291 )|int(0), 255]|sort )[1] }}
      {% endif %}
    {% else %}
        {{ states('sensor.calculated_light_brightness') }}
    {% endif %}

- name: 'Calculated Light Brightness No Late Dim'
  unit_of_measurement: "Int"
  state: >
    {{ ( [0, (-0.0428 * states('sensor.weatherflow_brightness')|float(0) + 291 )|int(0), 255]|sort )[1] }}

...etc

template_binary_sensors:

- name: "Everyone in Bed"
  icon: "mdi:sleep"
  state: >
    {% if is_state('input_select.automation_mode', 'Guest Away') %}
      {{ is_state('binary_sensor.spare_bed_occupied', 'on') }}
    {% elif is_state('input_select.automation_mode', 'Guest Home') %}
      {{ is_state('binary_sensor.master_bed_occupied', 'on') and is_state('binary_sensor.spare_bed_occupied', 'on') }}
    {% elif is_state('input_select.automation_mode', 'Normal') %}
      {{ is_state('binary_sensor.master_bed_occupied', 'on') }}
    {% else %}
      {{ false }}
    {% endif %}

- name: "Mstr Bed Sunrise Sim Active"
  icon: "mdi:weather-sunset-up"
  state: >
    {% set d = now().strftime("%Y-%m-%d ") %}
    {% set t = now().timestamp() %}
    {% set mbr_sun_sim_active = strptime(d + states('input_datetime.mstr_bed_sunrise_sim_time'), '%Y-%m-%d %H:%M:%S').timestamp() %}
    {{ mbr_sun_sim_active < t < ( mbr_sun_sim_active + 1800) }}

...etc

If I ever need to use triggered sensors they have to go in my configuration.yaml file listed under the includes.

2 Likes

I did something very similar but using a different YAML directive:

template: !include_dir_merge_list templates/

The templates sub-directory contains separate files:

  • binary_sensor.yaml
  • number.yaml
  • select.yaml
  • sensor.yaml
  • trigger.yaml
1 Like

Yeah that was always an option but…

Thanks, both of you, for the amazingly quick response!!!

I was going to use just one templates.yaml file, but two or more will work just as well.

Is this a bug? Should it be reported? There seem to be two workarounds now, so it’s not critical. I’m sure it will trip up other users going forward, as more people (hopefully) migrate to the new template method.

I wouldn’t characterize what tom_l and I have offered as being workarounds; they’re legitimate means of structuring the information in their own right. I don’t even know if what I suggested is immune to the reported glitch because I have not tried it without a trigger.yaml file (clearly tom_l’s suggestion isn’t affected by it).

However, to your point, it does feel like a bug because there should be no need to define at least one Trigger-based Template Sensor before others can be defined. If you know if still occurs in the latest release (I haven’t tested it), report it as an Issue in the GitHub Core repository.

1 Like

I have a way to split the templates to different folders. I know OP wanted flat files, but i like to nest and have multiple files.

Folder structure:

.
└── 
├──  configuration.yaml
└──  templates
       ├──  binary_sensor
       │    └──* place all template binary sensors in here *
       ├──  sensor
       │    └──* place all template sensors in here *
       └──  triggers
            ├──default_templates.yaml
            └──* place all template triggers in here *

configuration.yaml

template: !include_dir_merge_list templates/triggers/

config\templates\triggers\default_templates.yaml

  - binary_sensor: !include_dir_merge_list ../binary_sensor/
  - sensor: !include_dir_merge_list ../sensor/