Custom Componenet: Oura Ring sleep data sensor

The code was updated over the past weeks having a few fixes, including the creation of the data folder when it doesn’t exist. I would recommend you to update the code.

PS: I no longer access the Community very much, so, best place to report issues is GitHub.

1 Like

Thank you for the custom component
I did use the updated code at the beginning however it did not create the data folder for me.
So I created it manually and now it works

Hello Nito, thank you for your oura integration. I’ve recently added it to my home assistant configuration and have somehow managed to have an issue that it looks like should be fixed!

My home assistant errror log reads: FileNotFoundError: [Errno 2] No such file or directory: ‘/config/data/oura-token-cache-sleep_quality.conf’

I’m using the latest files in your repo and believe I have the config set up correctly.

I was able to resolve this finally by manually adding the /data folder under /config

1 Like

Anyone have a good card for this information?

1 Like

I use graphs (custom:mini-graph-card)

              - type: "custom:mini-graph-card"
                entities:
                  - entity: sensor.total_sleep_yesterday
                    name: Sleep
                    show_state: true
                    show_indicator: true
                    color: "#9AA0A6"
                unit: h
                decimals: 2
                hours_to_show: 336 # 14 * 24
                points_per_hour: 0.0416666666666666666666666666666666666666666 # 1 / 24
                update_interval: 43200 # 12 * 60 * 60
                more_info: false
                align_icon: left
                align_header: left
                align_state: center
                show:
                  graph: bar

Screenshot 2021-12-06 at 19.14.16

And tables (custom:flex-table-card)

 - type: custom:flex-table-card
        title: Weekly Sleep
        entities:
          include: sensor.sleep_quality
        columns:
          - name: Day
            modify: >-
              ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'].join('<br />')
            prop: attributes
          - name: Bedtime
            align: right
            modify: >-
              [
                x.monday.bedtime_start_hour,
                x.tuesday.bedtime_start_hour,
                x.wednesday.bedtime_start_hour,
                x.thursday.bedtime_start_hour,
                x.friday.bedtime_start_hour,
                x.saturday.bedtime_start_hour,
                x.sunday.bedtime_start_hour,
              ].join('<br />')
            prop: attributes
          - name: Wake Up
            align: right
            modify: >-
              [
                x.monday.bedtime_end_hour,
                x.tuesday.bedtime_end_hour,
                x.wednesday.bedtime_end_hour,
                x.thursday.bedtime_end_hour,
                x.friday.bedtime_end_hour,
                x.saturday.bedtime_end_hour,
                x.sunday.bedtime_end_hour,
              ].join('<br />')
            prop: attributes
          - name: Sleep
            align: right
            modify: >-
              [
                x.monday.total_sleep_duration,
                x.tuesday.total_sleep_duration,
                x.wednesday.total_sleep_duration,
                x.thursday.total_sleep_duration,
                x.friday.total_sleep_duration,
                x.saturday.total_sleep_duration,
                x.sunday.total_sleep_duration,
              ]
              .map(x => Number(x).toFixed(2) + ' h')
              .join('<br />')
            prop: attributes
          - name: Awake
            align: right
            modify: >
              [
                x.monday.awake_duration,
                x.tuesday.awake_duration,
                x.wednesday.awake_duration,
                x.thursday.awake_duration,
                x.friday.awake_duration,
                x.saturday.awake_duration,
                x.sunday.awake_duration,
              ]
              .map(x => Number(x).toFixed(2) + ' h')
              .join('<br />')
            prop: attributes

If it’s useful, I can add this to the component description.

Nonetheless, if there’s a good custom card, I would love to see it!

2 Likes

Hi @nitobuendia

I was able to get this up and running. THANKS.

I updated the 2021.12.04 today and noticed that the days are not correlating with the app days. For instance, todays (12/21/2021) data is in the Sun row. It seems like the data in each of the values in the sunday. are the tuesday. numbers. Everything is shifted by 2 days. Are you seeing this?

Best way to report bugs is on GitHub, but I have not seen such a thing at the moment. There’s a backfill logic, though, but it should map the same days.

I used the custom apexchart card … I couldn’t get the columns to work as I wanted, but for now, good enough for me.

image

type: custom:apexcharts-card
graph_span: 5d
stacked: true
apex_config:
  chart:
    height: 250px
  grid:
    show: true
    borderColor: rgba(255,255,255,0.1)
  legend:
    show: true
    itemMargin:
      vertical: 10
      horizontal: 10
header:
  title: Sleep
  show: true
  show_states: true
  colorize_states: true
  standard_format: true
all_series_config:
  stroke_width: 3
yaxis:
  - id: hours
    opposite: true
    apex_config:
      tickAmount: 8
    min: 0
    max: ~10
  - id: total
    show: false
    opposite: true
    apex_config:
      tickAmount: 8
    min: 0
    max: ~8
  - id: score
    min: ~30
    max: ~80
series:
  - entity: sensor.resting_heart_rate
    yaxis_id: score
    type: line
    opacity: 1
    stroke_width: 2
    name: Resting Heart Rate
    color: rgba(253,89,89,1)
    fill_raw: last
    show:
      legend_value: false
      in_header: true
  - entity: sensor.deep_sleep_yesterday
    yaxis_id: hours
    type: area
    opacity: 0.8
    name: Deep
    color: black
    fill_raw: last
    show:
      as_duration: hour
      legend_value: true
      in_header: false
  - entity: sensor.rem_sleep_yesterday
    yaxis_id: hours
    type: area
    opacity: 0.2
    name: Rem
    color: blue
    fill_raw: last
    show:
      as_duration: hour
      legend_value: true
      in_header: false
  - entity: sensor.light_sleep_yesterday
    yaxis_id: hours
    type: area
    opacity: 0.5
    name: Light
    color: skyblue
    fill_raw: last
    show:
      as_duration: hour
      legend_value: true
      in_header: false
  - entity: sensor.sleep_quality
    yaxis_id: score
    type: area
    opacity: 0.5
    name: Sleep Score
    color: lightgreen
    show:
      in_chart: false
      legend_value: true
      in_header: true
  - entity: sensor.total_sleep_min_yesterday
    yaxis_id: total
    type: area
    opacity: 0.5
    name: Total Sleep
    color: orange
    float_precision: 2
    show:
      as_duration: minute
      in_chart: false
      legend_value: true
      in_header: true
3 Likes

I only can see sensor.sleep_quality

That sensor contains all the data or ‘attributes’ that can be used to derive additional sensors needed. This is well documented at https://github.com/nitobuendia/oura-custom-component. Separate section Derived sensors covers this https://github.com/nitobuendia/oura-custom-component#derived-sensors.

This is a very nice component to have, thank you @nitobuendia for this. I have tried to get this working on several occasions earlier, but for this or that reason just finally succeeded.

I’m seeing heart_rate_average values lower than the resting_heartrate. The API provides directly the hr_average [Oura API]. Perhaps that could be used instead of calculating the average of the hr_5min values (in sensor.py lines 335-339)? hr_5min array often contains 0’s which lower the calculated average erroneously.

Got the chart a bit cleaner:

type: custom:apexcharts-card
graph_span: 7d
now:
  show: true
header:
  show: true
  title: Sleep Stats
  show_states: true
  colorize_states: true
series:
  - entity: sensor.oura_ring
    name: Score
    show:
      in_chart: false
    color: grey
  - entity: sensor.sleep_resting_heart_rate_yesterday
    name: HR
    show:
      in_chart: false
  - entity: sensor.time_in_bed_yesterday
    name: In Bed
    type: area
    color: white
    group_by:
      func: last
      duration: 1d
  - entity: sensor.total_sleep_yesterday
    name: Total Sleep
    type: line
    color: purple
    group_by:
      func: last
      duration: 1d
  - entity: sensor.rem_sleep_yesterday
    name: REM
    color: '#20bf6b'
    group_by:
      func: last
      duration: 1d
  - entity: sensor.deep_sleep_yesterday
    name: Deep
    color: '#45aaf2'
    group_by:
      func: last
      duration: 1d
  - entity: sensor.light_sleep_yesterday
    name: Light
    color: '#fed330'
    group_by:
      func: last
      duration: 1d
  - entity: sensor.time_awake_yesterday
    name: Awake
    color: '#fc5c65'
    group_by:
      func: last
      duration: 1d


2 Likes

That looks solid! Good job :slight_smile:

Went down a rabbit hole on this, forked the repo and added v2 api feeds for activity and readiness as well as sleep: GitHub - akeslo/ouraring-ha: An attempt at an update to the original version using APIv2 + new data points

2 Likes

I can’t find this in HACS. What am I missing?

@toddsantoro

You can add it as a custom repo

In HACS

  1. goto integrations
  2. click the dot menu on top right corner and select “custom repositories”
  3. Copy the repo address to the field and select integration
  4. click Add

image

Thanks… I didn’t know that was a thing:)

1 Like

I had this GitHub - nitobuendia/oura-custom-component: Oura Custom Component for Home-Assistant. Adds Oura Ring sleep information. one installed before, if I wanted to use yours, do I need to remove previous one first?

No need to remove, it goes to a different folder, and uses platform: ouraring, instead of platform: oura. I have both installed.

1 Like