Python_script for countdown to birthdays/anniversaries/significant dates

yes, affirmative.
this works:

today = datetime.datetime.now().date()

name = data.get('name', 'special') # defaults to special
eventtype = data.get('type', 'event') # defaults to event
region = data.get('region', 'EU') # defaults to dirty european date format.
dateStr = data.get('date', r'01/01/{}'.format(today.year)) # defaults to jan 1st this year.

sensorName = "sensor.event_{}_{}".format(eventtype.lower(), name.replace(" " , "_").lower())

fmat = '%d/%m/%Y' if region == 'EU' else '%m/%d/%Y'

origin = datetime.datetime.strptime(dateStr, fmat).date()
event = origin.replace(year=today.year)
event = event if event > today else event.replace(year=event.year+1)

friendly_name = "{}'s {}".format(name, eventtype) if eventtype=='birthday' else "{} {}".format(name, eventtype)

hass.states.set(sensorName , (event-today).days,
  {
    #"icon" : "mdi:calendar-star" ,
    "entity_picture": "/local/family/{}.jpg".format(name.lower()),
    "unit_of_measurement" : "days" ,
    "person" : name,
    "friendly_name" : friendly_name,
    "years" : (event-origin).days//365,
    "origin": "{}-{}-{}".format(origin.day,origin.month,origin.year),
    "next_event":"{}-{}-{}".format(event.day,event.month,event.year)
  }
)

Thanks for your response. it seams that i didn’t saved the file since i couldn’t find your script on my python file. All works good now.
Thanks for your help.

hay bro dont think its no-no

just that has it own mine and its getting better better everyday

most of the scripts written in here are to solve a problem we i want solve and then other
add there 5 cents and make something that is good beater.

do love the region bit you added makes cents

It is though. It’s overwriting a built in main function of python. It can cause major problems.

snap bro just looking at and that came to my mine to

I was all with you for a while, and then you said

… and I realised its time for your meds :stuck_out_tongue_winking_eye:

In the words of Her Royal Highness, there is no such thing as American English, there is English and there are mistakes :wink:

Anyway, duly noted, I’ll revise the script when I get a sec. Thanks mate :+1:

1 Like

I currently am sending out notices 7 days before an event like:

- alias: Reminder - Sue's birthday is coming up
  trigger:
    - platform: state
      entity_id: sensor.birthday_sue
      to: '7'
  action:
    - wait_template: "{{ states('sensor.time') == '10:00' }}"
    - service: notify.mobile_app_jiphone
      data:
        message: "Sue's birthday is only a week away!"

if I wanted to also be notified on the day of her birthday would I have to duplicate the above and replace 7 with 0 and update the message? Or is there a way to trigger an “or” for 7 or 0 and send a message based on if it’s 7 days away or 0?

I’m on my mobile in the car right now so I’m not going to try and post code, but a second trigger with the to: ‘0’ and a templated message will cover this scenario :slightly_smiling_face:

Thanks Marc. Would something like this work?

- alias: Reminder - Sue's birthday is coming up
  trigger:
    - platform: state
      entity_id: sensor.birthday_sue
      to: '7'
    - platform: state
      entity_id: sensor.birthday_sue
      to: '0'
  action:
    - wait_template: "{{ states('sensor.time') == '10:00' }}"
    - service: notify.mobile_app_jiphone
      data:
        message: "Sue's birthday is only a week away!"

Then need to conditionally send different messages if it’s 7 days or not. Not being my only other option of 0.

- service: notify.mobile_app_jiphone
  data_template:
    message: "Sue's birthday is {{ 'today' if trigger.to_state.state == '0' else 'only a week away'}}!"

Try that :+1:

Worked good thanks.

1 Like

please let me get back to this.
Id like to create a button which pops up in the anniversary day, showing the person/event and the years count.

For that I (think) I need a sensor.party_today which holds the attributes like the sensor countdown makes, to be able to show in the button like this:

type: custom:button-card
template: button_body
entity: 'sensor.today_party'
aspect_ratio: 1/1
name: Party

#icon:
show_state: false
show_entity_picture: true
entity_picture: >
  [[[ return entity.attributes.entity_picture ]]
tap_action:
  action: navigate
  navigation_path: tijd_agenda
hold_action:
  action: call_service
  service: persistent_notification.dismiss
  service_data:
    notification_id: party_notification
styles:
  card:
    - padding: 5px
    - font-size: 10px
    - color: blue
    - background: ivory
  grid:
    - grid-template-areas: '"n n" "years years" "original_date original_date"'
    - grid-template-columns: 1fr 1fr
    - grid-template-rows: 1fr min-content min-content min-content
  name:
    - align-self: middle
    - justify-self: start
    - padding-bottom: 4px
  img_cell:
    - margin: none
  icon:
    - color: red
    - width: 70%
    - margin-top: -5%
  custom_fields:
    years:
      - padding: 5px
      - align-self: start
      - justify-self: end
      - --text-color-sensor: green
    original_date:
#      - padding-bottom: 2px
      - align-self: middle
      - justify-self: start
      - --text-color-sensor: green

custom_fields:

  years: >
    [[[
      return `<ha-icon
        icon='mdi:calendar-star'
        style='width: 12px; height: 12px;'>
        </ha-icon><span>Years:<span style='color: var(--text-color-sensor);'>${entity.attributes.years} </span></span>`
    ]]]
  original_date: >
    [[[
      return `<ha-icon
        icon='mdi:calendar'
        style='width: 12px; height: 12px;'>
        </ha-icon><span>Date: <span style='color: var(--text-color-sensor);'>${entity.attributes.original_date}</span></span>`
    ]]]

been turning my head round this, if this could be added to the python script, or maybe should be a template sensor built around an anniversary sensor with numberofDays = 0.

Can’t make it yet, so seek some assistance here please. As a side note, I need it to be able to handle double events on a day (have 2 anniversaries on the day of tomorrow :wink: )

for the sake of it, I made a group with all relevant sensors, group.party_counters. Hope to create a template that expands that group, checks for state == 0 of each member and then create the sensor.today_party ?

this at least gives me a list of relevant sensors with the state == 0

value_template: >
  {% set party = expand('group.party_counters')|selectattr('state','eq','0')      
                                     |map(attribute='entity_id')
                                     |list %}
  {{ party }}

now how to get these sensors in the button, either directly, or via a dynamically made intermediary sensor:

for each entity_id in {{party}} create a sensor with name, entity_picture, event, years and origin.

please have a look if you can help me? thanks!

Anyone ever create some cool lovelace views of your countdowns you would like to share? I was just getting to creating a page in my setup to display them and thought I see if anyone had any ideas they would like to share.

Hi, hwo is this installabel via HACS? Cant find in this forum, and not in guthub. Is this btw the “best” solution for a countdowntimer entity?

Go to hacs, automation, add and type date countdown (or just uncheck the appdaemon filter and date countdown should be the top python script), tap install, done.

since HA 115 this setup give me an awful lot of errors like:

2020-09-21 17:54:49 ERROR (MainThread) [homeassistant.components.websocket_api.commands] TemplateError('UndefinedError: 'None' has no attribute 'attributes'') while processing template 'Template("{{states.sensor.birthday_marijn.attributes.type}}: {{states.sensor.birthday_marijn.attributes.original_date}}

on all attributes, and on all sensors the automation is supposed to make on HA start, by means of:

automation:

  - alias: Refresh date countdown sensors
    trigger:
      - platform: state
        entity_id: sensor.date
      - platform: homeassistant
        event: start
    action:
#      - service: same for all family members and some other important dates
      - service: python_script.date_countdown
        data:
          name: Marijn
          type: birthday
          date: 01/02/2001

there’s no understanding other than the python script wouldn’t have created the sensors in time, but, that should really be impossible, since A- this has worked ever since it was written in this form, and, more importantly B- the error presents itself rather a long time after homeassistant state has passed. Or so I think. Of course, I could defer it some, by adding it to the delayed startup sequence (+35 seconds). But that would defeat finding out why 115 causes this to be delayed so much.

Did anyone else using this python script experience something of the kind?

thanks for having a look

No, my date_countdown sensors are all working fine (obviously, because I wrote the script :wink: )

haha, yes, the script itself works perfectly, even with my own extensions.

It is more that somehow the python scripts seem to not run as quickly on homeassistant start as before, causing these UndefinedError in the template engine.
Or maybe the other way round: the new template engine is so fast, it tries to ‘read’ and create these template sensors (based on the sensor made in the python script) before they are made. I have other python scripts that create sensors, quite extensively, so maybe this is causing the slowdown (things waiting for each other) I am experiencing.

Will ask Bdraco and Amelchio.

I think it is this issue: Template Sensor Throws Error But Only at Startup; Works Otherwise · Issue #40382 · home-assistant/core · GitHub

yes! that describes exactly what I am seeing here. Maybe this is even causing some kind of loop or race which causes the spike in processor usage?
Glad you fixed that! when can we expect that to enter the updates?