Medication Management with HA and NFC Tags

I have developed a medication management system using Home Assistant, which utilizes NFC tags (but still works with the GUI). This system has been incredibly helpful for me in keeping track of my medications and reminding me when necessary. Here are some of its benefits:

  • Easy medication tracking: I simply scan the NFC tag associated with each medication or supplement using a mix of cards, stickers, and coins, depending on the packaging.
  • Mobile reminders: It sends reminders to my phone via the companion app, and the reminders are cleared as soon as I confirm that I have taken the medication.
  • History log: The system maintains a history of all the medications I have taken, providing me with a record of my medication usage.
  • Retroactive entry: I can also add medications I have taken in the past using the user interface (UI).
  • Custom medication support: The system allows me to add custom medications that are not pre-configured using an input_text.
  • CSV file generation: The system automatically creates a CSV file that can be used for further processing or analysis.

Although this system was initially created for my personal use, it has proven to be incredibly helpful. While it is not perfect and may not meet everyone’s needs, I wanted to share it with others who might find it beneficial.

It’s important to note that not all features are necessary for everyone. Therefore, I will explain the system step by step:


Automations: Currently, there are two methods I use for automation.

  • Method 1: This method requires more effort, but it allows me to create easy buttons for the Lovelace interface and set up individual reminders for each medication. However, it requires a new automation for each medication.

  • Method 2: This method is used for my supplements and is implemented in a cleaner way. However, it does not support the creation of buttons in the UI (as it works with trigger_ids, which are not compatible with UI buttons). Implementing reminders with this method would require some additional work. Instead, I use a dropdown list in the UI for supplement tracking.


Method 1 - Automation for each medication:

Here are the steps to follow when adding a new medication:

  • Use the companion app to add an NFC tag for the medication.
  • Create a new copy of the automation and modify it according to the specific medication:
  • Replace the trigger with the NFC tag that was just created.
  • Replace the placeholder “NAME” with the actual name of the medication three times in the automation.
  • Add a button to the Lovelace interface for easy access to the medication.

Automation:

alias: Tool NFC Tag Medi NAME
description: ""
trigger:
  - platform: tag
    tag_id: ec902a2b-9b88-498d-b1a2-06e560abb392
    enabled: true
condition: []
action:
#WRITING .csv FILE
  - service: notify.file_medis
    data:
      message: >-
        {{ '{:.6f}'.format((now().timestamp() -
        (states("input_number.tool_medi_adjust_hours") | float) * 3600)) }};{{
        (now().timestamp() - (states("input_number.tool_medi_adjust_hours") |
        float) * 3600) | timestamp_custom('%Y.%m.%d;%H:%M', 1, default=1)
        }};Medi;NAME;
#RESET TIME WHEN USING ADDING MEDS FROM THE PAST
  - service: input_number.set_value
    data:
      value: 0
    target:
      entity_id: input_number.tool_medi_adjust_hours
# WRITE TO HISTORY HELPER
  - service: input_text.set_value
    data:
      value: ''
    target:
      entity_id: input_text.tool_med_history   
  - service: input_text.set_value
    data:
      value: "Medi: NAME"
    target:
      entity_id: input_text.tool_med_history
mode: single

This system requires the following helper entities to be set up:

  • TEXT - Name: Tool Medi History - entity_id: input_text.tool_med_history
  • NUMBER - Name: Tool Medi Adjust Hours - entity_id: input_number.tool_medi_adjust_hours - max_value: 96 - display mode: slider

Method 2 - Single automation for all supplements:

Here are the steps to follow when adding a new supplement:

  • Use the companion app to add an NFC tag for the supplement.
  • Add the supplement to the dropdown list. The easiest way to do this is by clicking on the icon of the dropdown list and accessing its settings.
  • If you’re using NFC for the supplement (I don’t use it for ones I take rarely), add a new trigger to the automation and set the trigger_id with its NAME.

Automation:

alias: Tool NFC Supl General [ALL]
description: ""
trigger:
# TRIGGER FOR THE UI
  - platform: state
    entity_id:
      - input_button.tool_supl_run_automation
    id: button
#NFC TRIGGERS
  - platform: tag
    tag_id: 1d3345bf-b4d7-49e7-b4a4
    id: NAME1
  - platform: tag
    tag_id: asdfasdf-b4d7-49e7-b4a5
    id: NAME2
  - platform: tag
    tag_id: fgdhdfghfdg-b4d7-49e7-b4a6
    id: NAME3
  - platform: tag
    tag_id: ghjkghjkghj-b4d7-49e7-b4a7
    id: NAME4
condition: []
action:
#WRITING .csv FILE
  - service: notify.file_medis
    data:
      message: >-
        {{ '{:.6f}'.format((now().timestamp() -
        (states("input_number.tool_medi_adjust_hours") | float) * 3600)) }};{{
        (now().timestamp() - (states("input_number.tool_medi_adjust_hours") |
        float) * 3600) | timestamp_custom('%Y.%m.%d;%H:%M', 1, default=1)
        }};Supl;{{ trigger.id if (trigger.id != "button") else
        states("input_select.tool_nfc_supl_list") }};
#RESET TIME WHEN USING ADDING MEDS FROM THE PAST
  - service: input_number.set_value
    data:
      value: 0
    target:
      entity_id: input_number.tool_medi_adjust_hours
# WRITE TO HISTORY HELPER
  - service: input_text.set_value
    data:
      value: ''
    target:
      entity_id: input_text.tool_med_history   
  - service: input_text.set_value
    data:
      value: >-
        Supl: {{ trigger.id if (trigger.id != "button") else
        states("input_select.tool_nfc_supl_list") }}
    target:
      entity_id: input_text.tool_med_history
mode: single

This system requires the following helper entities to be set up:

  • DROPDOWN - Name: Tool NFC Supl List - entity_id: input_select.tool_nfc_supl_list - Options: [add items to your list]
  • BUTTON - name: Tool Supl Button Run Automation - entity_id: input_button.tool_supl_run_automation - icon: mdi:pill

already used in method 1:

  • TEXT - Name: Tool Med History - entity_id: input_text.tool_med_history
  • NUMBER - Name: Tool Medi Adjust Hours - entity_id: input_number.tool_medi_adjust_hours - max_value: 96 - display mode: slider

The .csv file (for both methods):

This needs a entry in configuration.yaml (not possible via UI)

notify:
  - name: file_medis
    platform: file
    filename: /config/medication_history.csv

Lovelace:


For method 1: Buttons. Replace NAMEx
Screenshot 2023-05-19 233118

show_name: true
show_icon: true
show_state: false
type: glance
entities:
  - entity: automation.tool_nfc_tag_medi_NAME1
    tap_action:
      action: call-service
      service: automation.trigger
      target:
        entity_id: automation.tool_nfc_tag_medi_NAME1
      data:
        skip_condition: true
    icon: mdi:pill
    name: NAME1
  - entity: automation.tool_nfc_tag_medi_NAME2
    tap_action:
      action: call-service
      service: automation.trigger
      target:
        entity_id: automation.tool_nfc_tag_medi_NAME2
      data:
        skip_condition: true
    icon: mdi:pill
    name: NAME2

For method 2: dropdown list
For method 1 and 2: adjust time
For optional features: notes and custom meds
Screenshot 2023-05-19 224455

type: entities
entities:
  - entity: input_number.tool_medi_adjust_hours
  - entity: input_text.tool_medi_note_create
  - entity: input_text.tool_medi_add_custom_medi
  - entity: input_select.tool_nfc_supl_list
  - entity: input_button.tool_supl_run_automation
    name: Save supplement

History (needs custom card “home-feed-card”, add it via HACS):
Screenshot 2023-05-19 225943

entities:
  - entity: input_text.tool_med_history
    exclude_states:
      - ''
      - unknown
      - unavailable
    remove_repeats: false
    include_history: true
    max_history: 12
    name: ''
    content_template: '{{state}}'
  - entity: input_text.tool_medi_note_create
    exclude_states:
      - ''
      - unknown
      - unavailable
      - saved
    remove_repeats: false
    include_history: true
    max_history: 12
    name: ''
    content_template: '{{state}}'
more_info_on_tap: false
max_item_count: 12
history_days_back: 12
compact_mode: true
exact_durations: true
show_notification_title: false
type: custom:home-feed-card
show_icons: false
card_id: medhistory

Optional additional features:


Simple reminder sent to the phone companion app:

The system is set up to send reminders for medications twice a day (indicated by the “/ 2” below), and it sends additional notifications every 2 hours 2 more times. Once the NFC tag is scanned, the notification is automatically cleared on the phone.

Please feel free to adjust this setup according to your specific needs. You can create copies of the reminder for different medications or just “add them together”.

  1. Automation (sends the notification):
alias: Tool Med Reminder
description: ""
trigger:
  - platform: time
    at: "8:00:00"
  - platform: time
    at: "10:00:00"
  - platform: time
    at: "12:00:00"
  - platform: time
    at: "18:00:00"
  - platform: time
    at: "20:00:00"
  - platform: time
    at: "22:00:00"
condition:
  - condition: or
    conditions:
      - condition: and
        conditions:
          - condition: numeric_state
            entity_id: input_number.tool_medi_counter_per_day_for_reminder
            below: input_number.tool_medi_number_to_reach_for_reminder
            above: 0
          - condition: time
            after: "20:00:00"
      - >-
        {{ (states("input_number.tool_medi_counter_per_day_for_reminder")|int) <
        ((states("input_number.tool_medi_number_to_reach_for_reminder")|int) / 2) }}
action:
  - service: notify.mobile_app_phone_main
    data:
      message: Med Reminder
      title: Med Reminder
      data:
        tag: medreminder
        timeout: 7200
        channel: medreminder
mode: single
  1. And reset it daily:
alias: Tool Reset MediReminder at 4
description: Helper automation to reset Reminder for taking Meds Daily at 4
trigger:
  - platform: time
    at: "04:00:00"
condition: []
action:
  - service: input_number.set_value
    data:
      value: 0
    target:
      entity_id: input_number.tool_medi_counter_per_day_for_reminder
mode: single
  1. Add this to the automation from method 1 you’re setting up (increase the helper after med is taken, and clear the notification on the phone):
  - service: notify.mobile_app_phone_main
    data:
      data:
        tag: medreminder
        channel: medreminder
      message: clear_notification
  - service: input_number.increment
    data: {}
    target:
      entity_id: input_number.tool_medi_counter_per_day_for_reminder

This needs the following helpers:

  • NUMBER - name: Tool Medi Counter_per_Day for Reminder - entity_id: input_number.tool_medi_counter_per_day_for_reminder
  • NUMBER - name: Tool Medi Number_to_Reach for Reminder - entity_id: input_number.tool_medi_number_to_reach_for_reminder

Lovelace:
Screenshot 2023-05-19 224419

type: entities
entities:
  - entity: input_number.tool_medi_counter_per_day_for_reminder
    name: Counter
    secondary_info: last-changed
  - entity: input_number.tool_medi_number_to_reach_for_reminder
    name: Target
    secondary_info: last-changed
title: 'Reminder Med 1: NAME1'

Add custom (not listed) medications:


Screenshot 2023-05-19 224455b

Automation:

alias: Tool Medi Add Custom Medi
description: ""
trigger:
  - platform: state
    entity_id:
      - input_text.tool_medi_add_custom_medi
condition: []
action:
  - service: notify.file_medis
    data:
      message: >-
        {{ '{:.6f}'.format(now().timestamp() -
        (states("input_number.tool_medi_adjust_hours") | float) * 3600) }};{{
        (now().timestamp() - (states("input_number.tool_medi_adjust_hours") |
        float) * 3600) | timestamp_custom('%Y.%m.%d;%H:%M', 1, default=1)
        }};Medi;Custom:{{ (states('input_text.tool_medi_add_custom_medi') |
        replace(";", "/",1)) }};
  - service: input_text.set_value
    data:
      value: >-
        Medi-Custom: {{ (states('input_text.tool_medi_add_custom_medi') |
        replace(";", "/",1)) }}
    target:
      entity_id: input_text.tool_med_history
  - service: input_text.set_value
    data:
      value: added
    target:
      entity_id:
        - input_text.tool_medi_add_custom_medi
  - delay:
      hours: 0
      minutes: 0
      seconds: 5
      milliseconds: 0
  - service: input_text.set_value
    data:
      value: ""
    target:
      entity_id:
        - input_text.tool_medi_add_custom_medi
  - service: input_number.set_value
    data:
      value: 0
    target:
      entity_id: input_number.tool_medi_adjust_hours
mode: single
max_exceeded: silent

This system requires the following helper entities to be set up:

  • TEXT - Name: Tool Medi Add Custom Medi - entity_id: input_text.tool_medi_add_custom_medi

Add custom notes (similar to the custom medication):


Screenshot 2023-05-19 224455a

Automation:

alias: Tool Medi Add Note
description: ""
trigger:
  - platform: state
    entity_id:
      - input_text.tool_medi_note_create
condition: []
action:
  - service: notify.file_medis
    data:
      message: >-
        {{ "{:.6f}".format((now().timestamp() -
        (states("input_number.tool_medi_adjust_hours") | float) * 3600)) }};{{
        ((now().timestamp() - (states("input_number.tool_medi_adjust_hours") |
        float) * 3600) | timestamp_custom("%Y.%m.%d;%H:%M", 1, default=1))
        }};Note;{{ (states('input_text.tool_medi_note_create') | replace(";",
        "/",1)) }}
  - service: input_text.set_value
    data:
      value: saved
    target:
      entity_id: input_text.tool_medi_note_create
  - delay:
      hours: 0
      minutes: 0
      seconds: 5
      milliseconds: 0
  - service: input_text.set_value
    data:
      value: ""
    target:
      entity_id: input_text.tool_medi_note_create
  - service: input_number.set_value
    data:
      value: 0
    target:
      entity_id: input_number.tool_medi_adjust_hours
mode: single
max_exceeded: silent

This system requires the following helper entities to be set up:

  • TEXT - name: Tool_Medi_Note_Create - entity_id: input_text.tool_medi_note_create

Backup the .csv file twice a week:


Automation:

alias: Tool Medi Backup File
description: ""
trigger:
  - platform: time
    at: "05:00:00"
condition:
  - condition: time
    weekday:
      - sun
      - wed
action:
  - service: shell_command.backup_med_list_csv
    data: {}
mode: single

configuration.yaml:

shell_command:
  backup_med_list_csv: "cp /config/medication_history.csv /config/medication_history.backup.{{ now().timestamp() | timestamp_custom('%Y%m%d', 1, default=1)  }}.csv"

I hope this helps someone. Improvements are welcome! :slight_smile:

8 Likes

Hey @dedi,
You and I seem to be on the same scope with HA and NFC’s. I started this 2 years ago.I use round nfc’s on pill bottles from pharmacy or vitamins and switch out tops when it is refilled. I think you have went farther down the rabbit hole than I did, lol.
I was hoping you could help out and maybe I don’t see or understand what you have developed.
My Rev2 for NFC pills was to add actionable reminder IF the nfc is not fired by a certain time. A reminder to snooze for 30 min to 2 hours. BUT actionable will only cancel when nfc tag is scanned. I’ve been scratching my head on how to put together.

It seems we are on the same page really, I hope you can help me with a few things
Cheers n thanks
JZ

1 Like

Hey @jimmyz51501
Sorry I only saw your post now, have to check if email notifications work.

If I understand you correctly (maybe I have to re-read it tomorrow, my brain fog…), all that you need is a helper (e.g. numerical, if you only have to take it once binary works too).
If you scan the NFC, increase number helper entity (either by one, or by the dosage). I also send a clear_notification to my phone in this automation, so the reminder is automatically dismissed.
In the reminder automation, I use fix times (multiple time triggers) and check if for the given time (between X and X) the dosage is already met. If it’s met, do nothing, if not, send reminder. (I actually have 2 helper, one is “dosage taget” and because I take it twice a day, it has to meet “dosage target / 2” - but that’s because I had to ramp up my doseage slowly)
In the middle of my sleep time, I reset the number helper back to 0.

This should all be in the Reminder Section above.
Sorry for my bad wording, hope you understand it. Otherwise I will reword it tomorrow :slight_smile:

Hey @dedi
Thanks for reply.
It’s been two months and now I have to remember what my thoughts were. :laughing:
I’ll have to revisit it again.
I think what you are referencing is what I need but not sure any more LOL. I have to sit down and look at it again.
You’re saying that automation 1 will give a snooze option? Your platform time of 8, 10, 12 etc… is just checking if was taken but not sending actionable?
Thanks for you getting back and will reach out once I wrap my brain about what I wanted. I feel ur fog LOL

It like a fixed snooze until you took the medication. You maybe want to make every 30min. Otherwise it will send a notification (not actionable above).

But I just updated mine to an actionable, in case I forgot or take it while I’m outside.

My notification looks like this, the “actions:” part in the “send notification”-automation

action:
  - service: notify.mobile_app_phone_main
    data:
        actions:
          - action: took_medication
            title: Took it
      message: Med Reminder
      title: Med Reminder
      data:
        tag: medreminder
        timeout: 7200
        channel: medreminder

And add the response-trigger to the Method 1 automation


trigger:
  - platform: tag
    tag_id: 04b8c487-4b99-4bdb-8d55-a921d59a047a
  - event_data:
      action: took_medication
    event_type:
      - mobile_app_notification_action
    platform: event

ok I’m starting to see.
Question? is [quote=“dedi, post:1, topic:573301”]
input_number.tool_medi_counter_per_day_for_reminder
[/quote]

Is that a catch all for all of ur meds? or for one med?

That is for one med. You need a separate helper for each med you want reminders for. But if you take several together, you may not need a separate one for each.

Ok I thought so, just checking thanks… had to scratch my head if it was for all… lol

This is how I’m automating my NFC’s

#Automations
 - alias: NFC_xxx
    description: 'Daily'
    trigger:
    - platform: tag
      tag_id: f641a9ba-16d6-41ce-b099-92ba16d98324
    action:
    - service: input_boolean.turn_on
      data:
        entity_id: input_boolean.xxx_taken
# Resets ##
  - alias: Reset xxx
    trigger:
    - platform: time
      at: "00:00:01"
    action: 
    - service: input_boolean.turn_off
      data:
        entity_id: input_boolean.xxx_taken

So I need to create a corresponding input_number.xxx (for each med)

OR will input_boolean.xxx_taken work?

Then replace/insert into your Auto1. Adjust trigger: platform time to my needs.

Am I missing stuff? :laughing:

If you only need to take meds once a day, this will work. If you take them more often, you need input_number.

As of right now in life… only once a day!! :rofl: :rofl:
I appreciate your help. I’ll work on it this weekend
Thanks again, hope you get to better health.

Have you thought of trying to put this in a blueprint for HA users? or HACS maybe. You did some good work here.

I don’t know if this is too individual for a blueprint. Something for HACS probably exceeds my level of knowledge and concentration I got left :joy:

1 Like