Noch mal ein CO² Beispiel – diesmal mit ESP32 und ESPHome
TLDR
ESP32 zusammen mit SCD41, BME280 und LEDs zu Signalisierung.
Der Sensorwert wird über HTTP in eine Homematic Systemvariable geschrieben.
Kosten ca. 70€
Vorteil: extrem einfach aufzubauen und MQTT / Webserver mit dabei.
Nachteil:
- Batteriebetrieb ist so nicht realistisch - USB Stromversorgung notwendig.
- keine Direktverknüpfung wie mit AskSin++ möglich.
Details
Nachdem mir der HmIP-SCTH230 nicht wirklich zusagt und ich auch nicht wüsste, wo ich ihn installieren sollte, habe ich für mich nach einer Alternative gesucht.
Als Sensor verwende ich den relativ neuen SCD41 von Sensiron (https://www.sensirion.com/fileadmin/use ... asheet.pdf). Der Sensor ist ziemlich klein, recht genau (: ±(40 ppm + 5 %) und hat bereits Temperatur und Luftfeuchtigkeit Kompensation an Board.
Im Gegensatz zu vielen anderen CO² Sensoren wird beim SCD4x "Photoacoustic sensing" statt NDIR verwendet und damit kann der Sensor sehr klein ausfallen. Wer mehr wissen möchte kann hier starten : https://www.sensirion.com/en/about-us/c ... echnology/
Lieferbar war nur das „Evaluation Kit SEK-SCD41“ für ca €55. Kein Schnäppchen allerdings kostet der nackte Sensor auch nur ein paar Euro weniger.
Als Protocol wird I²C benutzt.
Zusätzlich kann noch der Luftdruck von einem externen Sensor zur Erhöhung der Genauigkeit verwendet werden. Ich habe dafür einen BME 280 genommen – einfach deswegen, weil ich davon einige in meiner Bastelkiste habe.
Zur Visualisierung werden 6 LEDs angesteuert.
Statt den Code selbst zu schreiben, kommt ESPHome zum Einsatz. Meiner Meinung nach ist ESPHome eines der besten Frameworks für ESPxxx. Die Konfiguration wird in YAML definiert und daraus wird dann C++ generiert der mit Platform IO kompiliert wird. Im Gegensatz zu z.b. Tasmota ist deswegen nur der Code im Image der benötigt wird.
Natürlich könnte man auch CuxD oder ccuJack verwenden, aber für meine Zwecke reicht eine Systemvariable aus.
Aufbau:
ESP32-Dev Kit
PIN 21 zu SCD41 und BME280 SCL PIN
PIN 22 zu SCD41 und BME280 SDA PIN
PINS 18, 19, 23,25,26,32 jeweils zu 220K Widerstand und LED
Die BME280 Platine enthält bereits Pullup Widerstände. Ansonsten sollte man noch ca 15k Pullup für SDA und SCl verwenden.
Und so sieht mein „professionelles“ Design aus
Software
In Homematic muss einen Systemvariable vom Typ Zahl angelegt werden – damit ist auf der Homematic Seite alles erledigt.
Der große Vorteil von ESPHHome für mich ist, dass der Sensor so auch direkt in Home Assistent oder MQTT verwendet werden kann.
Die Luftdruck Kompensierung wird über das Attribut ambient_pressure_compensation_source: definiert. Hier wird der Sensor angegeben, der die aktuelle Luftdruckwerte an den SCD4x liefert
(Die Möglichkeit einen externen Sensor zu verwenden ist aktuell noch nicht offiziell implementiert – allerdings sollte https://github.com/esphome/esphome/pull/2493 demnächst durchgehen)
Mein eigener Code beschränkt sich auf die on_value Aktion für den CO² Sensor.
Je nach CO² Level werden die LEDs angesteuert und dann ein HTTP Request an die CCU geschickt um die Systemvariable zu aktualisieren. Dafür müssen nur die beiden Attribute hm_host und und hm_sysvar angepasst werden.
Die generierte URL sieht dann in etwa so aus:
Code: Alles auswählen
http://192.168.1.58:8181/any.exe?x=dom.GetObject("scd41-co2").State(630)
Wer weder MQTT noch Home Assitant im Einsatz hat kann „mqtt:“ und „api:“ enfernen.
Mit „web:“ wird ein einfacher Webserver auf Port bereitgestellt
So sieht die ESPHome Konfiguration aus
Code: Alles auswählen
substitutions:
updates: 30s
devicename: co2-sensor
hm_host: 192.168.1.58
hm_sysvar_co2: scd41-co2
esphome:
name: ${devicename}
esp32:
board: esp32dev
framework:
type: arduino
wifi:
ssid: !secret wifi_sid
password: !secret wifi_password
time:
- platform: sntp
id: sntp_time
timezone: "CET-1CEST,M3.5.0,M10.5.0/3"
servers: "de.pool.ntp.org"
# Enable logging
logger:
level: DEBUG
## Optional
api:
password: !secret api_password
reboot_timeout: 0s
ota:
password: !secret ota_password
## Optional
mqtt:
broker: 192.168.1.114
i2c:
- id: bus_a
sda: 21
scl: 22
scan: True
http_request:
useragent: esphome/device
id: httpget
timeout: 10s
sensor:
- platform: scd4x
id: scd41
i2c_id: bus_a
altitude_compensation: 418m
co2:
name: co2
id: co2
on_value:
then:
- lambda: |-
if (x > 400 ) id(led_g1).turn_on() ; else id(led_g1).turn_off();
if (x > 650 ) id(led_g2).turn_on() ; else id(led_g2).turn_off();
if (x > 800 ) id(led_y1).turn_on() ; else id(led_y1).turn_off();
if (x > 1050 ) id(led_y2).turn_on() ; else id(led_y2).turn_off();
if (x > 1300 ) id(led_r1).turn_on() ; else id(led_r1).turn_off();
if (x > 1550 ) id(led_r2).turn_on() ; else id(led_r2).turn_off();
- http_request.get:
url: !lambda |-
return ((std::string) "http://${hm_host}:8181/any.exe?x=dom.GetObject('${hm_sysvar_co2}').State(" + esphome::to_string(static_cast<uint16_t>(x)) + ")" );
humidity:
name: "Luftfeuchtigkeit"
id: humidity
temperature:
name: "Raumtemperatur"
id: temperature
ambient_pressure_compensation_source: bme280_pressure
update_interval: ${updates}
- platform: bme280
setup_priority: -15
temperature:
name: "BME280-Temperature"
id: bme280_temperature
oversampling: 1x
pressure:
name: "BME280-Pressure"
id: bme280_pressure
oversampling: 1x
humidity:
name: "BME280-Humidity"
id: bme280_humidity
oversampling: 1x
address: 0x76
update_interval: ${updates}
- platform: wifi_signal
name: "WiFi Signal"
id: wifisignal
update_interval: ${updates}
output:
- platform: gpio
pin: 23
id: led_g1
- platform: gpio
pin: 19
id: led_g2
- platform: gpio
pin: 18
id: led_y1
- platform: gpio
pin: 32
id: led_y2
- platform: gpio
pin: 25
id: led_r1
- platform: gpio
pin: 26
id: led_r2
# Example configuration entry
switch:
- platform: restart
name: "CO² Sensor Restart"
web_server:
port:80
Jetzt muss man das ganz nur noch kompilieren und hochladen.
Beim ersten mal über die USB-COM Schnittstelle und ab dann kann auch direkt über das Netz aktualisiert werden.
Code: Alles auswählen
esphome run ..\test\co2-sensor.yaml
In Homematic sieht es dann so aus
Und in Home Assitant:
Erweiterungen
Sobald der bestellte BME688 eintrifft werde ich ihn statt dem BME280 einbauen um auch noch VOC Werte zu erhalten.
Die etwas krude Signalsierung mit den LEDs ist auch nicht wirklich der Hit . Ich bin noch am überlegen, was ich stattdessen verwenden könnte. ESPHome bietet da einige Optionen https://esphome.io/index.html#display-components
Dann muss ich mir noch über ein Gehäuse Gedanken machen und zumindest von Breadboard zu Lochraster wechseln.
Batteriebetrieb ist mit diesem Setup nicht wirklich eine Option, weil der ESP32 und die LEDs dafür zuviel Strom ziehen.
Wenn man allerdings die LEDs weglässt und statt dem ESP32-DevKitC ein Board mit niedrigerem Verbrauch verwendet (z.b. TinyPico) wäre zusammen mit deep-sleep Batteriebetrieb denkbar.
Viel Spaß falls es jemand nachbauen möchte