Czujnik parametrów środowiska BME680 i ESPHome

Do prostych pomiarów stężenia lotnych związków organicznych (de facto to nie pomiar tylko aproksymacja na podstawie innych parametrów) BMP680 jest wręcz ideałem z kilku powodów

  1. Podłączenie przez I²C, więc nie wymaga zasadniczo żadnych układów dodatkowych
    I²C Bus — ESPHome
  2. Rezystancja gazu jest mierzona automatycznie (grzałka też jest sterowana automatycznie, choć można wymusić jej parametry i pracę ręczną)
    BME680 Temperature+Pressure+Humidity+Gas Sensor — ESPHome
  3. Można wykorzystać w powiązaniu z niewolną biblioteką Bosch Sensortec Environmental Cluster (pod linkiem licencja https://www.bosch-sensortec.com/media/boschsensortec/downloads/bsec/2017-07-17_clickthrough_license_terms_environmentalib_sw_clean.pdf którą trzeba zaakceptować przed użyciem biblioteki)
    a wtedy takie wartości jak IAQ, czy ekwiwalenty CO2 i VOC są liczone “automagicznie” :stuck_out_tongue_winking_eye:
    BME680 Temperature+Pressure+Humidity+Gas Sensor via BSEC — ESPHome
2 polubienia

Pozwolę sobie podlinkować alternatywę podłączenia tego czujnika poprzez wgranie jednego pliku Tasmota sensor.bin.

https://tasmota.github.io/docs/BME680/

1 polubienie

W Tasmocie jednak nie da się użyć biblioteki BSEC nie łamiąc przy okazji jej postanowień licencyjnych (wyklucza rozpowszechnianie prekompilowanych plików binarnych).

@szopen jak zwykle racja :+1: więc otwartych drzwi nie ma co wyważać…

Witam Wszystkich :wink: (bo to mój pierwszy post)

Potrzebuje Waszego wsparcia w temacie wykonania WemosD1mini + BME680
Zaczynam dopiero zabawę z ESP Home, dlatego może to mały błąd/brak albo robię to zupełnie nie tak jak trzeba. Całość kodu skopiowałem z:

jednak nie działa mi komunikacja z BME680 :confused:

mój kod:

esphome:
  name: d1-airq-lux
  friendly_name: D1_AIRQ_LUX

esp8266:
  board: d1_mini

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "ft2hVo4w5HRUCGufkL/MmHxfHqMX9wXC8u6WbT4GDWI="

ota:
  - platform: esphome
    password: "de9f86426cc12f747773de278a7f7599"

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "D1-Airq-Lux Fallback Hotspot"
    password: "YqUKGhoKWnJk"

captive_portal:

i2c:
  sda: GPIO4
  scl: GPIO5
  scan: true
  id: bus_a

bme680_bsec:

sensor:
  - platform: bme680_bsec
    temperature:
      name: "BME680 Temperature"
    pressure:
      name: "BME680 Pressure"
    humidity:
      name: "BME680 Humidity"
    iaq:
      name: "BME680 IAQ"
      id: iaq
    co2_equivalent:
      name: "BME680 CO2 Equivalent"
    breath_voc_equivalent:
      name: "BME680 Breath VOC Equivalent"

  - platform: bh1750
    name: "BH1750 Illuminance"
    address: 0x23
    update_interval: 60s

text_sensor:
  - platform: bme680_bsec
    iaq_accuracy:
      name: "BME680 IAQ Accuracy"

  - platform: template
    name: "BME680 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"};
      }

oraz błędy w logu:

INFO Successfully connected to d1-airq-lux @ 192.168.1.181 in 19.729s
INFO Successful handshake with d1-airq-lux @ 192.168.1.181 in 2.629s
[15:36:31][I][app:100]: ESPHome version 2024.9.2 compiled on Oct 20 2024, 15:35:58
[15:36:31][C][wifi:600]: WiFi:
[15:36:31][C][wifi:428]:   Local MAC: CC:7B:5C:4F:AB:DE
[15:36:31][C][wifi:433]:   SSID: [redacted]
[15:36:31][C][wifi:436]:   IP Address: 192.168.1.181
[15:36:31][C][wifi:439]:   BSSID: [redacted]
[15:36:31][C][wifi:441]:   Hostname: 'd1-airq-lux'
[15:36:31][C][wifi:443]:   Signal strength: -72 dB ▂▄▆█
[15:36:31][C][wifi:447]:   Channel: 11
[15:36:31][C][wifi:448]:   Subnet: 255.255.255.0
[15:36:31][C][wifi:449]:   Gateway: 192.168.1.1
[15:36:31][C][wifi:450]:   DNS1: 1.1.1.1
[15:36:31][C][wifi:451]:   DNS2: 8.8.8.8
[15:36:31][C][logger:185]: Logger:
[15:36:31][C][logger:186]:   Level: DEBUG
[15:36:31][C][logger:188]:   Log Baud Rate: 115200
[15:36:31][C][logger:189]:   Hardware UART: UART0
[15:36:31][C][i2c.arduino:071]: I2C Bus:
[15:36:31][C][i2c.arduino:072]:   SDA Pin: GPIO4
[15:36:31][C][i2c.arduino:073]:   SCL Pin: GPIO5
[15:36:31][C][i2c.arduino:074]:   Frequency: 50000 Hz
[15:36:31][C][i2c.arduino:086]:   Recovery: bus successfully recovered
[15:36:31][I][i2c.arduino:096]: Results from i2c bus scan:
[15:36:31][I][i2c.arduino:102]: Found i2c device at address 0x23
[15:36:31][I][i2c.arduino:102]: Found i2c device at address 0x77
[15:36:31][C][template.text_sensor:020]: Template Sensor 'BME680 IAQ Classification'
[15:36:31][C][template.text_sensor:020]:   Icon: 'mdi:checkbox-marked-circle-outline'
[15:36:31][C][bme680_bsec.sensor:148]: bme680_bsec_bme680bseccomponent_id via BSEC:
[15:36:31][C][bme680_bsec.sensor:152]:   BSEC Version: 1.4.8.0
[15:36:31][C][bme680_bsec.sensor:155]:   Address: 0x76
[15:36:31][E][bme680_bsec.sensor:158]: Communication failed (BSEC Status: 0, BME680 Status: -2)
[15:36:31][C][bme680_bsec.sensor:162]:   Temperature Offset: 0.00
[15:36:31][C][bme680_bsec.sensor:163]:   IAQ Mode: Static
[15:36:31][C][bme680_bsec.sensor:164]:   Supply Voltage: 3.3V
[15:36:31][C][bme680_bsec.sensor:165]:   Sample Rate: LP
[15:36:31][C][bme680_bsec.sensor:166]:   State Save Interval: 21600000ms
[15:36:31][C][bme680_bsec.sensor:168]:   Temperature 'BME680 Temperature'
[15:36:31][C][bme680_bsec.sensor:168]:     Device Class: 'temperature'
[15:36:31][C][bme680_bsec.sensor:168]:     State Class: 'measurement'
[15:36:31][C][bme680_bsec.sensor:168]:     Unit of Measurement: '°C'
[15:36:31][C][bme680_bsec.sensor:168]:     Accuracy Decimals: 1
[15:36:31][C][bme680_bsec.sensor:169]:     Sample Rate: Default
[15:36:31][C][bme680_bsec.sensor:170]:   Pressure 'BME680 Pressure'
[15:36:31][C][bme680_bsec.sensor:170]:     Device Class: 'atmospheric_pressure'
[15:36:31][C][bme680_bsec.sensor:170]:     State Class: 'measurement'
[15:36:31][C][bme680_bsec.sensor:170]:     Unit of Measurement: 'hPa'
[15:36:31][C][bme680_bsec.sensor:170]:     Accuracy Decimals: 1
[15:36:31][C][bme680_bsec.sensor:171]:     Sample Rate: Default
[15:36:31][C][bme680_bsec.sensor:172]:   Humidity 'BME680 Humidity'
[15:36:31][C][bme680_bsec.sensor:172]:     Device Class: 'humidity'
[15:36:31][C][bme680_bsec.sensor:172]:     State Class: 'measurement'
[15:36:31][C][bme680_bsec.sensor:172]:     Unit of Measurement: '%'
[15:36:31][C][bme680_bsec.sensor:172]:     Accuracy Decimals: 1
[15:36:31][C][bme680_bsec.sensor:173]:     Sample Rate: Default
[15:36:31][C][bme680_bsec.sensor:175]:   IAQ 'BME680 IAQ'
[15:36:31][C][bme680_bsec.sensor:175]:     State Class: 'measurement'
[15:36:31][C][bme680_bsec.sensor:175]:     Unit of Measurement: 'IAQ'
[15:36:31][C][bme680_bsec.sensor:175]:     Accuracy Decimals: 0
[15:36:31][C][bme680_bsec.sensor:175]:     Icon: 'mdi:gauge'
[15:36:31][C][bme680_bsec.sensor:177]:   IAQ Accuracy 'BME680 IAQ Accuracy'
[15:36:31][C][bme680_bsec.sensor:177]:     Icon: 'mdi:checkbox-marked-circle-outline'
[15:36:31][C][bme680_bsec.sensor:178]:   CO2 Equivalent 'BME680 CO2 Equivalent'
[15:36:31][C][bme680_bsec.sensor:178]:     Device Class: 'carbon_dioxide'
[15:36:31][C][bme680_bsec.sensor:178]:     State Class: 'measurement'
[15:36:31][C][bme680_bsec.sensor:178]:     Unit of Measurement: 'ppm'
[15:36:31][C][bme680_bsec.sensor:178]:     Accuracy Decimals: 1
[15:36:31][C][bme680_bsec.sensor:179]:   Breath VOC Equivalent 'BME680 Breath VOC Equivalent'
[15:36:31][C][bme680_bsec.sensor:179]:     Device Class: 'volatile_organic_compounds_parts'
[15:36:31][C][bme680_bsec.sensor:179]:     State Class: 'measurement'
[15:36:31][C][bme680_bsec.sensor:179]:     Unit of Measurement: 'ppm'
[15:36:31][C][bme680_bsec.sensor:179]:     Accuracy Decimals: 1
[15:36:31][E][component:082]:   Component bme680_bsec is marked FAILED
[15:36:31][C][bh1750.sensor:118]: BH1750 'BH1750 Illuminance'
[15:36:31][C][bh1750.sensor:118]:   Device Class: 'illuminance'
[15:36:31][C][bh1750.sensor:118]:   State Class: 'measurement'
[15:36:31][C][bh1750.sensor:118]:   Unit of Measurement: 'lx'
[15:36:31][C][bh1750.sensor:118]:   Accuracy Decimals: 1
[15:36:31][C][bh1750.sensor:119]:   Address: 0x23
[15:36:31][C][bh1750.sensor:124]:   Update Interval: 60.0s
[15:36:31][C][captive_portal:089]: Captive Portal:
[15:36:31][C][mdns:116]: mDNS:
[15:36:31][C][mdns:117]:   Hostname: d1-airq-lux
[15:36:31][C][esphome.ota:073]: Over-The-Air updates:
[15:36:31][C][esphome.ota:074]:   Address: d1-airq-lux.local:8266
[15:36:31][C][esphome.ota:075]:   Version: 2
[15:36:31][C][esphome.ota:078]:   Password configured
[15:36:31][C][safe_mode:018]: Safe Mode:
[15:36:31][C][safe_mode:019]:   Boot considered successful after 60 seconds
[15:36:31][C][safe_mode:021]:   Invoke after 10 boot attempts
[15:36:31][C][safe_mode:022]:   Remain in safe mode for 300 seconds
[15:36:31][C][api:139]: API Server:
[15:36:31][C][api:140]:   Address: d1-airq-lux.local:6053
[15:36:31][C][api:142]:   Using noise encryption: YES
[15:37:06][D][bh1750.sensor:159]: 'BH1750 Illuminance': Got illuminance=58.3lx
[15:37:06][D][sensor:093]: 'BH1750 Illuminance': Sending state 58.29232 lx with 1 decimals of accuracy
[15:37:12][D][text_sensor:064]: 'BME680 IAQ Classification': Sending state 'Extremely polluted'
[15:37:15][I][safe_mode:041]: Boot seems successful; resetting boot loop counter
[15:38:06][D][bh1750.sensor:159]: 'BH1750 Illuminance': Got illuminance=58.0lx
[15:38:06][D][sensor:093]: 'BH1750 Illuminance': Sending state 57.95275 lx with 1 decimals of accuracy
[15:38:12][D][text_sensor:064]: 'BME680 IAQ Classification': Sending state 'Extremely polluted'
[15:39:06][D][bh1750.sensor:159]: 'BH1750 Illuminance': Got illuminance=57.5lx

dodałem BH1750, to jest ok. id: dla i2c podmieniałem na: i2c_bus_1 ale bez zmian

Zobaczcie proszę co robię źle

W tym logu nie ma błędów, więc nie wiadomo z czym masz problem,
ale jeśli masz tylko jedną magistralę i2c to nie musisz jej deklarować jawnie

więc albo wyrzuć to

albo w każdym wywołaniu komponentu korzystającego z tej jedynej szyny też ją deklaruj jawnie

  i2c_id: bus_a

czyli

i2c:
  sda: GPIO4
  scl: GPIO5
  scan: true
  id: bus_a
[…]
sensor:
  - platform: bme680_bsec
    i2c_id: bus_a
    address: 0x77
[…]

  - platform: bh1750
    name: "BH1750 Illuminance"
    i2c_id: bus_a
    address: 0x23
[…]

edit dobra ten błąd przegapiłem

ale zauważ, że masz wykryty ten sprzęt na adresie 0x77 a w swoim YAMLu nawet go nie zdeklarowałeś, a w dodatku nie jest to adres domyślny dla BME680

Hej, dzięki za rzucenie okiem. Wywalam id: bus_a
Problem ze zdeklarowaniem jest taki że dla -platform: bme680_bsec widzi błąd

[address] is an invalid option for [sensor.bme680_bsec]. Please check the indentation.

wykrywa mi BME680 na adresie 0x77 co niby nie jest błędem ( Configuration variables:

  • address (Optional, int): Manually specify the I²C address of the sensor. Defaults to 0x76. Another address can be 0x77.)

ale w logach widać:

[15:36:31][C][bme680_bsec.sensor:152]:   BSEC Version: 1.4.8.0
[15:36:31][C][bme680_bsec.sensor:155]:   Address: 0x76

:star_struck: id: bus_a wywaliłem, dodałem deklaracje adresu 0x77 i… chyba działa :slight_smile:

kod wyglada obecnie tak:

esphome:
  name: d1-airq-lux
  friendly_name: D1_AIRQ_LUX

esp8266:
  board: d1_mini

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "ft2hVo4w5HRUCGufkL/MmHxfHqMX9wXC8u6WbT4GDWI="

ota:
  - platform: esphome
    password: "de9f86426cc12f747773de278a7f7599"

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "D1-Airq-Lux Fallback Hotspot"
    password: "YqUKGhoKWnJk"

captive_portal:

i2c:
  sda: GPIO4
  scl: GPIO5
  scan: true
  

bme680_bsec:
 address: 0x77

sensor:
  - platform: bme680_bsec  
    temperature:
      name: "BME680 Temperature"
    pressure:
      name: "BME680 Pressure"
    humidity:
      name: "BME680 Humidity"
    iaq:
      name: "BME680 IAQ"
      id: iaq
    co2_equivalent:
      name: "BME680 CO2 Equivalent"
    breath_voc_equivalent:
      name: "BME680 Breath VOC Equivalent"
    
 

  - platform: bme680
    address: 0x77
    temperature:
      name: "BME680 Temperature"
      oversampling: 16x
    pressure:
      name: "BME680 Pressure"
    humidity:
      name: "BME680 Humidity"
      id: "Humidity"
    gas_resistance:
      name: "BME680 Gas Resistance"
      id: "Gas_Resistance"
    update_interval: 30s
  
  - platform: template
    name: "BME680 Indoor Air Quality"
    id: iaq2
    icon: "mdi:gauge"
    # caulculation: comp_gas = log(R_gas[ohm]) + 0.04 log(Ohm)/%rh * hum[%rh]
    lambda: |-
      return log(id(Gas_Resistance).state) + 0.04 *  id(Humidity).state;



  - platform: wifi_signal # Reports the WiFi signal strength/RSSI in dB
    name: "WiFi Signal dB"
    id: wifi_signal_db
    update_interval: 60s
    entity_category: "diagnostic"

  - platform: copy # Reports the WiFi signal strength in %
    source_id: wifi_signal_db
    name: "WiFi Signal"
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "%"
    entity_category: "diagnostic"
    device_class: ""


text_sensor:
  - platform: bme680_bsec
    iaq_accuracy:
      name: "BME680 IAQ Accuracy"

  - platform: template
    name: "BME680 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"};
      }   


  - platform: wifi_info
    ip_address:
      name: "IP Adres"
    ssid:
      name: "Połączony z siecią"
    mac_address:
      name: "Mac Adres WiFi"

Bardzo dziękuje ! !

Parę słów komentarza.

  1. Miałeś przez chwilę błąd

zwróć uwagę na Please check the indentation. - czyli błędne wcięcia w YAML
Obecny edytor W IDE ESPHome ma już znakomite ułatwienie - pokazuje głębokość wcięć pionowymi liniami, trzeba z tego korzystać, bo ilość spacji we wcięciach YAMLa jest najważniejsza (kluczowym znakiem sterującym YAMLa są spacje!!).

Adres 0x77 nie jest błędem, bo zależy on od konfiguracji sprzętu (większość sprzętu i2c można konfigurować do użycia dowolnego z jakiejś puli adresów, dla BMP680 akurat są możliwe tylko 2 różne adresy), akurat pewnie dysponujesz tak skonstruowaną płytka prototypową tego sensora.
Adres deklarowany w sposób jawny można pominąć tylko w jednym wypadku - gdy jest to adres domyślny danego komponentu sprzętowego i w ogóle jego implementacja to dopuszcza.
Natomiast w ogóle właściwą praktyką jest zawsze jawne deklarowanie faktycznych adresów i2c (nawet gdy są to adresy domyślne).

i ostatnia kwestia - w paru postach miałem trochę do naprawiania (i widzę, że w ogóle miałeś posty poprawiane też przez innych) - zawsze na githubie, na tym forum oraz innych na engine Discourse stosuj formatowanie tekstu jako kod tam gdzie to niezbędne, krótki samouczek jak to robić poprawnie jest tam
https://forum.arturhome.pl/t/jak-prawidlowo-zamieszczac-yaml-inny-kod-lub-logi-w-postach-na-forum/11455