Yes sir…
cool Mark,
now, another question: could the day (of the next occurence) be incorporated easily into the script? Is something I always need when checking for upcoming parties
Hey, just to let you know, your script has a no-no and there’s some simplifying that you can do. By no-no i mean you’re overriding the built in type
method.
The optimization would just be a personal preference.
You can also build in some ‘safety’ in case people don’t fully configure the thing.
Also, I added the awesome and far superior US date style.
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.{}_{}".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" ,
"unit_of_measurement" : "days" ,
"friendly_name" : friendly_name,
"nextoccur" : event.strftime(fmat),
"years" : (event-origin).days//365,
}
)
uses
automation:
- alias: Reminder - Refresh date countdown sensors
initial_state: on
trigger:
- platform: time
at: '00:00:01'
- platform: homeassistant
event: start
action:
- service: python_script.date_countdown
data:
name: John
type: birthday
date: 17/08/1971
- service: python_script.date_countdown
data:
name: Our wedding
type: anniversary
date: 14/02/1994
- service: python_script.date_countdown
data:
name: Superior Date Style
type: birthday
date: 11/22/2019
region: US
above yields:
Log Details (ERROR)
Fri Nov 22 2019 16:10:56 GMT+0100 (CET)
Error executing script: name 'dateStr' is not defined
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/python_script/__init__.py", line 195, in execute
exec(compiled.code, restricted_globals, local)
File "event_date.py", line 12, in <module>
NameError: name 'dateStr' is not defined
Oops, fixed typo
… still some left. I think we need to quote the ‘birthday’ because it errors out on not defined otherwise.
friendly_name = "{}'s {}".format(name, eventtype) if eventtype=='birthday' else "{} {}".format(name, eventtype)
more importantly:
Fri Nov 22 2019 16:22:05 GMT+0100 (CET)
Error executing script: '__import__'
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/python_script/__init__.py", line 195, in execute
exec(compiled.code, restricted_globals, local)
File "event_date.py", line 24, in <module>
KeyError: '__import__'
the ever present import issues in the HA Python sandbox. Line 24 is
"nextoccur" : event.strftime(fmat),
Nothing to import though. You can remove the strftime. I can’t test til I get home
ok, and o dear…
taking that out gives:
hass.states.set(sensorName , (event-today).days,
{
"icon" : "mdi:calendar-star" ,
"unit_of_measurement" : "days" ,
"person" : name,
"friendly_name" : friendly_name,
"nextoccur" : event,
"years" : (event-origin).days//365,
"origin" : origin,
}
)
and it takes down my HA instance once more, as reported above.
Unable to serialize to JSON: Object of type date is not JSON serializable
and then followed by the full config in the log for all entities and all their attributes…
must have to do with the 'next_occurand
origin` I added, because when I simply used dateString in the original script I got the same errors, and had to use:
"original_date" : "{}-{}-{}".format(dateDay,dateMonth,dateYear)
I mean if you just want it working you can split it out. or just cast it to a string but it will be year-month-day format
hass.states.set(sensorName , (event-today).days,
{
"icon" : "mdi:calendar-star" ,
"unit_of_measurement" : "days" ,
"person" : name,
"friendly_name" : friendly_name,
"nextoccur" : str(event),
"years" : (event-origin).days//365,
"origin" : str(origin),
}
)
But i can’t believe that strptime() works and strftime(fmat) doesn’t inside that environment.
hass.states.set(sensorName , (event-today).days,
{
"icon" : "mdi:calendar-star" ,
"unit_of_measurement" : "days" ,
"person" : name,
"friendly_name" : friendly_name,
"nextoccur" : event.strftime(fmat),
"years" : (event-origin).days//365,
"origin" : origin.strftime(fmat),
}
)
EDIT, also just so you know, any date()
object (I.E. event
, origin
), you can get the day, month, year out of it with simply:
event.day
event.month
event.year
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
In the words of Her Royal Highness, there is no such thing as American English, there is English and there are mistakes
Anyway, duly noted, I’ll revise the script when I get a sec. Thanks mate
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
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
Worked good thanks.