Pt 2. Using Home Assistant to Cure My Migraines

Home Assistant Logo

If you regularly experience any of the symptoms I list in this article, it is entirely possible that like me your migraines may be triggered by something in your diet! This is not medical advice, I am not a Medical Professional, do not take medical advice from internet strangers. If you are suffering from similar symptoms, consider approaching a medical professional before biohacking your life. This was my journey, I hope it brings relief to others.

Introduction Link to heading

I used to suffer from migraines, amongst multiple less severe but nonetheless annoying symptoms.

Practically every single day, for the last 15 years, I’ve woken up with a migraine and gone to bed with one. It started 15 years ago at a friend’s wedding. The evening before we’re sharing a beer (Budweiser) chatting about the upcoming wedding, we go to bed, then at 3am in the morning I’m woken by the worst headache I’ve ever experienced. Cue 15 years of near daily migraines, not as devastating as the first migraine, but debilitating none the less.

Then I started to track my diet and symptoms with the help of Home Assistant. The goal? Identifying if something in my diet was the trigger for my migraines (And other symptoms).

Read more about my journey here

It started with a click Link to heading

Once I started collecting detailed diet and symptom information, I realised that having access to a very detailed food diary actually made it pretty simple to see the problem foods directly in the data, without going to the lengths of building a machine learning model or crafting a creative visualisation.

It is still my intention to implement the visualisation / machine learning predictive model and share it with the community in the hope that it may help someone else and if you are interested keep your eyes out for my next post on this subject.

Update - Visualisation http://rodders.me/health_data_tracker_visualisation/vertical_food_timeline.html

Building a data driven health tracker Link to heading

Over the past seven months that I’ve been using Home Assistant to log the data:

  • Date
  • Time
  • Categories (Food, Symptom etc.)
  • Additional Information (Detailed food info etc.)

I’ve collected over 12,000 rows of data which is more than enough to use as a dataset for a predictive model and expect some reasonable results. What also helps is now knowing my what my triggers are, I’ll be able to compare it to the output from the ML Model. About 80% of this data was readings from a CMG, which were later discounted as irrelevant (this was one of ChatGPTs suggestions that proved pointless)

Over-engineering a simple data collection problem? Link to heading

I already knew a paper method of recording would not work for me, I’ve tried it before and while I’m a big fan of analog, but as a recording methodology for data analysis goes, it’s a bit shit.

So I flexed my considerable experience with Home Assistant to develop a Home Assistant dashboard page specific to tracking food / fluid consumption, health indicators and symptoms.

Here’s where Home Assistant comes in, one thing that is a constant is my mobile phone which is rarely out of my hands, couple this with the Home Assistant app Android or IOS, a Nabu Casa subscription and that combination enabled me to update my food and symptom tracker regardless of where I was, at home or out with friends.

I had a method of simply (and quickly) keeping a detailed diary of food and symptoms using a simple button click interface that simplified maintaining a food / symptoms Diary etc. which in turn enabled me to begin collecting the detailed data necessary to attempt to identify the causes of my migraines and fix them.

Initially I also used a Continuous Glucose Monitor (Libre Freestyle integration FTW!) to monitor blood glucose after eating (ChatGPT suggestion), and it was simple to integrate this into the overall solution I built. However as more data was collected, it became apparent that this was not a factor causing my migraines.

NABU Casa subscription not required (but very worthwhile and helpful) Link to heading

A Nabu Casa Subscription enables remote access to your Home Assistant instance, using the Home Assistant app Android or IOS, outside of your home Wi-fi network, which means when you are not home you can access your Home Assistant server from anywhere.

Please note that a Nabu Casa subscription is not required for my solution (but come on, support the Devs!) if:

  • You have already setup your own remote access solution
  • You intend on setting up your own remote access solution
  • You not require remote access to your Home Assistant Instance.

You won’t need it.

However a subscription supports the developers and simplifies a lot of the more complex elements of setting up Home Assistant remote access and integrating with Alexa and Google voice control.

Support the Devs!

A Look at the Home Assistant Dashboard Link to heading

Here’s what the dashboard looks like.

The following details the methods I used to create the dashboard and begin collecting data.

Home Assistant Health Dashboard

Here’s how The Home Assistant Dashboard was made Link to heading

The overall solution is built around a number of Home Assistant components:

The Datafile Link to heading

To record the data into a CSV Data File that can be analysed with tools like python, pandas and Machine Learning models, a file notification integration needs to be setup in Home Assistant.

Settings -> Add Integration -> File -> Setup a notification service.

Setup File Notification

  • Give it a memorable name, this is used in the script to write the data associated with a button being clicked.
  • Make sure you leave Timestamp OFF, date and time is added by the Home Assistant scripts.

The Lovelace Dashboard Food Button Link to heading

food button

These are Buttons in a horizontal stack.

A Button needs to be created for each commonly used food. When the button is clicked the information under the data heading is written to the Home Assistant file sensor.

The key elements for data acquisition are under the data: heading :

  • carbs
  • fluids
  • category
  • item

Hopefully it’s obvious that you amend these for each food you wish to create a button for.

 1show_name: true
 2show_icon: true
 3type: entity-button
 4tap_action:
 5  action: perform-action
 6  data:
 7    category: FOOD
 8    item: Choccie Coffee (18g CHO & 3 tsp & 400ml fluids)
 9    carbs: 18
10    liquids: 400
11  target: {}
12  perform_action: script.health_log_button
13entity: script.health_log_button
14icon: mdi:coffee
15hold_action:
16  action: none
17name: Choccie Coffee (18g CHO)
18icon_height: 20px

Example of another category for the Dashboard Button Link to heading

The same script can be used to log other non food items by simply changing the category to whatever you want. In my case I started out recording secondary symptoms:

 1show_name: true
 2show_icon: true
 3type: entity-button
 4name: Feeling Cold
 5tap_action:
 6  action: perform-action
 7  data:
 8    category: SYMPTOM
 9    item: Feeling Cold
10  target: {}
11  perform_action: script.health_log_button
12entity: script.health_log_button
13icon_height: 20px
14icon: mdi:snowflake-alert

The Button Logging script Link to heading

This script is called each time a relevant button is clicked. It stores the data in a consistent CSV format for later analysis.

The notify.file where file is the name of the file sensor created earlier.

 1health_log_button:
 2  alias: "Health - Log Button"
 3
 4  sequence:
 5    - choose:
 6        - conditions:
 7            - condition: template
 8              value_template: "{{ carbs is defined and carbs | int != 0 }}"
 9          sequence:
10            - action: notify.send_message
11              enabled: true
12              target:
13                entity_id: notify.file
14              data:
15                message: > 
16                "{{ now().strftime('%Y-%m-%d')}},
17                 {{ now().strftime('%H:%M')}},
18                 {{category}},{{item}},{{carbs}}"
19            - action: input_number.set_value
20              target:
21                entity_id: input_number.food_carbs_consumed_event
22              data:
23                value: "{{carbs}}"
24            - action: python_script.set_state
25              data:
26                entity_id: sensor.food_carbs_day_total
27                state: "{{ states('sensor.food_carbs_day_total') | float(0) + states('input_number.food_carbs_consumed_event') | float(0) }}"
28            - condition: template
29              value_template: "{{ liquids is defined and liquids | int != 0 }}"
30            - action: notify.send_message
31              target:
32                entity_id: notify.file
33              data:
34                message: >
35                "{{ now().strftime('%Y-%m-%d')}}, 
36                 {{ now().strftime('%H:%M')}},
37                  DRINK,{{item}},{{liquids}}"                
38            - action: python_script.set_state
39              data:
40                entity_id: sensor.food_liquids_day_total
41                state: "{{ states('sensor.food_liquids_day_total') | float(0) + liquids | float(0) }}"
42
43
44      default:
45        sequence:
46          - action: notify.send_message
47            enabled: true
48            target:
49              entity_id: notify.file
50            data:
51              message: >
52              "{{ now().strftime('%Y-%m-%d')}},
53               {{ now().strftime('%H:%M')}},
54                {{category}},{{item}},0"              

Essentially this script runs through THEN conditions to determine what to write to the file.

IwcIwcIIwcfrofroffroininincttfttfcttaealealaeariuiuribtnitnibtnshedhedsheedsedsediisciifiiscianslnsandruntebtditnoetfshedhotghieTfseTtoenaHiHdrencEnacEdeycddaNenaNefarddrfiaraiddinndntaineddetnttedtmodeodionmatodtntanettehodhndmhteteedezatndeifzafnoefrlieiiottiolrlltal,eoezie,zelsserseeroennonsssooAorrNr..D.

What is written to to the file sensor Link to heading

This will write an entry in the file you have setup that looks like this:

2025-04-20,10:30,‘FOOD’,‘Coffee (15g CHO & 1 tsp Sugar & 400ml Fluids)’,‘15’

2025-04-20,10:30,‘DRINK’,‘Coffee (15g CHO & 1 tsp Sugar & 400ml Fluids)’,‘400’

And the data split :

DateTimeCategoryFood InfoCarbs / Fluids
2025-04-2010:30‘FOOD’‘Coffee (15g CHO & 1 tsp Sugar & 400ml)’‘15’
2025-04-2010:30‘DRINK’‘Coffee (15g CHO & 1 tsp Sugar & 400ml)’‘400’

Symptom Severity Logging Link to heading

The Symptom Severity section consists of five main elements :

  • input_number Helper required for the dashboard card to store the set value
  • A Dashboard card to allow the values to be set
  • A script to store severity values from the input_number helper to the datafile
  • An optional graph plotting historic data store in the input_number helper

Severity Logging

Symptom Severity Logging - The input_number helper Link to heading

The input_number Helper needs to be created in Home Assistant to allow this value to be set in the dashboard.

Settings -> Devices & Services -> Helpers -> + Create Helper -> Number

Give your helper a name, and under advanced select whether you want to use a slider or input field (either works with the script).

The Lovelace Dashboard Symptom Severity Logging Input and Button code Link to heading

 1type: horizontal-stack
 2cards:
 3  - features:
 4      - type: numeric-input
 5        style: buttons
 6    type: tile
 7    entity: input_number.health_headache_severity
 8    vertical: false
 9    name: Headache Severity
10    features_position: bottom
11  - show_name: true
12    show_icon: true
13    type: button
14    tap_action:
15      action: perform-action
16      target: {}
17      perform_action: script.health_headache_severity
18    entity: input_number.health_headache_severity
19    name: Update Headache
20    icon: mdi:head-alert-outline
21    icon_height: 20px
22view_layout:
23  position: sidebar

input_helper

I’m using the Apex Charts addon for plots, it has a lot more flexibility than the normal Home Assistant graph card.

Symptom Severity Logging - The script. Link to heading

This script adds the data from the input_number helper and stores the data in the datafile in the correct CSV format.

 1"health_headache_severity":
 2  alias: Health - Headache Severity
 3  sequence:
 4    - action: notify.send_message
 5      target:
 6        entity_id: notify.file
 7      data:
 8        message: >
 9                "{{ now().strftime('%Y-%m-%d')}},
10                 {{ now().strftime('%H:%M')}},
11                 'HEADACHE','Severity',
12                 '{{ states('input_number.health_headache_severity') }}'"                

Recording Sleep Information Link to heading

(Recording multiple data items with a single button click)

If you have a smart watch with an integration for Home Assistant, this could be automatic. My Galaxy smartwatch doesn’t have an integration, so I logged sleep data manually.

The Dashboard button and input fields Link to heading

input_number Helpers need to be created for each item you wish to record. For my example I was recording the sleep data from my smartwatch because there was no Home Assistant integration for it:

  • Restless Sleep
  • Light Sleep
  • Motionless Sleep

sleep_record

Using the script below, the data from the input_number Helpers helpers will be written to the file sensor.

The Lovelace Dashboard Card Link to heading

 1type: entities
 2entities:
 3  - entity: input_number.health_sleep_restless
 4    name: Restless (minutes)
 5  - entity: input_number.health_sleep_light
 6    name: Light (minutes)
 7  - entity: input_number.health_sleep_motionless
 8    name: Motionless (Minutes)
 9  - entity: script.health_sleep_record
10    icon: mdi:sleep
11    secondary_info: last-changed
12    name: Save Record

The script for sleep data capture Link to heading

 1"health_sleep_record":
 2  alias: Health - Sleep Record
 3  sequence:
 4    
 5    - action: notify.send_message
 6      target:
 7        entity_id: notify.file
 8      data:
 9        message: >
10                "{{ now().strftime('%Y-%m-%d')}},
11                 {{ now().strftime('%H:%M')}},
12                 'SLEEP','RESTLESS', 
13                 '{{ states('input_number.health_sleep_restless') }}'"                
14
15    - action: notify.send_message
16      target:
17        entity_id: notify.file
18      data:
19        message: >
20                "{{ now().strftime('%Y-%m-%d')}},
21                 {{ now().strftime('%H:%M')}},
22                 'SLEEP','LIGHT', 
23                 '{{ states('input_number.health_sleep_light') }}'"                
24
25    - action: notify.send_message
26      target:
27        entity_id: notify.file
28      data:
29        message: > 
30                "{{ now().strftime('%Y-%m-%d')}},
31                 {{ now().strftime('%H:%M')}},
32                 'SLEEP','MOTIONLESS', 
33                 '{{ states('input_number.health_sleep_motionless') }}'"

And that’s it! 12,000 button clicks later and I’m cured !

If you want to find out more about my journey to cure my migraines, read on!

Read more about my journey here