Thermal Comfort Dashboard: Rooms, Modes, Charts, and Diagnostics

Thermal Comfort Dashboard: Rooms, Modes, Charts, and Diagnostics

Module 19 · Lesson 11

Thermal Comfort Dashboard: Rooms, Modes, Charts, and Diagnostics

In Lesson 10, you tied together comfort modes, schedules, and manual override. Now you're building a panel that lets you see the whole house at a glance: temperatures, humidity, CO2, comfort mode, the override timer, and diagnostic signals. This isn't meant to be Lovelace decoration: it's a daily decision-making tool.

A well-built dashboard saves time and nerves. Instead of clicking through five tabs, you can see: is the house in the mode you expect, is any sensor going quiet, do the CO2 reminders make sense, and did the schedule accidentally get blocked by the override. This is the last step before the mini project in Lesson 12.

Plan on about 105 to 115 minutes. From here on, I'll shorten Home Assistant to HA.

A reminder from Lesson 10
A schedule changes the mode, not the temperature every few minutes.
The dashboard should show this clearly: what the current mode is, whether manual override is active, and whether the timer is genuinely counting down. With boiler_integration_level = Read-only, the panel doesn't suggest direct boiler control.

A real-life problem: the data exists, but tells you nothing

You have temperature entities, a bathroom humidity sensor, bedroom CO2, and a handful of mode helpers. In theory, everything works. In practice, it's cold in the morning and you don't know why: did the schedule not fire, did the override stay on after an HA restart, was the TRV head unavailable.

In the evening, you get a CO2 reminder and open the window, only to notice afterward that outdoor PM2.5 was high. You're missing one place that shows the relationships. You end up "debugging the house" through the automation history instead of simply looking at a panel and making a calm decision.

This lesson's goal is a dashboard that answers three questions: what mode are we in, are the sensors showing sensible data, is the comfort automation predictable.

What's actually the risk

Too many cards: the dashboard looks impressive but hides what matters.

No diagnostics: you see the temperature, but not a missing data point or the automation's state.

One card for everything: no separation between a quick overview and a detail section.

No visible mode: you don't know whether the schedule actually switched the house's state.

Mixing control and reading: an accidental tap changes something you didn't mean to change.

Which sensors and devices to show

At this stage of the module, you already have a full set of signals worth having in one place. Don't add everything at once. Start with the minimum that genuinely supports the household's decisions.

Area Example entities Why it belongs on the dashboard
Mode and schedule input_select.comfort_mode, input_boolean.comfort_manual_override, timer.comfort_override_reset You quickly see who's "in charge": the schedule or the override
Temperature sensor.living_room_temperature, climate.living_room_trv You see the trend and the target value in the room
Humidity sensor.bathroom_humidity, switch.bathroom_fan Checking the Lesson 8 scenario
CO2 and smog sensor.bedroom_co2, sensor.outdoor_pm25 Verifying whether the airing-out reminder makes sense
Safety switches input_boolean.comfort_automation_enabled, unavailable/unknown alerts One click and a quick fault diagnosis

Which entities you watch every day

In everyday use, the household doesn't need 40 entities. They need 6 to 10 of the most important ones, plus one combined status. That's why we'll add a text sensor, sensor.home_comfort_status, that summarizes the situation.

Don't guess by eye
If the status says "No data...", check the sensor first. If it says "CO2 high" or "Humidity high": respond to air comfort, even while an override is active. "Override active" is a lower-priority operational message. Only after that do you tune modes and thresholds.

Which sensor to add

The lesson's most important piece is a summary template sensor. It draws on entities from earlier lessons: temperature, humidity, CO2, PM2.5, mode, and override. The icon is static: the text state matters more than a dynamic icon.

template:
  - sensor:
      - name: "Home Comfort Status"
        unique_id: home_comfort_status
        icon: mdi:home-thermometer
        state: >-
          {% set temp = states(''sensor.living_room_temperature'') %}
          {% set hum = states(''sensor.bathroom_humidity'') %}
          {% set co2 = states(''sensor.bedroom_co2'') %}
          {% set pm = states(''sensor.outdoor_pm25'') %}
          {% set smog_on = is_state(''input_boolean.smog_season_enabled'', ''on'') %}
          {% set pm_limit = states(''input_number.outdoor_pm25_max'') | float(25) %}
          {% set co2_limit = states(''input_number.co2_reminder_threshold'') | float(1000) %}
          {% set hum_high = states(''input_number.bathroom_humidity_threshold_on'') | float(70) %}
          {% if temp in [''unavailable'', ''unknown'', ''none''] %}
            No temperature data
          {% elif hum in [''unavailable'', ''unknown'', ''none''] %}
            No humidity data
          {% elif co2 in [''unavailable'', ''unknown'', ''none''] %}
            No CO2 data
          {% elif smog_on and pm in [''unavailable'', ''unknown'', ''none''] %}
            No PM2.5 data
          {% elif temp not in [''unavailable'', ''unknown'', ''none''] and (temp | float(21)) < 16 %}
            Temperature too low
          {% elif temp not in [''unavailable'', ''unknown'', ''none''] and (temp | float(21)) > 26 %}
            Temperature too high
          {% elif hum not in [''unavailable'', ''unknown'', ''none''] and (hum | float(0)) > hum_high %}
            Humidity high
          {% elif co2 not in [''unavailable'', ''unknown'', ''none''] and (co2 | float(0)) > co2_limit %}
            CO2 high
          {% elif smog_on and pm not in [''unavailable'', ''unknown'', ''none''] and (pm | float(999)) > pm_limit %}
            Smog outside
          {% elif is_state(''input_boolean.comfort_manual_override'', ''on'') %}
            Override active
          {% else %}
            Stable
          {% endif %}
        attributes:
          comfort_mode: "{{ states(''input_select.comfort_mode'') }}"
          comfort_automation: "{{ states(''input_boolean.comfort_automation_enabled'') }}"
          override: "{{ states(''input_boolean.comfort_manual_override'') }}"
          override_timer: "{{ states(''timer.comfort_override_reset'') }}"

The order of the states: missing data → a comfort deviation (temperature / humidity / CO2) → smog → override → Stable. The override doesn't hide high CO2. Adjust the 16°C / 26°C (61°F / 79°F) thresholds and the humidity threshold from the helper to your house. If you don't have one of these entities: remove the matching branch and the matching card from the dashboard (the full YAML below assumes every path in the course).

The status is an operational hint, not a medical alarm. If your sensor layout differs, change the entities and the state names.

Which YAML to paste in: the dashboard's structure

The dashboard isn't the boiler's service panel
On the main view, show the mode, temperatures, statuses, and diagnostics. Don't add buttons for changing boiler, OpenTherm, Modbus, or EMS-ESP parameters unless you have a separate technical view and a clear Plan B.

The example below is one page of the "Comfort" dashboard. First the summary and mode controls, then the room sections, and diagnostics at the end. It uses standard cards, so a beginner doesn't need to install any extra add-ons.

title: Home Comfort
views:
  - title: Comfort
    path: comfort
    icon: mdi:home-thermometer
    cards:
      - type: entities
        title: House status: summary
        entities:
          - entity: sensor.home_comfort_status
            name: Comfort status
          - entity: input_select.comfort_mode
            name: Comfort mode
          - entity: input_boolean.comfort_manual_override
            name: Manual override
          - entity: timer.comfort_override_reset
            name: Override timer
          - entity: input_boolean.comfort_automation_enabled
            name: Comfort automation

      - type: history-graph
        title: Mode and status timeline: 24 h
        hours_to_show: 24
        entities:
          - sensor.home_comfort_status
          - input_select.comfort_mode
          - input_boolean.comfort_manual_override

      - type: entities
        title: Living room: temperature
        entities:
          - entity: sensor.living_room_temperature
            name: Living room temperature
          - entity: climate.living_room_trv
            name: Living room TRV head
          - entity: input_number.comfort_temperature
            name: Comfort
          - entity: input_number.eco_temperature
            name: Eco

      - type: history-graph
        title: Living room: 24 h
        hours_to_show: 24
        entities:
          - sensor.living_room_temperature
          - climate.living_room_trv

      - type: entities
        title: Bathroom and bedroom: air
        entities:
          - entity: sensor.bathroom_humidity
            name: Bathroom humidity
          - entity: switch.bathroom_fan
            name: Bathroom fan
          - entity: sensor.bedroom_co2
            name: Bedroom CO2
          - entity: sensor.outdoor_pm25
            name: Outdoor PM2.5
          - entity: input_boolean.smog_season_enabled
            name: Smog season

      - type: history-graph
        title: Air: 24 h
        hours_to_show: 24
        entities:
          - sensor.bathroom_humidity
          - sensor.bedroom_co2
          - sensor.outdoor_pm25

      - type: logbook
        title: Comfort automation diagnostics
        entities:
          - automation.comfort_start_manual_override_timer
          - automation.comfort_cancel_timer_after_manual_override_off
          - automation.comfort_reset_override_and_sync_mode
          - automation.comfort_morning_comfort_schedule
          - automation.comfort_night_night_schedule
          - automation.comfort_bedroom_co2_airing_out_reminder

Remove or comment out any entities you don't have. A comfort dashboard is meant to build trust. If it shows several empty entries right from the start, a household member will stop looking at it.

A history graph of the text status and mode may look different from a temperature chart. This is about a timeline of changes, not a smooth line of values. If the card is hard to read, leave that state in the summary section and use the logbook for diagnosing changes.

Match the automation entities in the logbook to your own alias names. This is exactly where you'll see whether the schedule actually ran, and whether the override was turned off by the timer or by hand.

Depending on your HA interface version, the activity-history card may be labeled Logbook or Activity. If the type: logbook YAML doesn't work in your version, add the card from the visual editor: an activity/logbook card, pointed at the same automations.

The diagnostics section: what to look for

The point of the diagnostics panel isn't to make everything red and alarming. It's to quickly recognize the class of problem:

A data problem: unknown/unavailable on a sensor.

A logic problem: the mode doesn't match the schedule despite valid data.

An execution problem: the automation starts, but the target entity doesn't respond.

This keeps you from mixing up thresholds and schedules right away. Fix the data first, then the logic, and tune comfort last.

A seasonal testing section on the dashboard

Toward the end of the module, you'll run seasonal tests anyway. Instead of keeping them in your head, add a simple markdown card with a checklist. Before heating season, you have the same set of reminders and avoid "October surprises."

The Markdown card is just a reminder list. Clicking the checkbox doesn't save a completed test to a helper: it's visual text. The content field must be a text block (the | block), not a YAML list.

type: markdown
title: Seasonal tests: comfort
content: |
  - [ ] Check the morning and night schedules (do they change comfort_mode)
  - [ ] Check manual override and the reset timer
  - [ ] Check the unavailable/unknown alert for CO2 and humidity
  - [ ] Check the PM2.5 threshold and smog season
  - [ ] Check that comfort_automation_enabled works as a safety switch
  - [ ] Check Plan B: how the house behaves with HA off

Comfort dashboard note

# Comfort dashboard: acceptance check
Test date: ____

Main view:
- home_comfort_status: present / missing
- comfort_mode + override + timer: present / missing
- comfort_automation_enabled: present / missing

Room sections:
- Living room temperature + climate: OK / needs fixing
- Bathroom humidity + fan: OK / needs fixing
- Bedroom CO2 + PM2.5: OK / needs fixing

Diagnostics:
- automation logbook: working / not working
- 24 h charts: readable / not readable
- unavailable entities visible: yes / no

Seasonal test:
- morning and night schedule: passed / needs work
- override and timer: passed / needs work
- Plan B for an HA outage: documented / missing

How to test this lesson

1. Add the summary card: home_comfort_status, mode, override, timer, automation.

2. Turn on the override and check that the status switches to "Override active."

3. Simulate high CO2 (or use a real rise) and check that the status changes.

4. Set the morning schedule to fire in 5 minutes, temporarily, and check the logbook.

5. Check the missing-data scenario without any risky changes to the installation. The simplest way: use the existing unavailable alert from earlier lessons, or temporarily point the status sensor at a nonexistent test entity name. Restore the correct name after testing.

6. Fill in the acceptance note and fix entity names anywhere the panel isn't readable.

Common mistakes

Meaningless tiles: the panel looks nice but doesn't show the automation's state.

No override timer: the household doesn't know why the schedule isn't working.

No 24-hour history: you judge comfort from a single reading.

Empty entities: a dashboard full of "entity not available" erodes trust in the system.

What not to do

Don't put buttons on the main dashboard that could accidentally change critical boiler settings.

Don't hide unavailable/unknown information: it's a diagnostic signal, not an embarrassing detail.

Don't build a separate panel for every minor entity. Start with the daily panel, add a technical view later.

Practical assignment

☐ Add the home_comfort_status sensor and check all of its states.

☐ Build the "Comfort" view with a summary section, rooms, and diagnostics.

☐ Add 24-hour charts for temperature, humidity, and CO2.

☐ Add a logbook for the schedule and override automations.

☐ Add a seasonal testing section and run at least 3 tests.

☐ Fill in the dashboard acceptance note and update the system map: comfort dashboard: done.

Key takeaways

The comfort dashboard should help with decisions, not just look good.

home_comfort_status organizes diagnostics and shortens response time.

Charts + logbook give context for both the trend and the automation history.

The seasonal panel turns comfort from "intuition" into a repeatable process.

What's next

In Lesson 12, you'll build the closing mini project: a whole-house comfort plan, seasonal scenarios, and a maintenance checklist. That's where you'll bring the system map, the schedules, the dashboard, and the Plan B together into one document you can maintain all year round.

If this dashboard runs stably for a week, you're ready for the module's finale: not "automation for automation's sake," but predictable home comfort.

Finished this lesson?