Frontend Panel for Diabetics using a Dexcom CGM

Binary helper is on or off.

Come to think of it, why would you need to use a helper at all?

As I said, I am hopelessly lost in YAML, but I try.
Something like this in three automations:

{% if states("sensor.sensor.blood_sugar")|float > 75}
# Light turn on
{% else %}
# Light turn off
{% endif %}
1 Like

I was told better to use a helpers though at first I was trying in one Automation but now its better even harder with what to do really. Also hard for me to explain it all and how the lamp is behaving! I have two sets of light one are Leds the other Beside lamp and I want both to run like sunset sunrise. but then after this th exchanging of the light colour only on the lamp so the other will turn on as normal when I used the motion sensor I have setup to detect me when I stick my hand out to go to my mobile, this triggers the Leds to come on!

I’m also no good on Yaml only to copy and past into it or try to change the code a little if I feel its right and I have backed up.

Not at all sure where I would put this code your showing me. I been side tracked due to a shed coming to be thinking on this! Takes me ages to get my head around to knowing what to try.

Too many variables really but should be easy is maybe I should start again with a new lamp and keep it off the other things I already have setup! Then is one fails the other will work as normal :slight_smile: Also any excuse for a new Lamp :rofl: :rofl: :kissing_closed_eyes:

Not sure what a Binary helper is on or off is? never used it before!

It’s getting it to the colour but its harder to get it to go back to a normal colour!

@Bart_Huitsing Love the idea of the radial chart and im playing about with Measureit as suggested though it appears to measure in seconds … what scale is this graoh using as right now the % are not what they should be

image

Based on the initial dashboard by @CaptainSweatpants I created a single Lovelace card which basically holds all the current information in one mini graph. I decided to share it as it might be of value to others.

For the trend I would have loved to use built-in icons in the state mapping (or just refer to the current icon of the trend sensor instead of including the trend sensor as an entity with a state mapping) but afaik this is not possible: hence I used unicode arrows that also show well on my iOS devices (which is not as obvious as one would expect).

IMG_0798

The configuration for this card:

type: custom:mini-graph-card
animate: true
entities:
  - entity: sensor.dexcom_glucose_value
    name: Dexcom CGM
  - entity: sensor.dexcom_glucose_trend
    show_graph: false
    show_state: true
state_map:
  - value: falling_quickly
    label: ⇊
  - value: falling
    label: ↓
  - value: falling_slightly
    label: ⬊
  - value: steady
    label: →
  - value: rising_slightly
    label: ⬈
  - value: rising
    label: ↑
  - value: rising_quickly
    label: ⇈
smoothing: true
hours_to_show: 24
line_width: 3
points_per_hour: 12
hour24: true
show:
  graph: line
  labels: false
  state: true
  name: true
  icon: false
  extrema: true
  average: true
  fill: false
color_thresholds:
  - color: "#8B0000"
    value: 0
  - color: "#FF0000"
    value: 3
  - color: "#0DA035"
    value: 4
  - color: "#E0B400"
    value: 10
  - color: "#FF0000"
    value: 14
color_thresholds_transition: hard
decimals: 1
icon: mdi:diabetes
lower_bound: ~4
upper_bound: ~14
3 Likes

Shouldn’t this be true?

No, it shouldn’t as it applies to the second entity only. This way I don’t print a graph for the glucose trend, but I do use the state_map on it to translate the sensor values to an arrow (you did notice the trend arrow in the upper right of the graph, didn’t you?)

AHA! I had the trend first… (Maybe if I had read the docs for the mini-graph card.)

I wonder if the average could be used to project an A1C estimate?

Updated SugarTV, now supports any size card and visual editor, please let me know if you have any questions about how to use it. Thank you!


1 Like

Excellent post, many thanks.

For those using nightscout trend sensor, the names are different, for example instead of rising_slightly it shoes FortyfiveUp. Hence I changed the map part to

state_map:
  - value: DoubleDown
    label: ⇊
  - value: SingleDown
    label: ↓
  - value: FortyFiveDown
    label: ⬊
  - value: Flat
    label: →
  - value: FortyFiveUp
    label: ⬈
  - value: SingleUp
    label: ↑
  - value: DoubleUp
    label: ⇈
  - value: unknown
    label: "--"

I removed that entry (probably after you copied it) as the state map of the mini graph card cannot be defined per entity. As a consequence adding “unknown” to the state map resulted in spikes in the glucose value graph.

Thanks :slight_smile:

I don’t know if this is the place to ask, but I have been using a nice view on my glucose values for a while now. Ever since 2025.6.x it is not working very good anymore (also not on 2025.7.00.bx).

It used to show the current value, but now it either shows the value with a lot of decimals after the comma, or it shows n/a.

type: custom:button-card
entity: sensor.dexcom_user_glucose_value
show_entity_picture: false
show_last_changed: false
show_icon: false
show_name: false
name: |
  [[[ 
     return `<span>${(states['sensor.dexcom_user_glucose_value'].state)} mmol/L</span>`
  ]]]
styles:
  card:
    - border-radius: 2%
    - padding: 2.5%
    - color: ivory
    - font-size: 12px
    - border-width: >
        [[[ if (states['sensor.dexcom_glucose_status'].state === 'Binnen
        bereik') return '0px';
            else return '2px';
        ]]]
    - border-color: >
        [[[ if (states['sensor.dexcom_glucose_status'].state === 'Erg laag')
        return 'red';
            if (states['sensor.dexcom_glucose_status'].state === 'Laag') return 'orange';
            if (states['sensor.dexcom_glucose_status'].state === 'Hoog') return 'orange';
            if (states['sensor.dexcom_glucose_status'].state === 'Erg hoog') return 'red';
            else return 'none';
        ]]]
  grid:
    - grid-template-areas: "\"img img\" \"trend trend\" \"update update\" \"range range\""
    - grid-template-columns: 1fr 1fr
    - grid-template-rows: 1fr min-content min-content min-content
  img_cell:
    - justify-content: middle
    - align-items: start
    - margin: none
    - padding-bottom: 5px
  icon:
    - width: 15%
    - margin-top: 0%
    - color: red
    - padding-bottom: 0px
  custom_fields:
    state:
      - align-self: start
      - justify-self: end
      - font-size: 17px
      - padding-bottom: 5px
    update:
      - font-family: helvetica neue, helvetica, Arial
      - font-weight: 500
      - font-size: 15px
      - color: grey
      - align-self: middle
      - justify-content: middle
      - padding-bottom: 5px
      - margin-top: 0px
    trend:
      - font-family: helvetica neue, helvetica, Arial
      - color: rgba(255, 255, 255, 0.7)
      - font-size: 15px
      - font-weight: 300
      - text-align: center
      - padding-bottom: 5px
    range:
      - font-family: helvetica neue, helvetica, Arial
      - font-size: 15px
      - font-weight: 500
      - text-align: center
      - line-height: 30px
      - color: white
      - background-color: |
          [[[
            if ((states['sensor.dexcom_glucose_status'].state === 'Erg laag'))
              return "red";
            if ((states['sensor.dexcom_glucose_status'].state === 'Laag'))
              return "orange";
            if ((states['sensor.dexcom_glucose_status'].state === 'Hoog'))
              return "orange";
            if ((states['sensor.dexcom_glucose_status'].state === 'Erg hoog'))
              return "red";
            else
              return "none";
          ]]]
    img:
      - font-weight: bold
      - font-size: 15px
      - color: >
          [[[ if (states['sensor.dexcom_glucose_status'].state === 'Binnen
          bereik') return 'grey';
              if ((states['sensor.dexcom_glucose_status'].state === 'Laag'))
          return "orange";
              if ((states['sensor.dexcom_glucose_status'].state === 'Hoog'))
          return "orange";
              else return 'red';
          ]]]
      - align-self: middle
      - justify-content: middle
      - padding-bottom: 65px
custom_fields:
  trend: |
    [[[ if (states['input_number.dexcom_change'].state > 0)
          return `${(states['sensor.dexcom_user_glucose_trend'].state)} (+${Math.round(states['input_number.dexcom_change'].state)})`;
        return `${(states['sensor.dexcom_user_glucose_trend'].state)} (${Math.round(states['input_number.dexcom_change'].state)})`;
    ]]]
  update: |
    [[[ return `${(states['sensor.dexcom_last_update'].state)}`; ]]]
  range: |
    [[[

      if ((states['sensor.dexcom_glucose_status'].state === 'Erg Laag'))
        return "Erg Laag";
      if ((states['sensor.dexcom_glucose_status'].state === 'Laag'))
        return "Laag";
      if ((states['sensor.dexcom_glucose_status'].state === 'Hoog'))
        return "Hoog";
      if ((states['sensor.dexcom_glucose_status'].state === 'Erg High'))
        return "Erg hoog";
      if ((states['sensor.dexcom_glucose_status'].state === 'Binnen bereik'))
        return "Binnen bereik";
      else
        return "N/A";
    ]]]
  img: |
    [[[
        if (states['sensor.dexcom_user_glucose_trend'].state == "steady")
          return `<img src=/local/icons/dexcom-steady.png
          style="width: 170px; height: 170px; color: #00def;">
          </ha-icon><span style="font-size:30px; margin-top:-111px; display:block;">${(states['sensor.dexcom_user_glucose_value'].state)}</span><span style="font-size:13px; margin-top:0px; display:block;">mmol/L</span>`;
        if (states['sensor.dexcom_user_glucose_trend'].state == "rising slightly")
          return `<img src=/local/icons/dexcom-risingslightly.png
          style="width: 170px; height: 170px; color: #00def;">
          </ha-icon><span style="font-size:30px; margin-top:-111px; display:block;">${(states['sensor.dexcom_user_glucose_value'].state)}</span><span style="font-size:13px; margin-top:0px; display:block;">mmol/L</span>`;
        if (states['sensor.dexcom_user_glucose_trend'].state == "falling slightly")
          return `<img src=/local/icons/dexcom-fallingslightly.png
          style="width: 170px; height: 170px; color: #00def;">
          </ha-icon><span style="font-size:30px; margin-top:-111px; display:block;">${(states['sensor.dexcom_user_glucose_value'].state)}</span><span style="font-size:13px; margin-top:0px; display:block;">mmol/L</span>`;
        if (states['sensor.dexcom_user_glucose_trend'].state == "falling")
          return `<img src=/local/icons/dexcom-falling.png
          style="width: 170px; height: 170px; color: #00def;">
          </ha-icon><span style="font-size:30px; margin-top:-111px; display:block;">${(states['sensor.dexcom_user_glucose_value'].state)}</span><span style="font-size:13px; margin-top:0px; display:block;">mmol/L</span>`;
        if (states['sensor.dexcom_user_glucose_trend'].state == "rising")
          return `<img src=/local/icons/dexcom-rising.png
          style="width: 170px; height: 170px; color: #00def;">
          </ha-icon><span style="font-size:30px; margin-top:-111px; display:block;">${(states['sensor.dexcom_user_glucose_value'].state)}</span><span style="font-size:13px; margin-top:0px; display:block;">mmol/L</span>`;
        if (states['sensor.dexcom_user_glucose_trend'].state == "falling quickly")
          return `<img src=/local/icons/dexcom-fallingquickly1.png
          style="width: 170px; height: 170px; color: #00def;">
          </ha-icon><span style="font-size:30px; margin-top:-111px; display:block;">${(states['sensor.dexcom_user_glucose_value'].state)}</span><span style="font-size:13px; margin-top:0px; display:block;">mmol/L</span>`;
        if (states['sensor.dexcom_user_glucose_trend'].state == "rising quickly")
          return `<img src=/local/icons/dexcom-risingquickly1.png
          style="width: 170px; height: 170px; color: #00def;">
          </ha-icon><span style="font-size:30px; margin-top:-111px; display:block;">${(states['sensor.dexcom_user_glucose_value'].state)}</span><span style="font-size:13px; margin-top:0px; display:block;">mmol/L</span>`;
        return `<img src=/local/icons/dexcom-steady.png
          style="width: 170px; height: 170px; color: #00def;">
          </ha-icon><span style="font-size:30px; margin-top:-111px; display:block;">N/A</span><span style="font-size:13px; margin-top:0px; display:block;">mmol/L</span>`;
    ]]]
tap_action:
  action: none

I have tried to alter some code myself, but can’t seem to figure it out.

The sensor sensor.dexcom_user_glucose_value has the correct value. I can also see the color change based on the value, but the value itself doesn’t show.

The decimals is set to 1, see:

But using debug tools it is with a lot of decimals:

Just a guess. Change:
<span>${(states['sensor.dexcom_user_glucose_value'].state)} mmol/L</span>
to:
<span>${parseFloat(states['sensor.dexcom_user_glucose_value'].state).toFixed(2)} mmol/L</span>

This would change 11.166666666666667 to 11.17

What is your display? This looks like well written YAML.

1 Like

It looks like below. The arrow on the right changes up down or just to the right based on the trend.

This is with your suggestion included. The strange thing is when I change mmol to something completely else, it doesn’t show. I’ll try and put into a clear dashboard to see if that helps.

other dashboard didn’t help, so it is in the card. I changed the mmol, but that’s part of the IMG: block. Doesn’t hold the actual value.


Cool! With your code I’ve edit the last IMG block and added the rounding to all parts. Now it is nicely rounded. Thanks a lot!

Cool. What is the display? I would like to duplicate it here.
Also please click on the solution.

Given the code says it’s a custom button card, I guess it is a standard dashboard.

I don’t fully understand what you mean by the display question. I already posted the screenshot multiple times. So I assume you don’t mean that, but what then?

I thought you were using a display other than the dashboard.

I fixed this issues with using Companion App