Skip to content

innonate/smart_fresh_air

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Smart Fresh Air

A Home Assistant integration for intelligent fresh air damper control based on indoor vs. outdoor environmental conditions.

Overview

Smart Fresh Air automatically controls a fresh air intake damper by comparing indoor and outdoor conditions (temperature, humidity, and air quality) to determine when bringing in outside air would be beneficial. The integration ensures a minimum amount of fresh air per hour while preventing uncomfortable or unhealthy conditions.

Key Features:

  • Safety-first logic — Temperature extremes block fresh air intake unless there's an indoor air quality emergency
  • Smart humidity comparison — Evaluates whether outdoor humidity will help or hurt indoor conditions
  • Accurate fresh air tracking — Only counts fresh air time when your HVAC fan is actually running
  • 20-minute hourly minimum — Ensures adequate fresh air while respecting blocking conditions
  • Manual overrides — Force open/closed for 24 hours or indefinitely
  • Detailed dashboard card — See exactly why the damper is open or closed

Installation

HACS (Recommended)

  1. Open HACS in Home Assistant
  2. Click Integrations+ Explore & Download Repositories
  3. Search for "Smart Fresh Air"
  4. Click Download
  5. Restart Home Assistant

Manual Installation

  1. Download the smart_fresh_air folder from this repository
  2. Copy it to your config/custom_components/ directory
  3. Restart Home Assistant

Configuration

After installation, add the integration via the UI:

  1. Go to Settings → Devices & Services → + Add Integration
  2. Search for "Smart Fresh Air"
  3. Follow the setup wizard:

Step 1: Damper Switch

Select the switch entity that controls your fresh air damper. This should be a Zigbee, Z-Wave, or WiFi switch wired to your damper actuator.

Note: The integration assumes a "power open" configuration where the switch being ON means the damper is OPEN.

Step 2: Temperature & Humidity Sensors

Select your indoor and outdoor temperature and humidity sensors. These are typically provided by your thermostat integration (e.g., Daikin Skyport, Ecobee, Nest).

Step 3: Air Quality Sensors

Select your outdoor AQI sensor. Indoor AQI is optional—many thermostats only provide outdoor air quality data.

Compatibility Note: Some integrations (like Daikin Skyport) use non-standard device classes for AQI sensors (e.g., "score" instead of "aqi"). The selector shows all sensors to accommodate this.

Step 4: HVAC Fan Detection

Select your HVAC airflow sensor (CFM). This enables accurate fresh air tracking—minutes are only counted when the fan is actually circulating air.

Why this matters: If your damper is open but the HVAC fan isn't running, no fresh air is actually being pulled in. This sensor ensures the "20 minutes per hour" goal represents actual air exchange.

Step 5: Optional Sensors

Optionally add bedroom temperature/humidity sensors for future enhanced comfort logic.


How It Works

Decision Priority (Safety-First)

The integration evaluates conditions in this order:

Priority Condition Result
1 Manual override active Follows override
2 Indoor AQI > 200 (Unhealthy) OPEN regardless of temperature
3 Outdoor temp < 40°F or > 90°F CLOSED (safety block)
4 Outdoor AQI > 150 (Unhealthy for Sensitive Groups) CLOSED
5 Outdoor AQI significantly worse than indoor CLOSED
6 Favorable conditions (score > 30) OPEN
7 Minimum fresh air needed & no hard blocks OPEN
8 Default CLOSED

Smart Humidity Logic

Unlike simple "is outdoor humidity in range" checks, this integration compares indoor vs. outdoor humidity to determine if fresh air would help or hurt:

Indoor Humidity Outdoor Humidity Result
Low (< 35%) Higher than indoor Favorable — will help humidify
Low (< 35%) Lower than indoor Blocking — won't help
High (> 55%) Lower than indoor Favorable — will help dehumidify
High (> 55%) Higher than indoor Blocking — will make it worse
Ideal (35-55%) Reasonable range Generally favorable

Example: If your indoor humidity is 43% and outdoor is 89%, the integration recognizes this as favorable because the humid outdoor air will help raise indoor humidity toward the ideal 50%.

Decision Score

A composite score from -100 to +100 helps visualize the overall favorability:

  • Temperature component (-40 to +20): Ideal range (55-78°F) scores highest
  • AQI component (-40 to +40): Based on indoor vs. outdoor comparison
  • Humidity component (-20 to +20): Based on whether outdoor air helps indoor conditions

Fresh Air Tracking

The integration tracks minutes of fresh air per hour, but only counts time when:

  1. The damper is open, AND
  2. The HVAC fan is running (airflow ≥ 50 CFM)

This ensures the 20-minute goal represents actual air exchange, not just "damper open time."


Entities

The integration creates these entities:

Entity Type Description
binary_sensor.should_open Binary Sensor Current decision (on = should be open)
sensor.decision_score Sensor Score from -100 to +100
sensor.decision_reason Sensor Human-readable reason for current state
sensor.fresh_air_this_hour Sensor Minutes of fresh air this hour
switch.fresh_air_damper Switch Virtual switch (tap to set 24h override)
select.override_mode Select Override mode selector

Key Attributes (on binary_sensor.should_open)

  • decision_reason / decision_reason_text — Why the damper is open/closed
  • decision_score — Composite favorability score
  • blocking_factors — List of conditions preventing fresh air
  • favorable_factors — List of conditions favoring fresh air
  • minutes_open_this_hour — Fresh air minutes this hour
  • fan_is_running — Whether HVAC fan is currently on
  • current_airflow_cfm — Current airflow reading

Dashboard Card

A custom Lovelace card is included for detailed status visualization.

Installation

  1. Add the card as a resource:

    • Go to Settings → Dashboards → Resources
    • Click + Add Resource
    • URL: /local/smart-fresh-air-card.js
    • Type: JavaScript Module
  2. Add the card to your dashboard:

type: custom:smart-fresh-air-card
entity: binary_sensor.should_open
override_entity: select.override_mode
title: Fresh Air Damper

Card Features

  • Status badge — OPEN (green) or CLOSED (gray)
  • Override indicator — Shows when manual override is active
  • Decision score bar — Visual -100 to +100 scale with color coding
  • Current reason — Why the damper is in its current state
  • Blocking/favorable factors — Detailed breakdown of decision inputs
  • Quick override buttons — Auto, Open 24h, Close 24h

Configuration Options

After initial setup, you can adjust thresholds via Settings → Devices & Services → Smart Fresh Air → Configure:

Option Default Description
Minimum Safe Temp 40°F Below this, fresh air is blocked
Maximum Safe Temp 90°F Above this, fresh air is blocked
Min Fresh Air Minutes 20 Target fresh air per hour

Design Decisions & Rationale

This section documents key architectural decisions for developers and contributors.

Why Safety-First Priority?

The decision logic uses a strict priority order rather than pure scoring because some conditions should always block fresh air regardless of other factors. A 30°F outdoor temperature should never result in an open damper just because the AQI score is favorable—the HVAC system would struggle to maintain comfort.

Exception: Indoor AQI emergencies (> 200) override temperature blocks because health takes priority over comfort at hazardous pollution levels.

Why Compare Indoor vs. Outdoor Humidity?

Early versions used simple "is outdoor humidity between 25-70%" checks. This failed in real-world scenarios:

  • Indoor at 43%, outdoor at 89% → Old logic: "Block, outdoor too humid"
  • Reality: Bringing in humid air would help the dry indoor condition

The comparison-based approach asks "will this help or hurt?" rather than "is outdoor humidity ideal?"

Why Require HVAC Fan Detection?

The fresh air intake only works when the HVAC system is circulating air. Without fan detection, the "20 minutes per hour" goal was meaningless—the damper could be open for 20 minutes while the fan was off, providing zero fresh air.

By tracking actual airflow (≥ 50 CFM threshold), the integration ensures the goal represents real air exchange.

Why Not Use Automations/Blueprints?

This feature requires:

  • Complex state tracking (minutes per hour, override expiration)
  • Multi-factor decision logic with priorities
  • Comparison-based evaluations (not just threshold checks)

While possible with automations and helpers, it would be fragile and difficult to maintain. A custom integration provides:

  • Proper state management via DataUpdateCoordinator
  • Clean entity creation with appropriate device classes
  • UI-based configuration flow
  • Easy distribution via HACS

Why Sync with HVAC Circulation Schedule?

Many HVAC systems (including Daikin) can be configured to circulate air for N minutes per hour when not heating/cooling. This integration is designed to work with that pattern:

  • Daikin circulates at the top of each hour
  • Integration prioritizes opening damper during first 20 minutes of hour
  • Fresh air tracking resets at hour boundaries

Troubleshooting

Damper not opening/closing

  1. Check that your damper switch entity is correct in the integration settings
  2. Verify the switch works manually via Home Assistant
  3. Check Home Assistant logs for errors from smart_fresh_air

AQI sensors not showing in setup

Some integrations use non-standard device classes (e.g., Daikin uses "score" instead of "aqi"). The AQI selector shows all sensors—search/filter for your AQI entity.

Fresh air minutes not counting

Verify that:

  1. The damper is actually open (check switch.fresh_air_damper)
  2. The HVAC fan is running (check fan_is_running attribute)
  3. Airflow is above 50 CFM (check current_airflow_cfm attribute)

Card showing "Entity not found"

  1. Verify the integration is set up and entities exist
  2. Check that entity IDs match your configuration (may vary based on setup)
  3. Clear browser cache and refresh

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Follow Home Assistant's integration development guidelines
  4. Test thoroughly with real hardware if possible
  5. Submit a pull request with a clear description

Development Setup

# Clone the repository
git clone https://github.com/innonate/smart_fresh_air.git

# Copy to your HA config for testing
cp -r smart_fresh_air/custom_components/smart_fresh_air ~/.homeassistant/custom_components/

# Enable debug logging
logger:
  logs:
    custom_components.smart_fresh_air: debug

Code Structure

smart_fresh_air/
├── __init__.py           # Integration setup, platform forwarding
├── manifest.json         # HACS/HA metadata
├── const.py              # Constants, thresholds, enums
├── coordinator.py        # Decision logic, state management
├── config_flow.py        # UI configuration wizard
├── binary_sensor.py      # "Should open" decision entity
├── sensor.py             # Score, reason, minutes entities
├── switch.py             # Virtual damper switch
├── select.py             # Override mode selector
├── strings.json          # Translation keys
└── translations/en.json  # English translations

Key Classes

  • SmartFreshAirCoordinator (coordinator.py): Core decision engine. Implements the priority-based logic, scoring, and state tracking. Extends DataUpdateCoordinator for efficient polling.

  • SmartFreshAirConfigFlow (config_flow.py): Multi-step configuration wizard using Home Assistant's config flow system.


License

MIT License — see LICENSE for details.


Acknowledgments

  • Inspired by discussions in the Home Assistant community about ERV/HRV control
  • Decision logic informed by EPA AQI guidelines and ASHRAE ventilation standards
  • Built for use with Daikin Skyport but designed to work with any HVAC integration

About

Home Assistant integration for intelligent fresh air damper control

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors