Binary_sensor configuration feeding off result of another binary_sensor?

So is there a way to configure a binary_sensor that references another binary_sensor? Pretty sure there is a way to do it, but I’m getting an error in my setup. Here’s an example, where I’m attempting to reference:

binary_sensor:
  - platform: tod
    name: Night
    after: sunset
    before: sunrise

  - platform: tod
    name: Late Evening
    after: sunset
    before: Night

But I get the error “Invalid config for [binary_sensor.tod]: Invalid time specified: Night for dictionary value @ data['before']. Got 'Night'. (See ?, line ?).” when I test the configuration or in logs when I reload Home Assistant. So it appears that it will not allow me to reference a previously defined binary sensor. :frowning:

I’m thinking that there has to be a way, just haven’t been able to figure it out…

No, not like that. Even if you specified the correct template format for your night sensor (instead of just a string, “Night”), that tod option does not accept templates and even if it did, it expects expect times, not binary states.

And even ignoring all that, your logic is flawed.

  - platform: tod
    name: Late Evening
    after: sunset # <<<<< This says after sunset
    before: Night # <<<<< This  is defined as after sunset and before sunrise

“before: after sunset” is just before sunset. So you have both after sunset and before sunset in your tod definition. Which I guess is just “at sunset”. Except it also has to be “before: before sunrise”. It’s doing my head in just thinking about it.

Try writing down the times of day you want to identify. Then next to the items in that list, write down what defines those states.

Or just use the Sun2 custom integration that gives you:

solar_midnight The time when the sun is at its lowest point closest to 00:00:00 of the specified date; i.e. it may be a time that is on the previous day.
astronomical_dawn The time in the morning when the sun is 18 degrees below the horizon.
nautical_dawn The time in the morning when the sun is 12 degrees below the horizon.
dawn The time in the morning when the sun is 6 degrees below the horizon.
sunrise The time in the morning when the sun is 0.833 degrees below the horizon. This is to account for refraction.
solar_noon The time when the sun is at its highest point.
sunset The time in the evening when the sun is 0.833 degrees below the horizon. This is to account for refraction.
dusk The time in the evening when the sun is a 6 degrees below the horizon.
nautical_dusk The time in the evening when the sun is a 12 degrees below the horizon.
astronomical_dusk The time in the evening when the sun is a 18 degrees below the horizon.
1 Like

Thanks for the reply. I knew my logic needed some work, but my concern was whether I could do what I was trying to in the way I was attempting, so I just threw together an example.

If I lived near the equator, the changes in sunset and sunrise would not vary by much, and would be irrelevant. But where I live they vary by about 4.5 hours from solstice to solstice, and of course much more so farther from the equator. So in the winter, sundown happens during the late afternoon, but in the summer, during what I would term “late evening”. I have some actions that I want to happen based on the time of sundown and/or another event such as time of day, etc., hence my question.

Thanks again for the response. Still a noob and trying to get my head around the capabilities and restrictions of the hass environment.

HaHa - in a number of ways, we’re probably all still noobs! But, to the point of your question…

Here’s what I do - I tried the ToD platform first, and that didn’t have enough “features” for what I wanted to do - don’t get me wrong, it’s a great platform, but I needed a bit more than what it offered.

I then switched to the template platform and wrote some logic for the various ToD segments I wanted. This then takes inputs from input_number entities that I can adjust from the front end (not that I do that very often). This is in my binary_sensor section:

- platform: template
  sensors:
    afternoon:
      friendly_name: Afternoon
      value_template: >
        {% set delta_between_now_and_midnight = now().timestamp() - now().replace(hour=0).replace(minute=0).replace(second=0).timestamp() %}
        {% set target_start_timestamp = state_attr('input_datetime.late_morning_end','timestamp') %}
        {% set target_end_timestamp = state_attr('input_datetime.afternoon_end','timestamp')  %}
        {{ delta_between_now_and_midnight >= target_start_timestamp and
           delta_between_now_and_midnight < target_end_timestamp }}

The first line in the template calculates the number of seconds between and the previous midnight - so it’s the number of elapsed seconds since midnight.

The next two lines calculate the number of seconds from midnight to the starting and ending points of the afternoon segment. The input_datetime is defined as only time and is specified as the following in my configuration.yaml file:

input_datetime:
  late_morning_end:
    name: Late Morning End
    has_date: false
    has_time: true
    initial: 12:00
  afternoon_end:
    name: Afternoon End
    has_date: false
    has_time: true
    initial: 17:00

Once those are established, all we need to do is see if our delta_between_now_and_)midnight is between the starting and ending points - remember these are all seconds. If it is, then the logic within the {{....}} evaluates to true and the binary_sensor.afternoon turns on. Otherwise, it turns off.

You can paste this in your files directly and it will work after reloading the input date times and the template entities from the configuration/server controls panel (no need to completely restart HA).

Let me know if you run into issues!

Afterthought: To answer your direct question of whether or not you can include binary_sensor entities in other binary_sensor entities, you certainly can. Here’s an example of how to do that - as well as any other entity, for that matter:

    hvac_adj_occupancy:
      friendly_name: HVAC adjustment for occupancy 
      value_template: >
          {{  is_state('binary_sensor.no_house_motion_medium','on') and
              is_state('device_tracker.desktop_oke4kv5','not_home') and
              is_state('device_tracker.desktop_9munpsl','not_home') }}

This binary_sensor.hvac_adj_occupancy turns on if binary_sensor.no_house_motion_medium is on and the two device_tracker entities are not_home.

1 Like

I should have read a little further in your post - missed the sun condition. You can replace the input_datetime with a sun event, such as:

        {% set midnight_timestamp = now().replace(hour=0).replace(minute=0).replace(second=0).timestamp() %}
        {% set delta_between_now_and_midnight = now().timestamp() - midnight_timestamp %}
        {% set target_end_timestamp = as_timestamp(state_attr('sun.sun','next_setting')) - midnight_timestamp %}

The last line shows how to use the sun.sun attribute next_setting as a timestamp (seconds since some arbitrary date and time in the 1970s). By subtracting the midnight_timestamp calculated on the first line of the template, you again get the number of seconds since midnight.

1 Like

Wow! This is awesome! Thanks so much for the very detailed and expressive explanations and suggestions. I really appreciate the time you took, and it certainly helps a lot.

From reading this over a couple of times, I really think you’ve given me the exact information I was looking for, and even more! Being fairly new to this environment, I’m always coming across nuances of the system that I have not thought of before. And your suggestion of using seconds from midnight to calculate certain values got my mind out of the track it was in and opened up some additional possibilities that I hadn’t thought up.

I’ll certainly let you know if I have further questions or run into issues.

Take care,

Glad that made sense! I’m sure I borrowed it from someone - just can’t remember when or who :thinking:

1 Like