Sensor for Days to Go

Hi

This is my code for days to go for my next bin collection. Why is it not showing the days to go ?

I use the same code for my days to go when using it for my google calendar. This time Im pulling the date from Node Red

- platform: template
  sensors:
    green_bin_countdown:
      friendly_name: Days to Go
      entity_id:
        - sensor.green_bin
        - sensor.date_time
      value_template: >
        {% set collection_sensor = states.sensor.green_bin.state %}
        {% set collection_date = strptime(collection_sensor,'%A %d %b %Y') %}
        {% set daystogo = strptime(collection_sensor, "%Y-%m-%d %H:%M:%S").strftime("%A") %}
        {% set daystogo2 = strptime(collection_sensor, "%Y-%m-%d %H:%M:%S").strftime("%b %d, %Y") %}
        {% if as_timestamp(collection_sensor) / 86400 - as_timestamp(as_timestamp(now()) | timestamp_custom("%Y-%m-%d 00:00:00",true)) / 86400 == 0.0 %}
        TODAY
        {% elif as_timestamp(collection_sensor) / 86400 - as_timestamp(as_timestamp(now()) | timestamp_custom("%Y-%m-%d 00:00:00",true)) / 86400 == 1.0 %}
        TOMORROW
        {% elif as_timestamp(collection_sensor) / 86400 - as_timestamp(as_timestamp(now()) | timestamp_custom("%Y-%m-%d 00:00:00",true)) / 86400 >= 7.0 %}
        {{ (as_timestamp(collection_sensor) / 86400 + 1 - as_timestamp(now()) / 86400) | int  }} days
        {% elif as_timestamp(collection_sensor) / 86400 - as_timestamp(as_timestamp(now()) | timestamp_custom("%Y-%m-%d 00:00:00",true)) / 86400 >= 2.0 %}
        {{ daystogo }}
        {% else %}
        Unknown
        {% endif %}

Thanks

Martyn

This code has been working for me.

        attribute_templates:
          summary: >
            {% set bid 
              = ((as_timestamp(states('input_datetime.garbage').split()[0])
              + 43200 - as_timestamp(now()))/43200)|int %}
            {% if bid < 0 %} Past
            {% elif bid == 0 %} Today
            {% elif bid < 3 %} Tomorrow
            {% elif bid < 28 %} in {{ ((bid+1)/2)|int }} days
            {% elif bid < 120 %} in {{ ((bid+1)/14)|int }} weeks
            {% elif bid < 1460 %} in {{ ((bid+1)/60)|int }} months
            {% else %} in {{ ((bid+1)/730)|int }} years {% endif %}

hi

What was your full sensor code for this please ?

no change on mine. It just says unknown

The rest of the sensor is a binary_sensor and likely not of use to you. My input_datetime.garbage should be equivalent to your sensor.greenbin. The state format for an input_datetime is YYYY-MM-DD HH:MM:SS. If sensor.greenbin does not match that then that’s the problem.
If your current code works for Google calendar then you need to investigate the state difference between sensor.greenbin and a Google calendar date. Likely there is a state format difference that is preventing it from working with your current code.

If you are just using this in the interface in an entities card, you can use the built in relative time calculations for your display.

sensor:
- platform: template
  sensors:
    green_bin_countdown:
      friendly_name: Green Bin Countdown
      device_class: timestamp
      value_template: >
        {% set collection_sensor = states.sensor.green_bin.state %}
        {% set collection_date = strptime(collection_sensor,'%A %d %b %Y') %}
        {{ as_timestamp(collection_date) | timestamp_custom('%Y-%m-%dT%H:%M:%S.%f+00:00', False) }}

It will countdown days, then hours, then minutes, then seconds until your date.

Does that work @petro ? Because the documentation says it only works for days in the past.

relative_time converts datetime object to its human-friendly “age” string. The age can be in second, minute, hour, day, month or year (but only the biggest unit is considered, e.g., if it’s 2 days and 3 hours, “2 days” will be returned). Note that it only works for dates in the past .

Right, that’s for the macro template method (mixing up work software and HA). I’m referring to hui-relative-time which is used throughout the UI to display device_class timestamp sensors. Assuming that @dicko will be using this in the UI in an entities field, it should return a correct time frame in the past or future.

Hi

I think the reason its not working for me is that is that the sensor is been created in Node-Red and the sensor is being classed as a string. Nothing seems to pick up what is coming through. Ive done more digging and its a EPOCH Number and the future date I am now counting down to is 1590447600 which is Tuesday 26th May. Im only after full days and do not require the hours and minutes. I can change the string format in Node-Red but it doesnt seem to matter either as I have tried.

Thanks and sorry if I didnt get all the info in the first place. This has been doing my head in for 2 days now.

All states are strings. Have you tried any other solution or are you making assumptions?

Hi. Im at a loss. I can get the date to leave Node Red without formatting to be EPOCH like I said above. I can use the moment node and change that to be what ever date format for the sensor in Home Assistant.

Ive searched the internet and also searched these forums and tried many solutions for trying to get it converted into days to go but nothing. the lovelace card shows unknown, unavailable and Ive even had invalid date format.

Ive also tried your code above too and below. I have 2 entities/sensors green_bin and green_bin_2 trying to get this working but my main sensor will be green_bin

- platform: template
  sensors:
    green_bin_countdown_web:
      friendly_name: Green Bin Countdown WEB
      device_class: timestamp
      entity_id:
        - sensor.green_bin_2
        - sensor.date_time
      value_template: >
        {{ (as_timestamp(now()) - as_timestamp("states.sensor.green_bin_2") ) | timestamp_custom("%j")| int }}

also tried this too but nothing that says days remaining

- platform: template
  sensors:
    green_bin_countdown:
      friendly_name: Next Green Bin Collection in
      entity_id:
        - sensor.green_bin
        - sensor.date_time
      value_template: >
        {% set bin_time = states('sensor.green_bin') %}
        {% set daystogo = (as_timestamp(now()) - as_timestamp(collection_date)) /86400 %}
        {% if daystogo < 1.0 %}
        Today
        {% elif daystogo < 2 %}
        Tomorrow
        {% elif daystogo < 28 %} in {{ ((daystogo+1)/2)|int }} days
        {% else%} 
        UNKNOWN
        {% endif %}

image
image

Regards

Martyn

This isn’t correct.

Take a look at people grabbing state information above.

now compare that to what you have

There are 2 method to grabbing state information.

  1. State method.
states('sensor.green_bin_2')
  1. From the State Object
states.sensor.green_bin_2.state

You wrapped your state object in quotes turning it into a string, which is a mixture of both methods. You should be using 1 or the other and you shouldn’t mix the two.

If you use the state object method, you shouldn’t use quotes around it anywhere. It’s an object, when you add quotes around it, you turn it into a string.

Hi

Thanks for all your help. I managed to get it working this morning but 1 more question.
I now have 2 sensors for the same item sensor.green_bin and sensor.green_bin_2

sensor.green_bin shows the epoch time of 1590447600

sensor.green_bin_2 shows the same date as 2020-05-26 00:00:00

I need the green_bin_2 date format for the script to work below but is there any chance to maybe bring it in as the epoch time and convert to the above date ?

Id also like to show the date as Tuesday 26th May 2020 on an entity card.

is there a way to do all this from 1 sensor rather than 2 or 3 ?

- platform: template
  sensors:
    green_bin_countdown:
      friendly_name: Next Green Bin Collection in
      entity_id:
        - sensor.green_bin_2
        - sensor.date_time
      value_template: >
        {% set daystogo = strptime(states('sensor.green_bin_2'), "%Y-%m-%d %H:%M:%S").strftime("%A") %}
        {% set daystogo2 = strptime(states('sensor.green_bin_2'), "%Y-%m-%d %H:%M:%S").strftime("%b %d, %Y") %}
        {% if as_timestamp(states('sensor.green_bin_2')) / 86400 - as_timestamp(as_timestamp(now()) | timestamp_custom("%Y-%m-%d 00:00:00",true)) / 86400 == 0.0 %}
        TODAY
        {% elif as_timestamp(states('sensor.green_bin_2')) / 86400 - as_timestamp(as_timestamp(now()) | timestamp_custom("%Y-%m-%d 00:00:00",true)) / 86400 == 1.0 %}
        TOMORROW
        {% elif as_timestamp(states('sensor.green_bin_2')) / 86400 - as_timestamp(as_timestamp(now()) | timestamp_custom("%Y-%m-%d 00:00:00",true)) / 86400 >= 7.0 %}
        {{ (as_timestamp(states('sensor.green_bin_2')) / 86400 + 1 - as_timestamp(now()) / 86400) | int  }} days
        {% elif as_timestamp(states('sensor.green_bin_2')) / 86400 - as_timestamp(as_timestamp(now()) | timestamp_custom("%Y-%m-%d 00:00:00",true)) / 86400 >= 2.0 %}
        {{ daystogo }}
        {% else %}
        Unknown
        {% endif %}

you can add them as attributes, then use custom cards to display different attributes throughout your ui.

SO, the above script has been working great at counting down and even showed TOMORROW up yesterday on the countdown but today, it should have shown TODAY but it is now showing unknown.

Why UNKNOWN ? I have tried changing from == 0.0 to <= 0.0 as I can see its less that 0.0 from another code in developer tools

Anyone any idea why it wont show TODAY ?

Thanks

well, it’s hard to follow your logic with all your in line conversions. I’d personally write it this way because it’s way easier to understand. This should work.

  {% set bin_time = as_timestamp(states('sensor.green_bin_2')) %}
  {% set midnight = now().replace(hours=0, minutes=0, seconds=0, microseconds=0).timestamp() + 86400 %}
  {% if bin_time =< midnight %}
    Today
  {% elif midnight < bin_time <= midnight + 86400 %}
    Tomorrow
  {% elif midnight + 86400 < bin_time <= midnight + 2*86400 %}
    {{ bin_time | timestamp_custom('%A') }}
  {% elif midnight + 86400 < bin_time <= midnight + 7*86400 %}
    {{ (bin_time-midnight) // 86400 }} days
  {% else %}
    unknown
  {% endif %}

Way easier to read and quickly fix.

Hi.

Thanks for that, I will keep this in mind in future but it didnt work. I had various errors when trying to implement. 1st was the the line below. I could not get valid code till I changed the =< to <=

{% if bin_time =< midnight %}

Once I did that, the code was valid but still would not show in the developers tab, so I tried the code on one of my bin sensors and it still showed unknown.

Any ideas ?

Thanks Martyn

As soon as midnight hit. It started working again. Its just the Today dates that dont seem to work.

image

Just reverse the signs, typo. <=

Hi

Thanks but id already tried that. Looked deeper into this and I think I had 1 too many if statements and this is now working for all variants.

Thanks for all your help and direction.

- platform: template
  sensors:
    green_bin_countdown:
      friendly_name: Green Bin days to go
      entity_id:
        - sensor.green_bin_2
        - sensor.date_time
      value_template: >
        {% set daystogo = strptime(states('sensor.green_bin_2'), "%Y-%m-%d %H:%M:%S").strftime("%A") %}
        {% set daystogo2 = strptime(states('sensor.green_bin_2'), "%Y-%m-%d %H:%M:%S").strftime("%b %d, %Y") %}
        {% if as_timestamp(states('sensor.green_bin_2')) / 86400 - as_timestamp(as_timestamp(now()) | timestamp_custom("%Y-%m-%d 00:00:00",true)) / 86400 < 1.0 %}
        TODAY
        {% elif as_timestamp(states('sensor.green_bin_2')) / 86400 - as_timestamp(as_timestamp(now()) | timestamp_custom("%Y-%m-%d 00:00:00",true)) / 86400 == 1.0 %}
        TOMORROW
        {% elif as_timestamp(states('sensor.green_bin_2')) / 86400 - as_timestamp(as_timestamp(now()) | timestamp_custom("%Y-%m-%d 00:00:00",true)) / 86400 >= 7.0 %}
        {{ (as_timestamp(states('sensor.green_bin_2')) / 86400 + 1 - as_timestamp(now()) / 86400) | int  }} days
        {% else %}
        {{ daystogo }}
        {% endif %}

I don’t think you should mark that as a solution. You’re calling double methods & multiple conversions in multiple spots and you have unused variables.

This is revised and works.

  {% set bin_time = as_timestamp(states('sensor.green_bin_2')) %}
  {% set midnight = now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp() + 86400 %}
  {% if bin_time <= midnight %}
    Today
  {% elif midnight < bin_time <= midnight + 86400 %}
    Tomorrow
  {% elif midnight + 86400 < bin_time <= midnight + 2*86400 %}
    {{ bin_time | timestamp_custom('%A') }}
  {% elif midnight + 86400 < bin_time <= midnight + 7*86400 %}
    {{ ((bin_time-midnight) // 86400) | int }} days
  {% else %}
    unknown
  {% endif %}

As for your template, if you are dead set on using it at least fix it so that others who come into this thread have a cohesive solution without errors & unnecessary conversions littered throughout it.

        {% set bin_day = as_timestamp(states('sensor.green_bin_2')) / 86400 %}
        {% set now_day = now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp() / 86400 %}
        {% if bin_day - now_day < 1.0 %}
          TODAY
        {% elif bin_day - now_day == 1.0 %}
          TOMORROW
        {% elif bin_day - now_day >= 7.0 %}
          {{ (bin_day + 1 - now_day) | int }} days
        {% else %}
          {{ (bin_day * 86400) | custom_timestamp('%A') }}
        {% endif %}
1 Like