Can I set an input_datetime to a time/day pulled from the text of a last_notification sensor?

I receive a text from my grocer when my curbside order is almost ready. It is an automated text that tells me the date and time for my pickup. For example. "Your order will be ready on 12/30 at 7:00 AM.

I have last_notification setup and working. My goal is to set setup an automation that runs a reminder of some kind (light flash, phone alert, whatever) when that time from the message rolls around.

Is there a way to set a datetime helper with the date and time pulled from the attribute of my last_notification sensor so that the execution of the automation can be set for a future time/date based on the specific time/date received in that text notification?

Thanks.

Yes there is a way.
But we need more details such as what the message looks like and what the attributes look like when that message arrives.

Edit sorry didn’t see the example.
But do you have the attributes of the last notification sensor?

The relevant attribute from the last_notification is ‘androit.text’; it contains the actual message with the date and time.

I appreciate the help.

It will be hard to get it correct without the proper details.
I suggest you create an automation that can write the sensor information, states and attributes to a text file.
When you get it working then just disable the automation and wait until the next order day and enable it then.

That will give us all the details because we don’t want this to trigger if you get a different message from someone else.

So, this is actually something I pulled when I first had the idea.

android.appInfo: ApplicationInfo{d2a63b0 com.samsung.android.messaging}
android.hiddenConversationTitle: 'null'
android.infoText: 'null'
android.isGroupConversation: false
android.largeIcon: Icon(typ=BITMAP size=92x92)
android.messages: '[Landroid.os.Parcelable;@ccdb223'
android.messagingStyleUser: Bundle[mParcelledData.dataSize=512]
android.messagingUser: android.app.Person@4ab67acf
android.people.list: '[android.app.Person@9b9a9ac4]'
android.progress: 0
android.progressIndeterminate: false
android.progressMax: 0
android.reduced.images: true
android.remoteInputHistory: 'null'
android.selfDisplayName: ⁨Me⁊
android.showChronometer: false
android.showWhen: true
android.subText: ''
android.template: android.app.Notification$MessagingStyle
android.text: Your order is set for 12/31 at 7:00-7:30am. Log in for more info.
android.title: ⁨Grocery Store⁊
android.wearable.EXTENSIONS: Bundle[mParcelledData.dataSize=692]
is_clearable: true
is_ongoing: false
package: com.samsung.android.messaging
post_time: 1640894123499
icon: mdi:bell-ring
friendly_name: Phone Last Notification
@ 2021-12-30T14:11:02.231072-06:00>)>'

If nobody else does it before me then I will have a look at it tomorrow.
But that is perfect!

1 Like

Again, I really appreciate it. The HA community is truly amazing. Not being a developer myself but still being able to utilize HA thanks to the support of people like you as well as just how far the interface and everything else has come over the last two years or so is astounding.

I believe this will work.

alias: New Automation
description: ''
mode: single
trigger:
  - platform: template
    value_template: >-
      {{ state_attr('sensor.last_notification', 'package') ==
      'com.samsung.android.messaging' and state_attr('sensor.last_notification',
      'android.title') == 'Grocery Store'  and
      state_attr('sensor.last_notification', 'android.text')[0:21] == 'Your
      order is set for' }}
condition: []
action:
  - service: input_datetime.set_datetime
    target:
      entity_id: input_datetime.YOUR_DATETIME
    data:
      datetime: "{{ now().year}}-{{ state_attr('sensor.last_notification', 'android.text') | regex_findall_index('(\d+\/\d+)') | replace('/', '-') }} {{ state_attr('sensor.last_notification', 'android.text') | regex_findall_index('at (\d+:\d+)') }}"

There is one big limitation, since there is no year mentioned in the sms I have to use what I believe and that is that it’s this year (current year, not 2021).
If you make an order that will be delivered the next year from when the sms arrives then this won’t work.
It’s possible to template that also in to the mix, but for now lets keep it simple and test if it works.

You need to replace the last notification entity and the datetime entitiy.
As you can see it triggers on sms package, from grocery store and the first 21 characters. This could possibly false trigger if the store sends more similar sms messages.

I think you actually can test this with the set states in the developer tools.
If you paste the attributes there and set the state then the automation should kick in, I think.

When I created this automation, I get the following error when I save:

Message malformed: extra keys not allowed @ data['device_id']

Looks like a formatting issue? But I’ll be damned if I can see what is malformed.

There is not even a device in the automation.
Your sure you didn’t accidentally do some other changes to the automation because that automation I posted saved fine on my instance with my entities.

Is the datetime both date and time or only time entity?

It’s a date and time named input_datetime.grocery_pickup.

Clearly I am doing something wrong though. I re-copied your automation, pasted into notepad and changed the entity_id to my datetime helper, and alias to a more fitting name, and now I get

Message malformed: Integration '' not found

I made a script so I could verify the action part was at least working:

service: input_datetime.set_datetime
target:
  entity_id: input_datetime.grocery_pickup
data:
  datetime: >-
    "{{ now().year}}-{{ state_attr('sensor.last_notification', 'android.text') |
    regex_findall_index('(\d+\/\d+)') | replace('/', '-') }} {{
    state_attr('sensor.last_notification', 'android.text') |
    regex_findall_index('at (\d+:\d+)') }}"

And I set the attribute of the sensor.phone_last_notification to ‘Your order is set for 12/31 7:00-7:30am.’

And running that script results in an error:

Failed to call service script/test_script. Error rendering data template: IndexError: list index out of range

Any ideas?

Mine’s a bit uglier than Hellis’s but here it is as a script:

alias: Set order ready
sequence:
  - service: input_datetime.set_datetime
    data:
      datetime: '{{ order_ready }}'
    target:
      entity_id: input_datetime.your_datetime
mode: single
variables:
  order_ready: >
    {% set text = state_attr('sensor.last_notification', 'android.text') %} {% set order_date = text|
    regex_findall(find='(0[1-9]|1[0-2])/(0[1-9]|[12][0-9]|3[01])',
    ignorecase=True) %} {% set order_time = text|
    regex_findall(find='([1-9]|1[0-2])\:(30)', ignorecase=True) %} {% set am_pm
    = text| regex_findall(find='(am|pm)', ignorecase=True) %} {% if am_pm ==
    "pm" %} {% set order_time = (order_time|int + 12) %} {% endif %} {% set
    order = ( now().year~"-"~order_date[0][0]~"-"~order_date[0][1]~"
    "~order_time[0][0]~":"~order_time[0][1]~":00") %} {{
    order|as_datetime|as_local }}

Since they included “am” in the time I took that to mean that it could also be “pm” and would need correcting from 12-hour to 24-hour format… if that’s not the case, we can get rid 3 lines.

1 Like

That is meant to be am and pm, so can’t remove those lines; but I am getting an error when I run the script:

Error rendering data template: IndexError: list index out of range

It works for me when I replace state_attr('sensor.last_notification', 'android.text') with "Your order is set for 12/31 at 7:00-7:30am. Log in for more info.".

Is that still the value of {{state_attr('sensor.last_notification', 'android.text')}} ? If the value has changed to something without a date and time, the template will fail.

Ok, so I am not sure why, but I recreated the script (for the third? time) and I did replace

{{state_attr('sensor.last_notification', 'android.text')}} with {{state_attr('sensor.phone_last_notification', 'android.text')}} since that is the full entity_id of the sensor in question. And now it works! (mostly)

It input the time as 7:30.

Is it possible to use the 7:00? I wouldn’t be late by 7:30, but the start time of the window would be preferable.

I really appreciate all you help (and everyone else’s).

I think this should work:

{% set text = state_attr('sensor.phone_last_notification', 'android.text') %}
{% set order_date = text| regex_findall(find='(0?[1-9]|1[0-2])/(0[1-9]|[12][0-9]|3[01])', ignorecase=True) %}
{% set order_time = text| regex_findall(find='(0?[0-9]|1[0-2]):([0-5][0-9])', ignorecase=True) %}
{% set am_pm = text| regex_findall(find='(am|pm)', ignorecase=True) %}
{% if am_pm == "pm" %}
{% set order_time = (order_time|int + 12) %}
{% endif %}
{% set order = ( now().year~"-"~order_date[0][0]~"-"~order_date[0][1]~" "~order_time[0][0]~":"~order_time[0][1]~":00") %}
{{ order|as_datetime|as_local }}
1 Like

That did it. Thank you all so much.

1 Like

I found a couple failure points… there are so many possible ways to write the date and time.

I think I have covered all(?) the bases…

{% set text = state_attr('sensor.phone_last_notification', 'android.text') %}
{% set order_date = text| regex_findall(find='(0?[1-9]|1[0-2])/(0?[1-9]|[1-2][0-9]|3[01])', ignorecase=True) %}
{% set order_time = text| regex_findall(find='(0?[1-9]|1[0-2]):([0-5][0-9])', ignorecase=True) %}
{% set am_pm = text| regex_findall(find='(am|pm)', ignorecase=True) %}
{% if am_pm|join() == 'pm'%}
  {% if (order_time[0][0])|int < 12 %}{% set order_hour = ((order_time[0][0])|int + 12) %} 
  {% else %}{% set order_hour = 12 %}{% endif %}
{% elif (order_time[0][0])|int >= 10 %}{% set order_hour = (order_time[0][0])%}
{% else %}{% set order_hour = "0"~(order_time[0][0])%}
{% endif %}
{% set order = ( now().year~"-"~order_date[0][0]~"-"~order_date[0][1]~" "~order_hour~":"~order_time[0][1]~":00") %}
{{ order|as_datetime|as_local }}

Only failure point left is the December order to January delivery.

That could probably be solved with

{% if order_date[0][0] == 1 and now().month == 12%}
{% set year = now().year +1 %}
{%else%}
{% set year = now().year %}
{% endif %}

But I don’t think it’s necessary with different ways to write time and date since it’s most likely an automated system.