2022-07-19 15:27:15 +02:00
// force the compiler to show a warning to confirm that this file is included
# warning **** Included USERMOD_BME280 version 2.0 ****
2023-01-12 20:35:34 +01:00
# ifndef WLED_ENABLE_MQTT
# error "This user mod requires MQTT to be enabled."
# endif
2020-12-25 21:17:30 +01:00
# pragma once
# include "wled.h"
# include <Arduino.h>
# include <BME280I2C.h> // BME280 sensor
# include <EnvironmentCalculations.h> // BME280 extended measurements
class UsermodBME280 : public Usermod
{
private :
2022-07-20 14:06:27 +02:00
// NOTE: Do not implement any compile-time variables, anything the user needs to configure
// should be configurable from the Usermod menu using the methods below
// key settings set via usermod menu
2022-11-25 16:45:21 +01:00
uint8_t TemperatureDecimals = 0 ; // Number of decimal places in published temperaure values
uint8_t HumidityDecimals = 0 ; // Number of decimal places in published humidity values
uint8_t PressureDecimals = 0 ; // Number of decimal places in published pressure values
uint16_t TemperatureInterval = 5 ; // Interval to measure temperature (and humidity, dew point if available) in seconds
uint16_t PressureInterval = 300 ; // Interval to measure pressure in seconds
2022-07-20 14:06:27 +02:00
bool PublishAlways = false ; // Publish values even when they have not changed
bool UseCelsius = true ; // Use Celsius for Reporting
bool HomeAssistantDiscovery = false ; // Publish Home Assistant Device Information
2022-11-25 16:45:21 +01:00
bool enabled = true ;
2022-07-20 14:06:27 +02:00
// set the default pins based on the architecture, these get overridden by Usermod menu settings
2022-08-14 13:05:59 +02:00
# ifdef ESP8266
2022-07-20 14:06:27 +02:00
//uint8_t RST_PIN = 16; // Uncoment for Heltec WiFi-Kit-8
# endif
2022-07-21 10:48:37 +02:00
bool initDone = false ;
2020-12-25 21:17:30 +01:00
// BME280 sensor settings
BME280I2C : : Settings settings {
BME280 : : OSR_X16 , // Temperature oversampling x16
BME280 : : OSR_X16 , // Humidity oversampling x16
BME280 : : OSR_X16 , // Pressure oversampling x16
// Defaults
BME280 : : Mode_Forced ,
BME280 : : StandbyTime_1000ms ,
BME280 : : Filter_Off ,
BME280 : : SpiEnable_False ,
BME280I2C : : I2CAddr_0x76 // I2C address. I2C specific. Default 0x76
} ;
BME280I2C bme { settings } ;
2021-04-12 10:31:59 +02:00
uint8_t sensorType ;
2020-12-25 21:17:30 +01:00
// Measurement timers
long timer ;
long lastTemperatureMeasure = 0 ;
long lastPressureMeasure = 0 ;
// Current sensor values
2021-04-12 10:31:59 +02:00
float sensorTemperature ;
float sensorHumidity ;
float sensorHeatIndex ;
float sensorDewPoint ;
float sensorPressure ;
2022-07-20 14:06:27 +02:00
String tempScale ;
2020-12-25 21:17:30 +01:00
// Track previous sensor values
float lastTemperature ;
float lastHumidity ;
float lastHeatIndex ;
float lastDewPoint ;
float lastPressure ;
2022-07-19 15:27:15 +02:00
// MQTT topic strings for publishing Home Assistant discovery topics
bool mqttInitialized = false ;
2022-11-25 16:45:21 +01:00
// strings to reduce flash memory usage (used more than twice)
static const char _name [ ] ;
static const char _enabled [ ] ;
2020-12-25 21:17:30 +01:00
2022-07-20 14:06:27 +02:00
// Read the BME280/BMP280 Sensor (which one runs depends on whether Celsius or Farenheit being set in Usermod Menu)
2020-12-25 21:17:30 +01:00
void UpdateBME280Data ( int SensorType )
{
float _temperature , _humidity , _pressure ;
2022-07-20 14:06:27 +02:00
if ( UseCelsius ) {
2020-12-25 21:17:30 +01:00
BME280 : : TempUnit tempUnit ( BME280 : : TempUnit_Celsius ) ;
EnvironmentCalculations : : TempUnit envTempUnit ( EnvironmentCalculations : : TempUnit_Celsius ) ;
2022-07-20 14:06:27 +02:00
BME280 : : PresUnit presUnit ( BME280 : : PresUnit_hPa ) ;
bme . read ( _pressure , _temperature , _humidity , tempUnit , presUnit ) ;
sensorTemperature = _temperature ;
sensorHumidity = _humidity ;
sensorPressure = _pressure ;
2022-11-25 16:45:21 +01:00
tempScale = F ( " °C " ) ;
2022-07-20 14:06:27 +02:00
if ( sensorType = = 1 )
{
sensorHeatIndex = EnvironmentCalculations : : HeatIndex ( _temperature , _humidity , envTempUnit ) ;
sensorDewPoint = EnvironmentCalculations : : DewPoint ( _temperature , _humidity , envTempUnit ) ;
}
} else {
2020-12-25 21:17:30 +01:00
BME280 : : TempUnit tempUnit ( BME280 : : TempUnit_Fahrenheit ) ;
EnvironmentCalculations : : TempUnit envTempUnit ( EnvironmentCalculations : : TempUnit_Fahrenheit ) ;
2022-07-20 14:06:27 +02:00
BME280 : : PresUnit presUnit ( BME280 : : PresUnit_hPa ) ;
2020-12-25 21:17:30 +01:00
2022-07-20 14:06:27 +02:00
bme . read ( _pressure , _temperature , _humidity , tempUnit , presUnit ) ;
2020-12-25 21:17:30 +01:00
2022-07-20 14:06:27 +02:00
sensorTemperature = _temperature ;
sensorHumidity = _humidity ;
sensorPressure = _pressure ;
2022-11-25 16:45:21 +01:00
tempScale = F ( " °F " ) ;
2022-07-20 14:06:27 +02:00
if ( sensorType = = 1 )
{
sensorHeatIndex = EnvironmentCalculations : : HeatIndex ( _temperature , _humidity , envTempUnit ) ;
sensorDewPoint = EnvironmentCalculations : : DewPoint ( _temperature , _humidity , envTempUnit ) ;
}
2020-12-25 21:17:30 +01:00
}
}
2022-07-20 14:06:27 +02:00
// Procedure to define all MQTT discovery Topics
2022-07-19 15:27:15 +02:00
void _mqttInitialize ( )
{
2022-11-25 16:45:21 +01:00
char mqttTemperatureTopic [ 128 ] ;
char mqttHumidityTopic [ 128 ] ;
char mqttPressureTopic [ 128 ] ;
char mqttHeatIndexTopic [ 128 ] ;
char mqttDewPointTopic [ 128 ] ;
snprintf_P ( mqttTemperatureTopic , 127 , PSTR ( " %s/temperature " ) , mqttDeviceTopic ) ;
snprintf_P ( mqttPressureTopic , 127 , PSTR ( " %s/pressure " ) , mqttDeviceTopic ) ;
snprintf_P ( mqttHumidityTopic , 127 , PSTR ( " %s/humidity " ) , mqttDeviceTopic ) ;
snprintf_P ( mqttHeatIndexTopic , 127 , PSTR ( " %s/heat_index " ) , mqttDeviceTopic ) ;
snprintf_P ( mqttDewPointTopic , 127 , PSTR ( " %s/dew_point " ) , mqttDeviceTopic ) ;
2022-07-19 15:27:15 +02:00
2022-07-20 14:06:27 +02:00
if ( HomeAssistantDiscovery ) {
2022-11-25 16:45:21 +01:00
_createMqttSensor ( F ( " Temperature " ) , mqttTemperatureTopic , " temperature " , tempScale ) ;
_createMqttSensor ( F ( " Pressure " ) , mqttPressureTopic , " pressure " , F ( " hPa " ) ) ;
_createMqttSensor ( F ( " Humidity " ) , mqttHumidityTopic , " humidity " , F ( " % " ) ) ;
_createMqttSensor ( F ( " HeatIndex " ) , mqttHeatIndexTopic , " temperature " , tempScale ) ;
_createMqttSensor ( F ( " DewPoint " ) , mqttDewPointTopic , " temperature " , tempScale ) ;
2022-07-20 14:06:27 +02:00
}
2022-07-19 15:27:15 +02:00
}
// Create an MQTT Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop.
void _createMqttSensor ( const String & name , const String & topic , const String & deviceClass , const String & unitOfMeasurement )
{
2022-07-21 18:38:07 +02:00
String t = String ( F ( " homeassistant/sensor/ " ) ) + mqttClientID + F ( " / " ) + name + F ( " /config " ) ;
2022-07-19 15:27:15 +02:00
StaticJsonDocument < 600 > doc ;
2022-07-21 10:48:37 +02:00
doc [ F ( " name " ) ] = String ( serverDescription ) + " " + name ;
doc [ F ( " state_topic " ) ] = topic ;
doc [ F ( " unique_id " ) ] = String ( mqttClientID ) + name ;
2022-07-19 15:27:15 +02:00
if ( unitOfMeasurement ! = " " )
2022-07-21 10:48:37 +02:00
doc [ F ( " unit_of_measurement " ) ] = unitOfMeasurement ;
2022-07-19 15:27:15 +02:00
if ( deviceClass ! = " " )
2022-07-21 10:48:37 +02:00
doc [ F ( " device_class " ) ] = deviceClass ;
doc [ F ( " expire_after " ) ] = 1800 ;
2022-07-19 15:27:15 +02:00
2022-07-21 10:48:37 +02:00
JsonObject device = doc . createNestedObject ( F ( " device " ) ) ; // attach the sensor to the same device
device [ F ( " name " ) ] = serverDescription ;
device [ F ( " identifiers " ) ] = " wled-sensor- " + String ( mqttClientID ) ;
device [ F ( " manufacturer " ) ] = F ( " WLED " ) ;
device [ F ( " model " ) ] = F ( " FOSS " ) ;
device [ F ( " sw_version " ) ] = versionString ;
2022-07-19 15:27:15 +02:00
String temp ;
serializeJson ( doc , temp ) ;
2022-07-21 18:38:07 +02:00
DEBUG_PRINTLN ( t ) ;
DEBUG_PRINTLN ( temp ) ;
2022-07-19 15:27:15 +02:00
mqtt - > publish ( t . c_str ( ) , 0 , true , temp . c_str ( ) ) ;
}
2022-11-25 16:45:21 +01:00
void publishMqtt ( const char * topic , const char * state ) {
//Check if MQTT Connected, otherwise it will crash the 8266
if ( WLED_MQTT_CONNECTED ) {
char subuf [ 128 ] ;
snprintf_P ( subuf , 127 , PSTR ( " %s/%s " ) , mqttDeviceTopic , topic ) ;
mqtt - > publish ( subuf , 0 , false , state ) ;
}
}
2020-12-25 21:17:30 +01:00
public :
void setup ( )
{
2023-05-30 19:36:14 +02:00
PinManagerPinType pins [ 2 ] = { { i2c_sda , true } , { i2c_scl , true } } ; // allocate pins
if ( ! pinManager . allocateMultiplePins ( pins , 2 , PinOwner : : HW_I2C ) ) { sensorType = 0 ; return ; }
2022-07-21 10:48:37 +02:00
2020-12-25 21:17:30 +01:00
if ( ! bme . begin ( ) )
{
2021-04-12 10:31:59 +02:00
sensorType = 0 ;
2022-11-25 16:45:21 +01:00
DEBUG_PRINTLN ( F ( " Could not find BME280 I2C sensor! " ) ) ;
2020-12-25 21:17:30 +01:00
}
else
{
switch ( bme . chipModel ( ) )
{
case BME280 : : ChipModel_BME280 :
2021-04-12 10:31:59 +02:00
sensorType = 1 ;
2022-07-21 18:38:07 +02:00
DEBUG_PRINTLN ( F ( " Found BME280 sensor! Success. " ) ) ;
2020-12-25 21:17:30 +01:00
break ;
case BME280 : : ChipModel_BMP280 :
2021-04-12 10:31:59 +02:00
sensorType = 2 ;
2022-07-21 18:38:07 +02:00
DEBUG_PRINTLN ( F ( " Found BMP280 sensor! No Humidity available. " ) ) ;
2020-12-25 21:17:30 +01:00
break ;
default :
2021-04-12 10:31:59 +02:00
sensorType = 0 ;
2022-07-21 18:38:07 +02:00
DEBUG_PRINTLN ( F ( " Found UNKNOWN sensor! Error! " ) ) ;
2020-12-25 21:17:30 +01:00
}
}
2022-07-21 10:48:37 +02:00
initDone = true ;
2020-12-25 21:17:30 +01:00
}
void loop ( )
{
2022-11-25 16:45:21 +01:00
if ( ! enabled | | strip . isUpdating ( ) ) return ;
2020-12-25 21:17:30 +01:00
// BME280 sensor MQTT publishing
2022-11-25 16:45:21 +01:00
// Check if sensor present and Connected, otherwise it will crash the MCU
if ( sensorType ! = 0 )
2020-12-25 21:17:30 +01:00
{
// Timer to fetch new temperature, humidity and pressure data at intervals
timer = millis ( ) ;
2022-11-25 16:45:21 +01:00
if ( timer - lastTemperatureMeasure > = TemperatureInterval * 1000 )
2020-12-25 21:17:30 +01:00
{
lastTemperatureMeasure = timer ;
2021-04-12 10:31:59 +02:00
UpdateBME280Data ( sensorType ) ;
2020-12-25 21:17:30 +01:00
2022-07-21 18:38:07 +02:00
float temperature = roundf ( sensorTemperature * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) ;
2021-04-12 10:31:59 +02:00
float humidity , heatIndex , dewPoint ;
2020-12-25 21:17:30 +01:00
// If temperature has changed since last measure, create string populated with device topic
// from the UI and values read from sensor, then publish to broker
2021-04-12 10:31:59 +02:00
if ( temperature ! = lastTemperature | | PublishAlways )
2020-12-25 21:17:30 +01:00
{
2022-11-25 16:45:21 +01:00
publishMqtt ( " temperature " , String ( temperature , TemperatureDecimals ) . c_str ( ) ) ;
2020-12-25 21:17:30 +01:00
}
2021-04-12 10:31:59 +02:00
lastTemperature = temperature ; // Update last sensor temperature for next loop
2020-12-25 21:17:30 +01:00
2021-04-12 10:31:59 +02:00
if ( sensorType = = 1 ) // Only if sensor is a BME280
2020-12-25 21:17:30 +01:00
{
2022-07-21 18:38:07 +02:00
humidity = roundf ( sensorHumidity * powf ( 10 , HumidityDecimals ) ) / powf ( 10 , HumidityDecimals ) ;
heatIndex = roundf ( sensorHeatIndex * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) ;
dewPoint = roundf ( sensorDewPoint * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) ;
2020-12-25 21:17:30 +01:00
2021-04-12 10:31:59 +02:00
if ( humidity ! = lastHumidity | | PublishAlways )
2020-12-25 21:17:30 +01:00
{
2022-11-25 16:45:21 +01:00
publishMqtt ( " humidity " , String ( humidity , HumidityDecimals ) . c_str ( ) ) ;
2020-12-25 21:17:30 +01:00
}
2021-04-12 10:31:59 +02:00
if ( heatIndex ! = lastHeatIndex | | PublishAlways )
2020-12-25 21:17:30 +01:00
{
2022-11-25 16:45:21 +01:00
publishMqtt ( " heat_index " , String ( heatIndex , TemperatureDecimals ) . c_str ( ) ) ;
2020-12-25 21:17:30 +01:00
}
2021-04-12 10:31:59 +02:00
if ( dewPoint ! = lastDewPoint | | PublishAlways )
2020-12-25 21:17:30 +01:00
{
2022-11-25 16:45:21 +01:00
publishMqtt ( " dew_point " , String ( dewPoint , TemperatureDecimals ) . c_str ( ) ) ;
2020-12-25 21:17:30 +01:00
}
2021-04-12 10:31:59 +02:00
lastHumidity = humidity ;
lastHeatIndex = heatIndex ;
lastDewPoint = dewPoint ;
2020-12-25 21:17:30 +01:00
}
}
2022-11-25 16:45:21 +01:00
if ( timer - lastPressureMeasure > = PressureInterval * 1000 )
2020-12-25 21:17:30 +01:00
{
lastPressureMeasure = timer ;
2022-07-21 18:38:07 +02:00
float pressure = roundf ( sensorPressure * powf ( 10 , PressureDecimals ) ) / powf ( 10 , PressureDecimals ) ;
2020-12-25 21:17:30 +01:00
2021-04-12 10:31:59 +02:00
if ( pressure ! = lastPressure | | PublishAlways )
2020-12-25 21:17:30 +01:00
{
2022-11-25 16:45:21 +01:00
publishMqtt ( " pressure " , String ( pressure , PressureDecimals ) . c_str ( ) ) ;
2020-12-25 21:17:30 +01:00
}
2021-04-12 10:31:59 +02:00
lastPressure = pressure ;
2020-12-25 21:17:30 +01:00
}
}
}
2022-11-25 16:45:21 +01:00
void onMqttConnect ( bool sessionPresent )
{
if ( WLED_MQTT_CONNECTED & & ! mqttInitialized )
{
_mqttInitialize ( ) ;
mqttInitialized = true ;
}
}
2022-07-19 22:47:56 +02:00
/*
* API calls te enable data exchange between WLED modules
*/
inline float getTemperatureC ( ) {
2022-07-20 14:06:27 +02:00
if ( UseCelsius ) {
2022-07-21 18:38:07 +02:00
return ( float ) roundf ( sensorTemperature * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) ;
2022-07-20 14:06:27 +02:00
} else {
2022-07-21 18:38:07 +02:00
return ( float ) roundf ( sensorTemperature * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) * 1.8f + 32 ;
2022-11-25 16:45:21 +01:00
}
2022-07-19 22:47:56 +02:00
}
2022-11-25 16:45:21 +01:00
2022-07-19 22:47:56 +02:00
inline float getTemperatureF ( ) {
2022-07-20 14:06:27 +02:00
if ( UseCelsius ) {
2022-07-21 18:38:07 +02:00
return ( ( float ) roundf ( sensorTemperature * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) - 32 ) * 0.56f ;
2022-07-20 14:06:27 +02:00
} else {
2022-07-21 18:38:07 +02:00
return ( float ) roundf ( sensorTemperature * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) ;
2022-07-20 14:06:27 +02:00
}
2022-07-19 22:47:56 +02:00
}
2022-11-25 16:45:21 +01:00
2022-07-19 22:47:56 +02:00
inline float getHumidity ( ) {
2022-07-21 18:38:07 +02:00
return ( float ) roundf ( sensorHumidity * powf ( 10 , HumidityDecimals ) ) ;
2022-07-19 22:47:56 +02:00
}
2022-11-25 16:45:21 +01:00
2022-07-19 22:47:56 +02:00
inline float getPressure ( ) {
2022-07-21 18:38:07 +02:00
return ( float ) roundf ( sensorPressure * powf ( 10 , PressureDecimals ) ) ;
2022-07-19 22:47:56 +02:00
}
2022-11-25 16:45:21 +01:00
2022-07-20 14:06:27 +02:00
inline float getDewPointC ( ) {
if ( UseCelsius ) {
2022-07-21 18:38:07 +02:00
return ( float ) roundf ( sensorDewPoint * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) ;
2022-07-20 14:06:27 +02:00
} else {
2022-07-21 18:38:07 +02:00
return ( float ) roundf ( sensorDewPoint * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) * 1.8f + 32 ;
2022-07-20 14:06:27 +02:00
}
}
2022-11-25 16:45:21 +01:00
2022-07-20 14:06:27 +02:00
inline float getDewPointF ( ) {
if ( UseCelsius ) {
2022-07-21 18:38:07 +02:00
return ( ( float ) roundf ( sensorDewPoint * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) - 32 ) * 0.56f ;
2022-07-20 14:06:27 +02:00
} else {
2022-07-21 18:38:07 +02:00
return ( float ) roundf ( sensorDewPoint * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) ;
2022-07-20 14:06:27 +02:00
}
2022-07-19 22:47:56 +02:00
}
2022-11-25 16:45:21 +01:00
2022-07-20 14:06:27 +02:00
inline float getHeatIndexC ( ) {
if ( UseCelsius ) {
2022-07-21 18:38:07 +02:00
return ( float ) roundf ( sensorHeatIndex * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) ;
2022-07-20 14:06:27 +02:00
} else {
2022-07-21 18:38:07 +02:00
return ( float ) roundf ( sensorHeatIndex * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) * 1.8f + 32 ;
2022-07-20 14:06:27 +02:00
}
2022-11-25 16:45:21 +01:00
}
inline float getHeatIndexF ( ) {
2022-07-20 14:06:27 +02:00
if ( UseCelsius ) {
2022-07-21 18:38:07 +02:00
return ( ( float ) roundf ( sensorHeatIndex * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) - 32 ) * 0.56f ;
2022-07-20 14:06:27 +02:00
} else {
2022-07-21 18:38:07 +02:00
return ( float ) roundf ( sensorHeatIndex * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) ;
2022-07-20 14:06:27 +02:00
}
2022-07-19 22:47:56 +02:00
}
2022-07-19 15:27:15 +02:00
// Publish Sensor Information to Info Page
void addToJsonInfo ( JsonObject & root )
{
JsonObject user = root [ F ( " u " ) ] ;
2022-07-19 22:47:56 +02:00
if ( user . isNull ( ) ) user = root . createNestedObject ( F ( " u " ) ) ;
2022-07-19 15:27:15 +02:00
if ( sensorType = = 0 ) //No Sensor
{
// if we sensor not detected, let the user know
2022-07-21 10:48:37 +02:00
JsonArray temperature_json = user . createNestedArray ( F ( " BME/BMP280 Sensor " ) ) ;
2022-07-19 15:27:15 +02:00
temperature_json . add ( F ( " Not Found " ) ) ;
}
else if ( sensorType = = 2 ) //BMP280
{
2022-07-21 18:38:07 +02:00
JsonArray temperature_json = user . createNestedArray ( F ( " Temperature " ) ) ;
JsonArray pressure_json = user . createNestedArray ( F ( " Pressure " ) ) ;
temperature_json . add ( roundf ( sensorTemperature * powf ( 10 , TemperatureDecimals ) ) ) ;
2022-07-20 14:06:27 +02:00
temperature_json . add ( tempScale ) ;
2022-07-21 18:38:07 +02:00
pressure_json . add ( roundf ( sensorPressure * powf ( 10 , PressureDecimals ) ) ) ;
2022-07-19 23:15:26 +02:00
pressure_json . add ( F ( " hPa " ) ) ;
2022-07-19 15:27:15 +02:00
}
else if ( sensorType = = 1 ) //BME280
{
2022-07-21 18:38:07 +02:00
JsonArray temperature_json = user . createNestedArray ( F ( " Temperature " ) ) ;
JsonArray humidity_json = user . createNestedArray ( F ( " Humidity " ) ) ;
JsonArray pressure_json = user . createNestedArray ( F ( " Pressure " ) ) ;
JsonArray heatindex_json = user . createNestedArray ( F ( " Heat Index " ) ) ;
JsonArray dewpoint_json = user . createNestedArray ( F ( " Dew Point " ) ) ;
temperature_json . add ( roundf ( sensorTemperature * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) ) ;
2022-07-20 14:06:27 +02:00
temperature_json . add ( tempScale ) ;
2022-07-21 18:38:07 +02:00
humidity_json . add ( roundf ( sensorHumidity * powf ( 10 , HumidityDecimals ) ) ) ;
2022-07-19 15:27:15 +02:00
humidity_json . add ( F ( " % " ) ) ;
2022-07-21 18:38:07 +02:00
pressure_json . add ( roundf ( sensorPressure * powf ( 10 , PressureDecimals ) ) ) ;
2022-07-19 22:47:56 +02:00
pressure_json . add ( F ( " hPa " ) ) ;
2022-07-21 18:38:07 +02:00
heatindex_json . add ( roundf ( sensorHeatIndex * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) ) ;
2022-07-20 14:06:27 +02:00
heatindex_json . add ( tempScale ) ;
2022-07-21 18:38:07 +02:00
dewpoint_json . add ( roundf ( sensorDewPoint * powf ( 10 , TemperatureDecimals ) ) / powf ( 10 , TemperatureDecimals ) ) ;
2022-07-20 14:06:27 +02:00
dewpoint_json . add ( tempScale ) ;
2022-07-19 15:27:15 +02:00
}
return ;
}
// Save Usermod Config Settings
void addToConfig ( JsonObject & root )
{
2022-11-25 16:45:21 +01:00
JsonObject top = root . createNestedObject ( FPSTR ( _name ) ) ;
top [ FPSTR ( _enabled ) ] = enabled ;
2022-07-21 10:48:37 +02:00
top [ F ( " TemperatureDecimals " ) ] = TemperatureDecimals ;
top [ F ( " HumidityDecimals " ) ] = HumidityDecimals ;
top [ F ( " PressureDecimals " ) ] = PressureDecimals ;
top [ F ( " TemperatureInterval " ) ] = TemperatureInterval ;
top [ F ( " PressureInterval " ) ] = PressureInterval ;
top [ F ( " PublishAlways " ) ] = PublishAlways ;
top [ F ( " UseCelsius " ) ] = UseCelsius ;
top [ F ( " HomeAssistantDiscovery " ) ] = HomeAssistantDiscovery ;
DEBUG_PRINTLN ( F ( " BME280 config saved. " ) ) ;
2022-07-19 15:27:15 +02:00
}
// Read Usermod Config Settings
bool readFromConfig ( JsonObject & root )
{
// default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor
// setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed)
2022-11-25 16:45:21 +01:00
JsonObject top = root [ FPSTR ( _name ) ] ;
2022-07-21 10:48:37 +02:00
if ( top . isNull ( ) ) {
2022-11-25 16:45:21 +01:00
DEBUG_PRINT ( F ( _name ) ) ;
2022-07-21 10:48:37 +02:00
DEBUG_PRINTLN ( F ( " : No config found. (Using defaults.) " ) ) ;
return false ;
}
2022-07-19 15:27:15 +02:00
bool configComplete = ! top . isNull ( ) ;
2022-11-25 16:45:21 +01:00
configComplete & = getJsonValue ( top [ FPSTR ( _enabled ) ] , enabled ) ;
2022-07-19 15:27:15 +02:00
// A 3-argument getJsonValue() assigns the 3rd argument as a default value if the Json value is missing
2022-07-21 10:48:37 +02:00
configComplete & = getJsonValue ( top [ F ( " TemperatureDecimals " ) ] , TemperatureDecimals , 1 ) ;
configComplete & = getJsonValue ( top [ F ( " HumidityDecimals " ) ] , HumidityDecimals , 0 ) ;
configComplete & = getJsonValue ( top [ F ( " PressureDecimals " ) ] , PressureDecimals , 0 ) ;
configComplete & = getJsonValue ( top [ F ( " TemperatureInterval " ) ] , TemperatureInterval , 30 ) ;
configComplete & = getJsonValue ( top [ F ( " PressureInterval " ) ] , PressureInterval , 30 ) ;
configComplete & = getJsonValue ( top [ F ( " PublishAlways " ) ] , PublishAlways , false ) ;
configComplete & = getJsonValue ( top [ F ( " UseCelsius " ) ] , UseCelsius , true ) ;
configComplete & = getJsonValue ( top [ F ( " HomeAssistantDiscovery " ) ] , HomeAssistantDiscovery , false ) ;
2022-11-25 16:45:21 +01:00
DEBUG_PRINT ( FPSTR ( _name ) ) ;
2022-07-21 10:48:37 +02:00
if ( ! initDone ) {
// first run: reading from cfg.json
DEBUG_PRINTLN ( F ( " config loaded. " ) ) ;
} else {
DEBUG_PRINTLN ( F ( " config (re)loaded. " ) ) ;
// changing parameters from settings page
}
2022-07-19 15:27:15 +02:00
return configComplete ;
}
2022-07-21 10:48:37 +02:00
uint16_t getId ( ) {
return USERMOD_ID_BME280 ;
}
2022-11-25 16:45:21 +01:00
} ;
const char UsermodBME280 : : _name [ ] PROGMEM = " BME280/BMP280 " ;
const char UsermodBME280 : : _enabled [ ] PROGMEM = " enabled " ;