D1 Mini + BME680 using MQTT get data to HA

Hello everyone!

I kindly ask your help to see if i get to meet my goal.
Long story short i have some strange swings in my house on air quality; i did the Ikea air quality sensor + bme680 hack and seems to be working quite well.
Then it is exposing significant changes in air and gas readings on some rooms and so i bought some more Wemos D1 Mini + BME680 and am trying to use the BSEC library to feed HA with all the nice details and calculations the Bosch library makes rather than just using D1+Tasmota+BME680.

Now after a long time - as i am not coder or used to these things but i do all i can alone - i managed to have all working correctly; my setup is:

D1 Mini ESP8266
BME680
BSEC
ESP8266 WIfi connection
Arduino MQTT client
ArduinoJson

All works fine, wifi connects, mqtt connects, mqtt sends mesasges and i see them in HA.

Here is what gets to HA mosquito:

Message 751 received on vibme680/sensors at 10:15 AM:
Timestamp [ms]: 375368, Raw Temperature [°C]: 22.13, Pressure [hPa]: 98953.00, Raw relative humidity [%]: 54.93, Gas [Ohm]: 55860.00, IAQ: 26.43, IAQ accuracy: 1, Temperature [°C]: 22.07, Relative humidity [%]: 55.13, Static IAQ: 25.63, CO2 equivalent: 5

So now this is where i kindly ask your support:
Asa you can see i do not know how to format the message in JSON as it would be ideal, i did a lot of tries but just dont get to do it correctly.

Is there a way to get the values in this format and create a sensor in HA for each of the values?
If formatting to JSON is mandatory anyone has a good guide on how to do it?
A guide that a non coder like me could really understand?

Thanks in advance for your time and help.

My config:
---------------------------------------------------------------------------------------------
#include "bsec.h"
#include <ESP8266WiFi.h>
#include <ArduinoMqttClient.h>
#include <ArduinoJson.h>

// WIFI
char ssid[] = "dontknow";                    
char pass[] = "dontcare";

// Helper functions declarations
void checkIaqSensorStatus(void);
void errLeds(void);

WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

const char broker[] = "noidea";
int        port     = 1883;
const char topic[]  = "vibme680/sensors";
const long interval = 1000;
unsigned long previousMillis = 0;
int count = 0;

// Create an object of the class Bsec
Bsec iaqSensor;

String output;

// Entry point for the example
void setup(void)
{
  Serial.begin(115200);
  Wire.begin(0, 2);
  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("INFO: WiFi connected");
  Serial.println("INFO: IP address: ");
  Serial.println(WiFi.localIP());

  mqttClient.setUsernamePassword("dontremember", "dontremember");
  Serial.print("Attempting to connect to the MQTT broker: ");
  Serial.println(broker);
  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());
    while (1);
  }
  Serial.println("You're connected to the MQTT broker!");
  Serial.println();

  iaqSensor.begin(BME680_I2C_ADDR_PRIMARY, Wire);
  output = "\nBSEC library version " + String(iaqSensor.version.major) + "." + String(iaqSensor.version.minor) + "." + String(iaqSensor.version.major_bugfix) + "." + String(iaqSensor.version.minor_bugfix);
  Serial.println(output);
  checkIaqSensorStatus();

  bsec_virtual_sensor_t sensorList[10] =
  {
    BSEC_OUTPUT_RAW_TEMPERATURE,
    BSEC_OUTPUT_RAW_PRESSURE,
    BSEC_OUTPUT_RAW_HUMIDITY,
    BSEC_OUTPUT_RAW_GAS,
    BSEC_OUTPUT_IAQ,
    BSEC_OUTPUT_STATIC_IAQ,
    BSEC_OUTPUT_CO2_EQUIVALENT,
    BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
    BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
    BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
  };

  iaqSensor.updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP);
  checkIaqSensorStatus();

// Print the header
  output = "Timestamp [ms], raw temperature [°C], pressure [hPa], raw relative humidity [%], gas [Ohm], IAQ, IAQ accuracy, temperature [°C], relative humidity [%], Static IAQ, CO2 equivalent, breath VOC equivalent";
  Serial.println(output);
}

// Function that is looped forever
void loop(void)
{
  mqttClient.poll();

  unsigned long time_trigger = millis();
  if (iaqSensor.run()) { // If new data is available
    output = "Timestamp [ms]: " + String(time_trigger) + ", ";
    output += "Raw Temperature [°C]: " + String(iaqSensor.rawTemperature) + ", ";
    output += "Pressure [hPa]: " + String(iaqSensor.pressure) + ", ";
    output += "Raw relative humidity [%]: " + String(iaqSensor.rawHumidity) + ", ";
    output += "Gas [Ohm]: " + String(iaqSensor.gasResistance) + ", ";
    output += "IAQ: " + String(iaqSensor.iaq) + ", ";
    output += "IAQ accuracy: " + String(iaqSensor.iaqAccuracy) + ", ";
    output += "Temperature [°C]: " + String(iaqSensor.temperature) + ", ";
    output += "Relative humidity [%]: " + String(iaqSensor.humidity) + ", ";
    output += "Static IAQ: " + String(iaqSensor.staticIaq) + ", ";
    output += "CO2 equivalent: " + String(iaqSensor.co2Equivalent) + ", ";
    output += "Breath VOC equivalent: " + String(iaqSensor.breathVocEquivalent) + ", ";
    Serial.println(output);

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time a message was sent
    previousMillis = currentMillis;

    //Serial.print("Sending message to topic: ");
    //Serial.println(topic);
    //Serial.println(output);
    // send message
    mqttClient.beginMessage(topic);
    mqttClient.println(output);
    mqttClient.endMessage();
    Serial.println();

    count++;
  }

//      Serial.print("Pressure: ");
//      Serial.print(iaqSensor.pressure);
//      Serial.println(" Pa");
//
//      Serial.print("Temperature: ");
//      Serial.print(iaqSensor.temperature);
//      Serial.println(" *C");
//
//      Serial.print("Humidity: ");
//      Serial.print(iaqSensor.humidity);
//      Serial.println(" %");
//
//      Serial.print("IAQ: ");
//      Serial.print(iaqSensor.iaq);
//      Serial.println(" PPM");
//
//      Serial.print("CO2 Equivalent: ");
//      Serial.print(iaqSensor.co2Equivalent);
//      Serial.println(" PPM");
//
//      Serial.print("Breath VOC Equivalent: ");
//      Serial.print(iaqSensor.breathVocEquivalent);
//      Serial.println(" PPM");
//      Serial.println();

  } 
  else
  {
    checkIaqSensorStatus();
  }
}

// Helper function definitions
void checkIaqSensorStatus(void)
{
  if (iaqSensor.status != BSEC_OK)
  {
    if (iaqSensor.status < BSEC_OK)
  {
      output = "BSEC error code : " + String(iaqSensor.status);
      Serial.println(output);
    for (;;)
      errLeds(); /* Halt in case of failure */
    }
    else
    {
      output = "BSEC warning code : " + String(iaqSensor.status);
      Serial.println(output);
    }
  }

  if (iaqSensor.bme680Status != BME680_OK)
  {
    if (iaqSensor.bme680Status < BME680_OK)
    {
      output = "BME680 error code : " + String(iaqSensor.bme680Status);
      Serial.println(output);
      for (;;)
        errLeds(); /* Halt in case of failure */
    }
    else
    {
      output = "BME680 warning code : " + String(iaqSensor.bme680Status);
      Serial.println(output);
    }
  }
}

void errLeds(void)
{
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(100);
  digitalWrite(LED_BUILTIN, LOW);
  delay(100);
}

Now i tried some more things and instead of sending the complete output i put:

     mqttClient.beginMessage(rawtemptopic);
     mqttClient.print("{ \"sensor\" : 1, \"Raw Temperature [°C]\" : ");
     mqttClient.print(iaqSensor.rawTemperature);
     mqttClient.print(" }");
     mqttClient.endMessage();
     delay(1000);

     mqttClient.beginMessage(pressuretopic);
     mqttClient.print("{ \"sensor\" : 2, \"pressure [hPa]\" : ");
     mqttClient.print(iaqSensor.pressure);
     mqttClient.print(" }");
     mqttClient.endMessage();
     delay(1000);

And now i have in mosquito:

Message 647 received on vibme680/sensors/voc at 1:11 PM:

{
    "sensor": 11,
    "Breath VOC equivalent": 0.5
}

But i still think this is not good for creating the sensor in HA or is usable?

Why not use ESPhome . less lines of code, better said no code but yaml.
No need to fiddle with JSON if you really want the results on an mqtt broker besides having them in HA this is also possible.
Have a look at the ESPhome site or simply use google for ESPhome + bme640_bsec to see examples.

Hi there

Does this address the use of Bosch library that provides the output of IAQ and CO2 for example?
-edit- sorry did not correctly read your response…

Going to check it right away.

… but was so prod of my hard work LOL

Thanks for this link.

But Is the same as using the D1 mini with tasmota, it provides the exact same output and in fact is what i use already with the Ikea sensor.

But my fight now is to go further and have the complete output this sensor can provide:

“Timestamp [ms], raw temperature [°C], pressure [hPa], raw relative humidity [%], gas [Ohm], IAQ, IAQ accuracy, temperature [°C], relative humidity [%], Static IAQ, CO2 equivalent, breath VOC equivalent”;

Specially i really want the IAQ and CO2 that the other methods do not provide.

Just too a look at bme680_bsec.cpp in ESPHome and seems to address all i want :slight_smile:
Going to test it right away :slight_smile:

So it´s working perfect with ESPHome, just a note if someone reads this:

USE the advanced config for the sensor in ESPHome :slight_smile: