Using BME680 sensor with BSEC

I just added a “BME680” sensor. There is a software package supporting this and I added the code (bme680_bsec). The compile fails for lack of “bsec.h”. The error message tells me what to put in “platformio.ini”. I do not know how to access this file & where is it? Another message suggested I update to “Platform IO Core 6”. I also do not know how to do that. Guess I have a great deal to learn at age 76. :wink:

Not sure I fully follow. It looks like this sensor is already supported in ESPHome without any extra libraries. Are you using this?

Thanks for reply. No, I previously used that with no problem.
This is an enhanced version with BSEC library called by yaml statement: ‘bme680_bsec’
The compile for me gives error for missing library bsec.h
The error directs me to adding the library in ‘platformio.ini’ in ‘lib_deps’ [env:] section.
Where is that file I need to edit? How do I edit it?
Thanks

Ah, got ya.

Have you tried the ‘Clean Build Files’ option? It’s under the three dots menu for the device on the ESPHome add-on page. That’s fixed I don’t know how many random errors I’ve encountered when compiling (and specifically making changes).

Hey

I use this code and it works well.

i2c:
  scan: false

bme680_bsec:
    # id
    # -----------
    # Identifier for this component, useful when working with multiple devices.
    # Must be unique, and can be used in the sensor sections to refer to the correct device.
    # Default: auto-computed
    id: bme680_internal

    # i2c address
    # -----------
    # Common values are:
    # - 0x76
    # - 0x77
    # Default: 0x76
    address: 0x77

    # Temperature offset
    # ------------------
    # Useful if device is in enclosure and reads too high
    # For example, if it reads 5C too high, set this to 5
    # This also corrects the relative humidity readings
    # Default: 0
    temperature_offset: 0

    # IAQ calculation mode
    # --------------------
    # Available options:
    # - static (for fixed position devices)
    # - mobile (for on a person or other moveable devices)
    # Default: static
    iaq_mode: static

    # Sample rate
    # -----------
    # Available options:
    # - lp (low power - samples every 3 seconds)
    # - ulp (ultra-low power - samples every 5 minutes)
    # Default: lp
    sample_rate: lp

    # Interval at which to save BSEC state
    # ------------------------------------
    # Default: 6h
    state_save_interval: 6h

sensor:
  - platform: bme680_bsec
    # ID of the bme680_bsec component to use for the next sensors.
    # Useful when working with multiple devices
    bme680_bsec_id: bme680_internal

    temperature:
      # Temperature in °C
      name: "Temperature"
      sample_rate: lp
      filters:
        - median
    pressure:
      # Pressure in hPa
      name: "Pressure"
      sample_rate: lp
      filters:
        - median
    humidity:
      # Relative humidity %
      name: "Humidity"
      sample_rate: lp
      filters:
        - median
    gas_resistance:
      # Gas resistance in Ω
      name: "Gas Resistance"
      filters:
        - median
    iaq:
      # Indoor air quality value
      name: "IAQ"
      id: iaq
      filters:
        - median
    iaq_accuracy:
      # IAQ accuracy as a numeric value of 0, 1, 2, 3
      name: "Numeric IAQ Accuracy"
    co2_equivalent:
      # CO2 equivalent estimate in ppm
      name: "CO2 Equivalent"
      filters:
        - median
    breath_voc_equivalent:
      # Volatile organic compounds equivalent estimate in ppm
      name: "Breath VOC Equivalent"
      filters:
        - median

text_sensor:
  - platform: bme680_bsec
    iaq_accuracy:
      # IAQ accuracy as a text value of Stabilizing, Uncertain, Calibrating, Calibrated
      name: "IAQ Accuracy"

  - platform: template
    name: "IAQ Classification"
    icon: "mdi:checkbox-marked-circle-outline"
    lambda: |-
      if ( int(id(iaq).state) <= 50) {
        return {"Excellent"};
      }
      else if (int(id(iaq).state) >= 51 && int(id(iaq).state) <= 100) {
        return {"Good"};
      }
      else if (int(id(iaq).state) >= 101 && int(id(iaq).state) <= 150) {
        return {"Lightly polluted"};
      }
      else if (int(id(iaq).state) >= 151 && int(id(iaq).state) <= 200) {
        return {"Moderately polluted"};
      }
      else if (int(id(iaq).state) >= 201 && int(id(iaq).state) <= 250) {
        return {"Heavily polluted"};
      }
      else if (int(id(iaq).state) >= 251 && int(id(iaq).state) <= 350) {
        return {"Severely polluted"};
      }
      else if (int(id(iaq).state) >= 351) {
        return {"Extremely polluted"};
      }
      else {
        return {"error"};
      }

Clean build did not help. I need to find the platformio.ini file, then I can add the entry shown in the error message. I am missing the header file bsec.h

My code is the same as yours but will not compile under home-assistant/esphome. Did you do something to get ‘bsec.h’? Is there a way for me to edit 'platformio.ini? The error mention shows me how to fix it if I can edit that file. Thanks, Doug

I did not have to do anything manually.

Here’s my framework code:

esp32:
  board: esp32dev
  framework:
    type: arduino
    version: recommended

Try clearing your build files.

I found platformio.ini in build directory but that gets overwritten.
Now I think they want this in ‘custom_components’ folder and I do not know where that is.
I should not need to go so deep into things if it works for you after not doing anything special. And yet I can not get it to work.
Not sure what next step should be.

The ‘bme680_bsec’ is a standard ESPHome component, so it should work ‘out of the box’ without any ‘manual intervention’. I’m using this component myself and it compiles without errors (ESPHome version 2023.10.3). So it looks like a problem in your environment or something in the yaml code.

To help you we need more information, so please post your complete yaml and the log files. Also the version of ESPHome you are using.

1 Like

I can confirm this has worked for last 12 months on a ESP2866. I just checked with new recompile and no errors. I just copied the ESPHome template from below…no fiddling …no extra files.

Tomorrow I expect to have some time. I will post my YAML and log file. BTW, my chip/module is actually a bme688, but that works with bme680_bsec I am told. Seeing this is a missing ‘bsec.h’ problem, the bme688 is not this problem. I was running the ‘bme680’ s/w no problem, then I tried to upgrade to the ‘bme680_bsec’ and could not compile. So my environment works with ‘bme680’ version (interesting).
I really appreciate the help, thank you.

I have my yaml and compile log. Need a lesson in posting them properly…sorry. Where can I learn that?
Thanks, Doug

Ignore preachy bit and read down the post

Very helpful, thanks.
I appreciate the help I get here, so let me compose a proper package of information and post that.
I do try hard to fix my own problems and attempt to read the appropriate documents and search posts.
So I will reply when I have done my work putting together a good package of information.
Thanks, Doug

1 Like

I hope I do better at providing good information: computer is ODROID-N2+ & O/S:11.1 & Home Assistant 2023.10.5 & Supervisor 2023.10.1 & Frontend 20231005.0-lattest.

The espHome YAML:
‘’’
###############################################################################

solar_battery_fan.yaml for PWM fan control for solar 48vdc battery box to

vent hydrogen. created 06/22/2023 by Doug Basberg

####################

A 120mm PWM fan will vent hydrogen from battery charging to 2" PVC pipe to

outdoor vent.

Two gas sensors (BME688 and MQ-8) will provide date to ESP32 to decide how

much hydrogen is accumulating in the battery box.

The fan speed will be controlled by PWM from the ESP32 based on gas values.

#############

gas sensor MQ-8 is hydrogen specific and creates an analog value for quantity

of hydrogen which is read on gpio32 and digtal out goes to gpio33.

gas sensor BME688 uses I2C to report temperatue, humidity, Pressure, and gas

resistance.

ESP32 reads gas sensors and controls fan PWM and reports operation to HA.

###############################################################################

#####################################################

06/22/2023 DSB – start development of project

06/26/2023 DSB – add PWM code - later check for correct values

06/27/2023 DSB – further code development

06/28/2023 DSB – eliminating compile errors in HA environment

##b06/30/2023 DSB – decided to use MQTT because ‘api’ is not well documented.
##########################################

06/30/2023 DSB – move to Notepad++ for initial code entry and return to

HA esphome later for testing and further development.

working in Obsidian on initial coding

10/21/23 DSB – After bench testing, fan added to ESP2 board - upped fan limit

to 95% and min to 30% - ready to mount in battery box for power & gas cal

10/23/23 DSB - add MQTT_subscribe of manual fan speed - add ‘on-values’ to

automate ‘auto fan control’ by gas sensors

10/24/23 DSB - more debug editing.

10/25/23 DSB - addingscripts failed!- add ‘interval’ component

10/26/23 DSB - continue development - decision about which sensor for fan

speed (%) & coversion to (%) - added " BME680_bsec "

##################################################################################

substitutions:
device_name: solar-battery-fan
friendly_name: solar-battery-fan
ip_address: !secret solar_fan_ip_address
broker_ip: !secret broker_ip

assign I/O pins

mq_8a_pin: “32”
mq_8d_pin: “33”
sda_1_pin: “21”
scl_1_pin: “22”
tach_pin: “13”
pwm_out_pin: “14”

define constants

bme688_gas_resistance_min: “6000” # high fan needed below this value
mq_8_gas_min: “5000” # high fan needed below this value
h2_max_volt: “2.00” # MQ-8 voltage for max fan
h2_lo_volt: “0.60” # MQ-8 voltage for min fan

########################################################

GLOBALS

########################################################

globals:

FAN variables

  • id: auto_mode # fan mode
    type: bool
    restore_value: no
    initial_value: ‘true’

  • id: mq8_percent_on # value from MQ8 H2 sensor routine
    type: float
    restore_value: no
    initial_value: ‘100’

  • id: bme688_percent_on # value from bme688 sensor routine
    type: float
    restore_value: no
    initial_value: ‘100’

  • id: fan_percent_on # current fan percent ON
    type: float
    restore_value: no
    initial_value: ‘100’

  • id: target_speed # RPM
    type: float
    restore_value: no
    initial_value: ‘0’

  • id: fan_tach # RPM
    type: float
    restore_value: no
    initial_value: ‘0’

################# END OF GLOBALS #####################

esphome:
name: ${friendly_name}

esp32:
board: esp32doit-devkit-v1
framework:
type: arduino
version: recommended

logger:
level: DEBUG

####### Using MQTT instead #####
#api:

ota:

wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: ${ip_address}
gateway: !secret wifi_gateway
subnet: !secret wifi_subnet

enable fallback hotspot

ap:
ssid: “solar_fan_hotspot”
password: “Aa234567@”

#############################
web_server:
port: 80
#############################

captive_portal:

###########################################

MQTT setup

###########################################

mqtt:
broker: ${broker_ip}
username: has
password: !secret mqtt_pw
topic_prefix: !secret solar_battery_fan_prefix
log_topic: !secret solar_battery_fan_log

#######################################################

#######################

I2C bus A

#######################

i2c:
sda: $sda_1_pin
scl: $scl_1_pin
id: i2c_a
scan: true

change from 100kHz

frequency: 10khz

###########################################################
######### BME688 SENSOR with BSEC routines ############
###########################################################
bme680_bsec:
id: bme688_bsec
address: 0x76 # could be 0x77
temperature_offset: 0
iaq_mode: static
sample_rate: ulp # ulp = 5min & lp = 3sec
state_save_interval: 24h #efault si 6h

##########################################################

###########################################################

Binary Sensors

###########################################################

binary_sensor:

MQ-8 hydrogen sensor digital out

  • platform: gpio
    id: h2_above_limit
    name: “H2 above limit”
    pin:
    number: $mq_8d_pin
    inverted: false
    mode:
    input: true

###########################################################

Sensors

###########################################################

sensor:

Debug Counters to watch operation from HA

  • platform: template
    name: debug_one
    id: debug_one
    update_interval: never

  • platform: template
    name: debug_two
    id: debug_two
    update_interval: never

read manual speed (float 0-100) from HA

  • platform: mqtt_subscribe
    name: manual_speed
    topic: esphome/sbf/speed
    id: manual_speed
    on_value:
    then:
    - if:
    condition:
    lambda: ‘return id(auto_mode) == false;’
    then:
    - lambda: |-
    id(fan_percent_on) = id(manual_speed).state;

    -  sensor.template.publish:
        id: debug_one
        state: !lambda 'return id(manual_speed).state;'
    

##################################################

MQ-8 hydrogen gas sensor analog voltage

##################################################

  • platform: adc
    pin: $mq_8a_pin
    attenuation: auto
    id: battery_gas_voltage
    name: “battery_gas_voltage”
    update_interval: 60s
    on_value:
    then:
    - lambda: |-
    id(mq8_percent_on) = 70.0;
    - if:
    condition:
    lambda: ‘return id(battery_gas_voltage).state > ${h2_max_volt};’
    then:
    - lambda: |-
    id(mq8_percent_on) = 95.0;
    - if:
    condition:
    lambda: ‘return id(battery_gas_voltage).state < ${h2_lo_volt};’
    then:
    - lambda: |-
    id(mq8_percent_on) = 30.0;
    - sensor.template.publish:
    id: debug_two
    state: !lambda ‘return id(mq8_percent_on);’
    ###############################################################

Send WiFi signal strength & uptime to HA

  • platform: wifi_signal
    name: $friendly_name WiFi Strength
    update_interval: 60s
  • platform: uptime
    name: $friendly_name Uptime
    id: uptime_sensor
    update_interval: 60s

Read Fan tacho PIN and show measureed RPM as a sensor

  • platform: pulse_counter
    name: solar_fan_rpm
    pin:
    number: $tach_pin
    mode: INPUT_PULLUP
    unit_of_measurement: ‘RPM’
    id: solar_fan_rpm
    accuracy_decimals: 0
    filters:
    • multiply: 0.5 # for two pulses per rev (maybe 1?)

#######################################################################
################ BME688 SENSORS #####################################
#######################################################################

Using BSEC routine

BME688 sensor - T, H, P, gas (but only bme680 routine available)

  • platform: bme680_bsec
    bme680_bsec_id: bme688_bsec

    temperature:
    name: $friendly_name Temperature
    id: batt_box_temperature
    sample_rate: lp
    filters:
    - median

    humidity:
    name: $friendly_name Humidity
    id: batt_box_humidity
    sample_rate: lp
    filters:
    - median

    pressure:
    name: $friendly_name Pressure
    id: batt_box_pressure
    sample_rate: lp
    filters:
    - median

    gas_resistance: # in ohms
    name: $friendly_name Gas Resistance
    id: batt_box_gas_resistance
    filters:
    - median

    iaq:

    indoor air quality

    name: “BME688 IAQ”
    filters:
    - median
    iaq_accuracy:

    IAQ accuracy as a numeric value of 0, 1, 2, 3

    name: “BME688 Numeric IAQ Accuracy”
    co2_equivalent:

    CO2 equivalent in ppm

    name: “BME688 CO2 Equivalent”
    filters:
    - median
    breath_voc_equivalent:

    Volatile Organic Compounds equivalent in ppm

    name: “BME688 Breath VOC Equivalent”
    filters:
    - median

################## END OF BME688 SENSORS ##########

############### END OF SENSORS #####################

########################## TEXT SENSORS ############

text_sensor:

  • platform: bme680_bsec
    iaq_accuracy:

    IAQ accuracy as a text value of Stabilizing, Uncertain, calibrating,

    or Calibrating

    name: “BME688 IAQ Accuracy”

Send IP Address

  • platform: wifi_info
    ip_address:
    name: $friendly_name IP Address

Send Uptime in raw seconds

  • platform: template
    name: $friendly_name Uptime
    id: uptime_human
    icon: mdi:clock-start

################## END OF TEXT SENSORS ###########################

#######################################################################

Good for debugging, you can manually set the fan

speed. Just make sure the Climate device is set to off or it will keep

getting overridden.

###############
fan:

  • platform: speed
    id: solar_battery_fan
    output: solar_fan_speed_set
    name: “Solar Battery Fan”
    restore_mode: ALWAYS_ON

output:

Wire this pin (pwm_out) into the PWM pin of your 12v fan

ledc is the name of the pwm output system on an esp32

  • platform: ledc
    id: solar_fan_speed_set
    inverted: false
    pin: $pwm_out_pin

    25KHz is standard PC fan frequency, minimises buzzing

    frequency: “25000 Hz”

    my fans stop working below 30% power.

    also they’re powerful and loud, cap their max speed to 95%

    min_power: 30%
    max_power: 95%

################################################################
############ SWITCHES ########################################
################################################################

switch:

Expose an ESP32 restart button to HA

  • platform: restart
    name: ${friendly_name} ESP32 Restart
    id: solar_fan_restart

###############################################################
################## TIME ####################################
###############################################################

time:

  • platform: sntp
    id: sntp_time
    on_time:

    Restart every day at 12:30am.

    I’ve had some memory issues lockup

    the device after a couple weeks

    Every morning at 12:30am

    • seconds: 0
      minutes: 30
      hours: 0
      then:
      • switch.turn_on: solar_fan_restart
      • delay: 10ms
      • switch.turn_off: solar_fan_restart

############## END OF TIME ############################

#######################################################

Run tasks at intervals

#######################################################

interval:

Run every 5 seconds

  • interval: 5sec
    then:
    decide which sensor % by choosing largest value
    • if:
      condition:
      lambda: ‘return id(mq8_percent_on) > id(bme688_percent_on);’
      then:
      - lambda: |-
      id(fan_percent_on) = id(mq8_percent_on);
      else:
      - lambda: |-
      id(fan_percent_on) = id(bme688_percent_on);
    • lambda: |-
      id(solar_battery_fan).speed = id(fan_percent_on);
    • mqtt.publish_json:
      topic: esphome/sbf/spd_upd
      payload: |-
      root[“fan_percent_on_set”] = id(fan_percent_on);

################# END OF INTERVAL ############################

################# END OF PROGRAM #############################
‘’’


The compile Log *********************


‘’’
Processing solar-battery-fan (board: esp32doit-devkit-v1; framework: arduino; platform: platformio/espressif32 @ 3.5.0)

HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
LDF: Library Dependency Finder → Library Dependency Finder (LDF) — PlatformIO latest documentation
Library Manager: Installing boschsensortec/BSEC Software Library @ 1.6.1480
Warning! Please upgrade to the PlatformIO Core 6
Dependency Graph
|-- 1.2.2
|-- 1.0
|-- 1.0
|-- 1.0
|-- 2.1.0
| |-- 1.2.2
|-- 1.1.0
|-- 1.0
|-- 0.8.6
| |-- 1.2.2
|-- 1.0.1
|-- 6.18.5
|-- 1.0
Compiling /data/solar-battery-fan/.pioenvs/solar-battery-fan/src/bsec.cpp.o
Compiling /data/solar-battery-fan/.pioenvs/solar-battery-fan/src/esphome/components/adc/adc_sensor.cpp.o
Compiling /data/solar-battery-fan/.pioenvs/solar-battery-fan/src/esphome/components/binary_sensor/automation.cpp.o
Compiling /data/solar-battery-fan/.pioenvs/solar-battery-fan/src/esphome/components/binary_sensor/binary_sensor.cpp.o
Compiling /data/solar-battery-fan/.pioenvs/solar-battery-fan/src/esphome/components/binary_sensor/filter.cpp.o
In file included from src/bsec.cpp:39:0:
src/bsec.h:46:32: fatal error: inc/bsec_datatypes.h: No such file or directory
#include “inc/bsec_datatypes.h”
^
compilation terminated.
*** [/data/solar-battery-fan/.pioenvs/solar-battery-fan/src/bsec.cpp.o] Error 1
Compiling /data/solar-battery-fan/.pioenvs/solar-battery-fan/src/esphome/components/bme680_bsec/bme680_bsec.cpp.o
In file included from src/esphome/components/bme680_bsec/bme680_bsec.h:12:0,
from src/esphome/components/bme680_bsec/bme680_bsec.cpp:1:
src/bsec.h:46:32: fatal error: inc/bsec_datatypes.h: No such file or directory
#include “inc/bsec_datatypes.h”
^
compilation terminated.
*** [/data/solar-battery-fan/.pioenvs/solar-battery-fan/src/esphome/components/bme680_bsec/bme680_bsec.cpp.o] Error 1
========================== [FAILED] Took 4.98 seconds ====================
‘’’
I hope this is what people need to understand my problem. As others have said, the bme680_bsec component is built-in and this should not occur.
Any suggestions are greatly apreciated.

Thank you, Doug

DAMN! I just looked at my above post. I lost all indents. I did a “control-a” on my notepad++ and pasted it here between ‘’’ and ‘’’. That did not work as I expected.
But, this problem would not likely be an indent problem. The file “validates” and the whole program worked with the vanilla “bme680” component. It appear the compile can not find a required file from inside the bsec.h file. Interesting it has the C and H top level file but not the dependency file.
Again, thanks for looking and any advise. Doug

Hi Doug,

you have to use three backtic’s ``` to format the yaml code. (On my screen it looks you used both back and forward tics). Now it is almost impossible to read your code, not only because the missing idents. Normally I copy the yaml-file and try to compile it in my own environment to see if I have the same problems, but that’s not possible now.

If I look at the logfile I see both the bsec.ccp and the bme680_bsec.cpp code is compiled. If I look at my own logfile, I only see the bme680_bsec.cpp is compiled. You said you first used the bsec component en later switched to bme680_bsec component. So it looks like some old stuff was not cleared out. You also said that you already cleaned the build files, normally this solves the problem. Maybe you could try it once again.

What you also can do, is create a new yaml file with different name (and a different device name to be sure) and compile that new file. Then you are sure a new build environment for this file is created and see if this will solve the problem. Can you also tell us which version of ESPHome you are using.

3 Likes

Thank you Jos,
I see now I did not use backtic’s.
Interesting, I did not see that it compiled both bsec.cpp and bme680_bsec.cpp. But what previously worked was bme680.ccp (not bsec.cpp).
I like your idea of creating anew yaml with a different name. I will do that. If it does not work, it will at least be interesting to see the compile log of that one.
BTW, I used ‘Terminal’ to look for the directories I see in the compile log starting with /src. Do you know where those are? I was warned the build directory files are overwritten for each compile. So where does the ‘platformoi.ini’ file reside that si not overwritten? I got an error message saying I can fix the error by putting a code into the ENV libs area. But where is that?

anyway let me try providing the yaml file again:

###############################################################################
## solar_battery_fan.yaml for PWM fan control for solar 48vdc battery box to
## vent hydrogen. created 06/22/2023 by Doug Basberg
####################
## A 120mm PWM fan will vent hydrogen from battery charging to 2" PVC  pipe to 
## outdoor vent.
##  Two gas sensors (BME688 and MQ-8) will provide date to ESP32 to decide how 
##  much hydrogen is accumulating in the battery box.  
##  The fan speed will be controlled by PWM from the ESP32 based on gas values.
#############
## gas sensor MQ-8 is hydrogen specific and creates an analog value for quantity 
## of hydrogen which is read on gpio32 and digtal out goes to gpio33.
## gas sensor BME688 uses I2C to report temperatue, humidity, Pressure, and gas 
## resistance.
##  ESP32 reads gas sensors and controls fan PWM and reports operation to HA.
###############################################################################
#
#####################################################
## 06/22/2023 DSB -- start development of project
## 06/26/2023 DSB -- add PWM code - later check for correct values
## 06/27/2023 DSB -- further code development
## 06/28/2023 DSB -- eliminating compile errors in HA environment
##b06/30/2023 DSB -- decided to use MQTT because 'api' is not well documented.
##########################################
## 06/30/2023 DSB -- move to Notepad++ for initial code entry and return to
##    HA esphome later for testing and further development.
###### working in Obsidian on initial coding  ##############
## 10/21/23 DSB -- After bench testing, fan added to ESP2 board - upped fan limit
##   to 95% and min to 30% - ready to mount in battery box for power & gas cal
##
## 10/23/23 DSB - add MQTT_subscribe of manual fan speed - add 'on-values' to 
##    automate 'auto fan control' by gas sensors
## 10/24/23 DSB - more debug editing.
## 10/25/23 DSB - addingscripts failed!- add 'interval' component
## 10/26/23 DSB - continue development - decision about which sensor for fan
##   speed (%) & coversion to (%) - added " BME680_bsec "
##
##################################################################################
##
substitutions:
  device_name: solar-battery-fan
  friendly_name: solar-battery-fan
  ip_address: !secret solar_fan_ip_address
  broker_ip: !secret broker_ip
  
  ### assign I/O pins
  mq_8a_pin: "32"
  mq_8d_pin: "33"
  sda_1_pin: "21"
  scl_1_pin: "22"
  tach_pin: "13"
  pwm_out_pin: "14"
  
  ### define constants
  bme688_gas_resistance_min: "6000"   # high fan needed below this value
  mq_8_gas_min: "5000"                # high fan needed below this value 
  h2_max_volt: "2.00"       # MQ-8 voltage for max fan
  h2_lo_volt: "0.60"        # MQ-8 voltage for min fan
  
########################################################
## GLOBALS
########################################################
#
globals:

###     FAN variables         ###

  - id: auto_mode     # fan mode
    type: bool
    restore_value: no
    initial_value: 'true'
    
  - id: mq8_percent_on  # value from MQ8 H2 sensor routine
    type: float
    restore_value: no
    initial_value: '100'
    
  - id: bme688_percent_on # value from bme688 sensor routine
    type: float
    restore_value: no
    initial_value: '100'
    
  - id: fan_percent_on  # current fan percent ON
    type: float
    restore_value: no
    initial_value: '100'
    
  - id: target_speed   # RPM
    type: float
    restore_value: no
    initial_value: '0'
  
  - id: fan_tach        # RPM
    type: float
    restore_value: no
    initial_value: '0'


#################  END OF GLOBALS  #####################


esphome:
  name: ${friendly_name}
  
esp32:
  board: esp32doit-devkit-v1
  framework:
    type: arduino
    version: recommended
  
logger:
  level: DEBUG
  
####### Using MQTT instead  #####  
#api:


ota:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: ${ip_address}
    gateway: !secret wifi_gateway
    subnet: !secret wifi_subnet
    
  # enable fallback hotspot
  ap:
    ssid: "solar_fan_hotspot"
    password: "Aa234567@"

#############################    
web_server:
  port: 80
#############################

captive_portal:

###########################################
### MQTT setup
###########################################
#
mqtt:
  broker: ${broker_ip}
  username: has
  password: !secret mqtt_pw
  topic_prefix: !secret solar_battery_fan_prefix
  log_topic: !secret solar_battery_fan_log
  
#######################################################



#######################
## I2C bus A
#######################
#
i2c:
  sda: $sda_1_pin
  scl: $scl_1_pin
  id: i2c_a
  scan: true
  # change from 100kHz
  frequency: 10khz
  
  
###########################################################
######### BME688 SENSOR  with BSEC routines   ############
###########################################################
bme680_bsec:
  id: bme688_bsec
  address: 0x76   # could be 0x77
  temperature_offset: 0
  iaq_mode: static
  sample_rate: ulp  # ulp = 5min & lp = 3sec
  state_save_interval: 24h    #efault si 6h
  
##########################################################



###########################################################
## Binary Sensors
###########################################################
#
binary_sensor:

  ## MQ-8 hydrogen sensor digital out
  - platform: gpio 
    id: h2_above_limit
    name: "H2 above limit"
    pin: 
      number: $mq_8d_pin
      inverted: false
      mode:
        input: true
      

###########################################################
## Sensors
###########################################################
#
sensor:

### Debug Counters to watch operation from HA
  - platform: template
    name: debug_one
    id: debug_one
    update_interval: never
    
  - platform: template
    name: debug_two
    id: debug_two
    update_interval: never

### read manual speed (float 0-100) from HA
  - platform: mqtt_subscribe
    name: manual_speed
    topic: esphome/sbf/speed
    id: manual_speed
    on_value:
      then:
        - if:
            condition:
              lambda: 'return id(auto_mode) == false;'
            then:
              - lambda: |-
                  id(fan_percent_on) = id(manual_speed).state;

        -  sensor.template.publish:
            id: debug_one
            state: !lambda 'return id(manual_speed).state;'
  ##################################################
  ####  MQ-8 hydrogen gas sensor analog voltage  ###
  ##################################################
  #
  - platform: adc
    pin: $mq_8a_pin
    attenuation: auto
    id: battery_gas_voltage
    name: "battery_gas_voltage"
    update_interval: 60s
    on_value:
      then:
        - lambda: |-
            id(mq8_percent_on) = 70.0;
        - if:
            condition:
              lambda: 'return id(battery_gas_voltage).state > ${h2_max_volt};'
            then:
              - lambda: |-
                  id(mq8_percent_on) = 95.0;
        - if:
            condition:
              lambda: 'return id(battery_gas_voltage).state < ${h2_lo_volt};' 
            then:
              - lambda: |-
                  id(mq8_percent_on) = 30.0;
        - sensor.template.publish:
            id: debug_two
            state: !lambda 'return id(mq8_percent_on);'
###############################################################            


  ## Send WiFi signal strength & uptime to HA
  - platform: wifi_signal
    name: $friendly_name WiFi Strength
    update_interval: 60s
  - platform: uptime
    name: $friendly_name Uptime
    id: uptime_sensor
    update_interval: 60s
    
  ## Read Fan tacho PIN and show measureed RPM as a sensor
  - platform: pulse_counter
    name: solar_fan_rpm
    pin:
      number: $tach_pin
      mode: INPUT_PULLUP
    unit_of_measurement: 'RPM'
    id: solar_fan_rpm
    accuracy_decimals: 0
    filters:
      - multiply: 0.5   # for two pulses per rev (maybe 1?)
      
#######################################################################
################  BME688 SENSORS   #####################################
#######################################################################
### Using BSEC routine ###
#

  ## BME688 sensor - T, H, P, gas (but only bme680 routine available)
  - platform: bme680_bsec
    bme680_bsec_id: bme688_bsec
  
    temperature:
      name: $friendly_name Temperature
      id: batt_box_temperature
      sample_rate: lp
      filters:
        - median
      
    humidity:
      name: $friendly_name Humidity
      id: batt_box_humidity
      sample_rate: lp
      filters: 
        - median
      
    pressure:
      name: $friendly_name Pressure
      id: batt_box_pressure
      sample_rate: lp
      filters:
        - median
    
    gas_resistance:   # in ohms
      name: $friendly_name Gas Resistance
      id: batt_box_gas_resistance
      filters:
        - median
        
    iaq:    
      # indoor air quality
      name: "BME688 IAQ"
      filters:
        - median
    iaq_accuracy:
      # IAQ accuracy as a numeric value of 0, 1, 2, 3
      name: "BME688 Numeric IAQ Accuracy"
    co2_equivalent:
      # CO2 equivalent in ppm
      name: "BME688 CO2 Equivalent"
      filters:
        - median
    breath_voc_equivalent:
      # Volatile Organic Compounds equivalent in ppm
      name: "BME688 Breath VOC Equivalent"
      filters:
        - median
        
################## END OF BME688 SENSORS  ##########
      
      

    
############### END OF SENSORS #####################


########################## TEXT SENSORS  ############

text_sensor:

  - platform: bme680_bsec
    iaq_accuracy:
      # IAQ accuracy as a text value of Stabilizing, Uncertain, calibrating, 
      #   or Calibrating
      name: "BME688 IAQ Accuracy"
      

  # Send IP Address
  - platform: wifi_info
    ip_address:
      name: $friendly_name IP Address

  # Send Uptime in raw seconds
  - platform: template
    name: $friendly_name Uptime
    id: uptime_human
    icon: mdi:clock-start




################## END OF TEXT SENSORS ###########################
#


    
  
#######################################################################
# Good for debugging, you can manually set the fan 
# speed. Just make sure the Climate device is set to off or it will keep 
# getting overridden.
###############
fan:
  - platform: speed
    id: solar_battery_fan
    output: solar_fan_speed_set
    name: "Solar Battery Fan"
    restore_mode: ALWAYS_ON
    
output:
  # Wire this pin (pwm_out) into the PWM pin of your 12v fan
  # ledc is the name of the pwm output system on an esp32
  - platform: ledc
    id: solar_fan_speed_set
    inverted: false
    pin: $pwm_out_pin
    

    # 25KHz is standard PC fan frequency, minimises buzzing
    frequency: "25000 Hz" 

    # my fans stop working below 30% power.
    # also they're  powerful and loud, cap their max speed to 95%
    min_power: 30%
    max_power: 95%

################################################################
############ SWITCHES   ########################################
################################################################
#
switch:
  # Expose an ESP32 restart button to HA
  - platform: restart
    name: ${friendly_name} ESP32 Restart
    id: solar_fan_restart

###############################################################
##################  TIME   ####################################
###############################################################


time:
  - platform: sntp
    id: sntp_time
    on_time:
    
      # Restart every day at 12:30am. 
      # I've had some memory issues lockup 
      # the device after a couple weeks
      # Every morning at 12:30am
      - seconds: 0
        minutes: 30
        hours: 0
        then:
          - switch.turn_on: solar_fan_restart
          - delay: 10ms
          - switch.turn_off: solar_fan_restart

##############  END OF TIME  ############################


  #######################################################
  ### Run tasks at intervals
  #######################################################
  #
interval:
  # Run every 5 seconds
  - interval: 5sec
    then:
      ##### decide which sensor % by choosing largest value ###
      - if:
          condition:
            lambda: 'return id(mq8_percent_on) > id(bme688_percent_on);'
          then:
            - lambda: |-
                id(fan_percent_on) = id(mq8_percent_on);
          else:
            - lambda: |-
                id(fan_percent_on) = id(bme688_percent_on);
      - lambda: |-
          id(solar_battery_fan).speed = id(fan_percent_on);
      - mqtt.publish_json:
          topic: esphome/sbf/spd_upd
          payload: |-
            root["fan_percent_on_set"] = id(fan_percent_on);

#################   END OF INTERVAL   ############################

#################   END OF PROGRAM   #############################

That is better :sunglasses:

I am using home-assistant/esphome with an ESP32 and I liked Jos comment about trying to buiild a new project with the same code and compiling fresh. I did that with the same result “bsec.h” missing. I include yaml and compile files below. I am at a loss. It is beyond my programming skills. Does anyone have a suggestion? Thanks, Doug

#######################################################
## testing bme680_bsec component for ability to compile
## Doug Basberg 10/31/23
## Edit in Notepad++ to improve fan speed logic.
##
########################################################


##
substitutions:
  device_name: solar-battery-fan
  friendly_name: solar-battery-fan
  ip_address: !secret solar_fan_ip_address
  broker_ip: !secret broker_ip
  
  ### assign I/O pins
  mq_8a_pin: "32"
  mq_8d_pin: "33"
  sda_1_pin: "21"
  scl_1_pin: "22"
  tach_pin: "13"
  pwm_out_pin: "14"
  
  ### define constants
  bme688_gas_resistance_min: "6000"   # high fan needed below this value
  mq_8_gas_min: "5000"                # high fan needed below this value 
  h2_max_volt: "2.00"       # MQ-8 voltage for max fan
  h2_lo_volt: "0.60"        # MQ-8 voltage for min fan
  
########################################################
## GLOBALS
########################################################
#
globals:

###     FAN variables         ###

  - id: auto_mode     # fan mode
    type: bool
    restore_value: no
    initial_value: 'true'
    
  - id: mq8_percent_on  # value from MQ8 H2 sensor routine
    type: float
    restore_value: no
    initial_value: '100'
    
  - id: bme688_percent_on # value from bme688 sensor routine
    type: float
    restore_value: no
    initial_value: '100'
    
  - id: fan_percent_on  # current fan percent ON
    type: float
    restore_value: no
    initial_value: '100'
    
  - id: target_speed   # RPM
    type: float
    restore_value: no
    initial_value: '0'
  
  - id: fan_tach        # RPM
    type: float
    restore_value: no
    initial_value: '0'
    
 
    
  

esphome:
  name: battery-fan-control
#  includes:
#    - bsec.h 

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
#api:

ota:
  password: "bb82e3877ace3b33fba868a6178b8850"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Battery-Fan-Control"
    password: "C5uwAb0Zk1ej"

captive_portal:

web_server:
  port: 80
  
###########################################
### MQTT setup
###########################################
#
mqtt:
  broker: ${broker_ip}
  username: has
  password: !secret mqtt_pw
  topic_prefix: !secret solar_battery_fan_prefix
  log_topic: !secret solar_battery_fan_log
  
#######################################################



#######################
## I2C bus A
#######################
#
i2c:
  sda: $sda_1_pin
  scl: $scl_1_pin
  id: i2c_a
  scan: true
  # change from 100kHz
  frequency: 10khz
  
  
###########################################################
######### BME688 SENSOR  with BSEC routines   ############
###########################################################
bme680_bsec:
  id: bme688_internal
  address: 0x76   # could be 0x77
  temperature_offset: 0
  iaq_mode: static
  sample_rate: ulp  # ulp = 5min & lp = 3sec
  state_save_interval: 24h    #efault si 6h
  
##########################################################



###########################################################
## Binary Sensors
###########################################################
#
binary_sensor:

  ## MQ-8 hydrogen sensor digital out
  - platform: gpio 
    id: h2_above_limit
    name: "H2 above limit"
    pin: 
      number: $mq_8d_pin
      inverted: false
      mode:
        input: true
      

###########################################################
## Sensors
###########################################################
#
sensor:

### Debug Counters to watch operation from HA
  - platform: template
    name: debug_one
    id: debug_one
    update_interval: never
    
  - platform: template
    name: debug_two
    id: debug_two
    update_interval: never

### read manual speed (float 0-100) from HA
  - platform: mqtt_subscribe
    name: manual_speed
    topic: esphome/sbf/speed
    id: manual_speed
    on_value:
      then:
        - if:
            condition:
              lambda: 'return id(auto_mode) == false;'
            then:
              - lambda: |-
                  id(fan_percent_on) = id(manual_speed).state;

        -  sensor.template.publish:
            id: debug_one
            state: !lambda 'return id(manual_speed).state;'
  ##################################################
  ####  MQ-8 hydrogen gas sensor analog voltage  ###
  ##################################################
  #
  - platform: adc
    pin: $mq_8a_pin
    attenuation: auto
    id: battery_gas_voltage
    name: "battery_gas_voltage"
    update_interval: 60s
    on_value:
      then:
        - lambda: |-
            id(mq8_percent_on) = 70.0;
        - if:
            condition:
              lambda: 'return id(battery_gas_voltage).state > ${h2_max_volt};'
            then:
              - lambda: |-
                  id(mq8_percent_on) = 95.0;
        - if:
            condition:
              lambda: 'return id(battery_gas_voltage).state < ${h2_lo_volt};' 
            then:
              - lambda: |-
                  id(mq8_percent_on) = 30.0;
        - sensor.template.publish:
            id: debug_two
            state: !lambda 'return id(mq8_percent_on);'
###############################################################            


  ## Send WiFi signal strength & uptime to HA
  - platform: wifi_signal
    name: $friendly_name WiFi Strength
    update_interval: 60s
  - platform: uptime
    name: $friendly_name Uptime
    id: uptime_sensor
    update_interval: 60s
    
  ## Read Fan tacho PIN and show measureed RPM as a sensor
  - platform: pulse_counter
    name: solar_fan_rpm
    pin:
      number: $tach_pin
      mode: INPUT_PULLUP
    unit_of_measurement: 'RPM'
    id: solar_fan_rpm
    accuracy_decimals: 0
    filters:
      - multiply: 0.5   # for two pulses per rev (maybe 1?)
      
#######################################################################
################  BME688 SENSORS   #####################################
#######################################################################
### Using BSEC routine ###
#

  ## BME688 sensor - T, H, P, gas (but only bme680 routine available)
  - platform: bme680_bsec
    bme680_bsec_id: bme688_internal
  
    temperature:
      name: $friendly_name Temperature
      id: batt_box_temperature
      sample_rate: lp
      filters:
        - median
      
    humidity:
      name: $friendly_name Humidity
      id: batt_box_humidity
      sample_rate: lp
      filters: 
        - median
      
    pressure:
      name: $friendly_name Pressure
      id: batt_box_pressure
      sample_rate: lp
      filters:
        - median
    
    gas_resistance:   # in ohms
      name: $friendly_name Gas Resistance
      id: batt_box_gas_resistance
      filters:
        - median
        
    iaq:    
      # indoor air quality
      name: "BME688 IAQ"
      filters:
        - median
    iaq_accuracy:
      # IAQ accuracy as a numeric value of 0, 1, 2, 3
      name: "BME688 Numeric IAQ Accuracy"
    co2_equivalent:
      # CO2 equivalent in ppm
      name: "BME688 CO2 Equivalent"
      filters:
        - median
    breath_voc_equivalent:
      # Volatile Organic Compounds equivalent in ppm
      name: "BME688 Breath VOC Equivalent"
      filters:
        - median
        
################## END OF BME688 SENSORS  ##########
      
      

    
############### END OF SENSORS #####################


########################## TEXT SENSORS  ############

text_sensor:

  - platform: bme680_bsec
    iaq_accuracy:
      # IAQ accuracy as a text value of Stabilizing, Uncertain, calibrating, 
      #   or Calibrating
      name: "BME688 IAQ Accuracy"
      

  # Send IP Address
  - platform: wifi_info
    ip_address:
      name: $friendly_name IP Address

  # Send Uptime in raw seconds
  - platform: template
    name: $friendly_name Uptime
    id: uptime_human
    icon: mdi:clock-start




################## END OF TEXT SENSORS ###########################
#


    
  
#######################################################################
# Good for debugging, you can manually set the fan 
# speed. Just make sure the Climate device is set to off or it will keep 
# getting overridden.
###############
fan:
  - platform: speed
    id: solar_battery_fan
    output: solar_fan_speed_set
    name: "Solar Battery Fan"
    restore_mode: ALWAYS_ON
    
output:
  # Wire this pin (pwm_out) into the PWM pin of your 12v fan
  # ledc is the name of the pwm output system on an esp32
  - platform: ledc
    id: solar_fan_speed_set
    inverted: false
    pin: $pwm_out_pin
    

    # 25KHz is standard PC fan frequency, minimises buzzing
    frequency: "25000 Hz" 

    # my fans stop working below 30% power.
    # also they're  powerful and loud, cap their max speed to 95%
    min_power: 30%
    max_power: 95%

################################################################
############ SWITCHES   ########################################
################################################################
#
switch:
  # Expose an ESP32 restart button to HA
  - platform: restart
    name: ${friendly_name} ESP32 Restart
    id: solar_fan_restart

###############################################################
##################  TIME   ####################################
###############################################################


time:
  - platform: sntp
    id: sntp_time
    on_time:
    
      # Restart every day at 12:30am. 
      # I've had some memory issues lockup 
      # the device after a couple weeks
      # Every morning at 12:30am
      - seconds: 0
        minutes: 30
        hours: 0
        then:
          - switch.turn_on: solar_fan_restart
          - delay: 10ms
          - switch.turn_off: solar_fan_restart

##############  END OF TIME  ############################


  #######################################################
  ### Run tasks at intervals
  #######################################################
  #
interval:
  # Run every 5 seconds
  - interval: 5sec
    then:
      - if:
          condition:
            lambda: 'return (id(auto_mode == true));'
          then:
          ##### decide which sensor % by choosing largest value ###
            - if:
                condition:
                  lambda: 'return (id(mq8_percent_on) > id(bme688_percent_on))'
                then:
                  - lambda: |-
                      id(fan_percent_on) = id(mq8_percent_on);
                else:
                  - lambda: |-
                      id(fan_percent_on) = id(bme688_percent_on);
            - lambda: |-
                id(solar_battery_fan).speed = id(fan_percent_on);
            - mqtt.publish_json:
                topic: esphome/sbf/spd_upd
                payload: |-
                  root["fan_percent_on_set"] = id(fan_percent_on);

#################   END OF INTERVAL   ############################

#################   END OF PROGRAM   #############################

and the compile showing the error message:

INFO Reading configuration /config/esphome/battery-fan-control.yaml...
INFO Detected timezone 'America/New_York'
INFO Generating C++ source...
INFO Compiling app...
Processing battery-fan-control (board: esp32dev; framework: arduino; platform: platformio/espressif32 @ 3.5.0)
--------------------------------------------------------------------------------
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
Library Manager: Installing boschsensortec/BSEC Software Library @ 1.6.1480
Warning! Please upgrade to the PlatformIO Core 6
Dependency Graph
|-- <AsyncTCP-esphome> 1.2.2
|-- <WiFi> 1.0
|-- <FS> 1.0
|-- <Update> 1.0
|-- <ESPAsyncWebServer-esphome> 2.1.0
|   |-- <AsyncTCP-esphome> 1.2.2
|-- <DNSServer> 1.1.0
|-- <ESPmDNS> 1.0
|-- <AsyncMqttClient-esphome> 0.8.6
|   |-- <AsyncTCP-esphome> 1.2.2
|-- <Wire> 1.0.1
|-- <ArduinoJson> 6.18.5
|-- <SPI> 1.0
Compiling /data/battery-fan-control/.pioenvs/battery-fan-control/src/esphome/components/adc/adc_sensor.cpp.o
Compiling /data/battery-fan-control/.pioenvs/battery-fan-control/src/esphome/components/binary_sensor/automation.cpp.o
Compiling /data/battery-fan-control/.pioenvs/battery-fan-control/src/esphome/components/binary_sensor/binary_sensor.cpp.o
Compiling /data/battery-fan-control/.pioenvs/battery-fan-control/src/esphome/components/binary_sensor/filter.cpp.o
Compiling /data/battery-fan-control/.pioenvs/battery-fan-control/src/esphome/components/bme680_bsec/bme680_bsec.cpp.o
In file included from src/esphome/components/bme680_bsec/bme680_bsec.cpp:1:0:
src/esphome/components/bme680_bsec/bme680_bsec.h:12:18: fatal error: bsec.h: No such file or directory

**************************************************************
* Looking for bsec.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:bsec.h"
* Web  > https://registry.platformio.org/search?q=header:bsec.h
*
**************************************************************

compilation terminated.
*** [/data/battery-fan-control/.pioenvs/battery-fan-control/src/esphome/components/bme680_bsec/bme680_bsec.cpp.o] Error 1
Compiling /data/battery-fan-control/.pioenvs/battery-fan-control/src/esphome/components/captive_portal/captive_portal.cpp.o
========================== [FAILED] Took 7.37 seconds ==========================

I can not find the /data/battery-fan-control directory. Where is that?
Thanks for your consideration and any suggestions, Doug