Skip to content

Commit

Permalink
Rename constants for topics
Browse files Browse the repository at this point in the history
Add intermediate class "SensorNode"
Add helper function to fix value ranges
Add helper function to calculate absolute humidity
Derive DHT22/BME280/DS18B20 from SensorNode
Add absolute humidity for DHT22/BME280 to reported values
  • Loading branch information
luebbe committed Sep 21, 2019
1 parent f91fbf3 commit 93a2c16
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 66 deletions.
16 changes: 8 additions & 8 deletions src/AdcNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ void AdcNode::send()
}
else
{
setProperty(cVoltage).send(String(_voltage));
setProperty(cBatteryLevel).send(String(_batteryLevel));
setProperty(cVoltageTopic).send(String(_voltage));
setProperty(cBatteryLevelTopic).send(String(_batteryLevel));
Homie.getLogger() << cIndent << "Voltage: " << _voltage << "V" << endl;
Homie.getLogger() << cIndent << "Battery level: " << _batteryLevel << "%" << endl;
}
Expand Down Expand Up @@ -113,17 +113,17 @@ void AdcNode::beforeHomieSetup()
void AdcNode::onReadyToOperate()
{
// Will be called after MQTT_CONNECT
setProperty(cVoltageUnit).send("V");
setProperty(cBatteryLevelUnit).send("%");
setProperty(cVoltageUnitTopic).send("V");
setProperty(cBatteryLevelUnitTopic).send("%");
};

void AdcNode::setup()
{
// Will be called from Homie.setup()
advertise(cVoltage);
advertise(cVoltageUnit);
advertise(cBatteryLevel);
advertise(cBatteryLevelUnit);
advertise(cVoltageTopic);
advertise(cVoltageUnitTopic);
advertise(cBatteryLevelTopic);
advertise(cBatteryLevelUnitTopic);

printCaption();
Homie.getLogger() << cIndent << "Send interval: " << _sendInterval / 1000 << " s" << endl;
Expand Down
45 changes: 28 additions & 17 deletions src/BME280Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ BME280Node::BME280Node(const char *name,
const Adafruit_BME280::sensor_sampling tempSampling,
const Adafruit_BME280::sensor_sampling pressSampling,
const Adafruit_BME280::sensor_sampling humSampling,
const Adafruit_BME280::sensor_filter filter) : HomieNode(name, "BME280", "sensor"),
const Adafruit_BME280::sensor_filter filter) : SensorNode(name, "BME280"),
_i2cAddress(i2cAddress),
_lastMeasurement(0),
_tempSampling(tempSampling),
Expand All @@ -31,7 +31,7 @@ BME280Node::BME280Node(const char *name,

void BME280Node::printCaption()
{
Homie.getLogger() << cCaption << endl;
Homie.getLogger() << cCaption << " i2c[" << _i2cAddress << "]:" << endl;
}

void BME280Node::loop()
Expand All @@ -47,22 +47,30 @@ void BME280Node::loop()
humidity = bme.readHumidity();
pressure = bme.readPressure() / 100;

fixRange(&temperature, cMinTemp, cMaxTemp);
fixRange(&humidity, cMinHumid, cMaxHumid);
fixRange(&pressure, cMinPress, cMaxPress);

printCaption();

float absHumidity = computeAbsoluteHumidity(temperature, humidity);

Homie.getLogger() << cIndent << "Temperature: " << temperature << " °C" << endl;
temperature += temperatureOffsetSetting.get();
Homie.getLogger() << cIndent << "Temperature (after offset): " << temperature << " °C" << endl;
Homie.getLogger() << cIndent << "Humidity: " << humidity << " %" << endl;
Homie.getLogger() << cIndent << "Pressure: " << pressure << " hPa" << endl;
Homie.getLogger() << cIndent << "Abs humidity: " << absHumidity << " g/m³" << endl;

setProperty(cStatus).send("ok");
setProperty(cTemperature).send(String(temperature));
setProperty(cHumidity).send(String(humidity));
setProperty(cPressure).send(String(pressure));
setProperty(cStatusTopic).send("ok");
setProperty(cTemperatureTopic).send(String(temperature));
setProperty(cHumidityTopic).send(String(humidity));
setProperty(cPressureTopic).send(String(pressure));
setProperty(cAbsHumidityTopic).send(String(absHumidity));
}
else
{
setProperty(cStatus).send("error");
setProperty(cStatusTopic).send("error");
}
_lastMeasurement = millis();
}
Expand All @@ -77,20 +85,23 @@ void BME280Node::beforeHomieSetup()

void BME280Node::onReadyToOperate()
{
setProperty(cTemperatureUnit).send("°C");
setProperty(cHumidityUnit).send("%");
setProperty(cPressureUnit).send("hPa");
setProperty(cTemperatureUnitTopic).send("°C");
setProperty(cHumidityUnitTopic).send("%");
setProperty(cPressureUnitTopic).send("hPa");
setProperty(cAbsHumidityUnitTopic).send("g/m³");
};

void BME280Node::setup()
{
advertise(cStatus);
advertise(cTemperature);
advertise(cTemperatureUnit);
advertise(cHumidity);
advertise(cHumidityUnit);
advertise(cPressure);
advertise(cPressureUnit);
advertise(cStatusTopic);
advertise(cTemperatureTopic);
advertise(cTemperatureUnitTopic);
advertise(cHumidityTopic);
advertise(cHumidityUnitTopic);
advertise(cPressureTopic);
advertise(cPressureUnitTopic);
advertise(cAbsHumidityTopic);
advertise(cAbsHumidityUnitTopic);

if (bme.begin(_i2cAddress))
{
Expand Down
9 changes: 6 additions & 3 deletions src/BME280Node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@
#include <SPI.h>
#include <Wire.h>

#include <HomieNode.hpp>
#include "SensorNode.hpp"
#include "constants.hpp"

class BME280Node : public HomieNode
class BME280Node : public SensorNode
{
private:
const float cMinTemp = -40.0;
const float cMaxTemp = 85.0;
const float cMinPress = 300.0;
const float cMaxPress = 1100.0;
// suggested rate is 1/60Hz (1m)
static const int MIN_INTERVAL = 60; // in seconds
static const int MEASUREMENT_INTERVAL = 300;
const char *cCaption = "• BME280 sensor:";
const char *cIndent = "";

Expand Down
34 changes: 22 additions & 12 deletions src/DHT22Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#define DHTTYPE DHT22

DHT22Node::DHT22Node(const char *name, const int sensorPin, const int measurementInterval)
: HomieNode(name, "DHT22", "sensor"),
: SensorNode(name, "DHT22"),
_sensorPin(sensorPin),
_measurementInterval(measurementInterval),
_lastMeasurement(0)
Expand All @@ -37,21 +37,28 @@ void DHT22Node::loop()
temperature = dht->readTemperature();
humidity = dht->readHumidity();

fixRange(&temperature, cMinTemp, cMaxTemp);
fixRange(&humidity, cMinHumid, cMaxHumid);

printCaption();

if (isnan(temperature) || isnan(humidity))
{
Homie.getLogger() << cIndent << "Error reading from Sensor" << endl;
setProperty(cStatus).send("error");
setProperty(cStatusTopic).send("error");
}
else
{
float absHumidity = computeAbsoluteHumidity(temperature, humidity);

Homie.getLogger() << cIndent << "Temperature: " << temperature << " °C" << endl;
Homie.getLogger() << cIndent << "Humidity: " << humidity << " %" << endl;
Homie.getLogger() << cIndent << "Abs humidity: " << absHumidity << " g/m³" << endl;

setProperty(cStatus).send("ok");
setProperty(cTemperature).send(String(temperature));
setProperty(cHumidity).send(String(humidity));
setProperty(cStatusTopic).send("ok");
setProperty(cTemperatureTopic).send(String(temperature));
setProperty(cHumidityTopic).send(String(humidity));
setProperty(cAbsHumidityTopic).send(String(absHumidity));
}
_lastMeasurement = millis();
}
Expand All @@ -60,17 +67,20 @@ void DHT22Node::loop()

void DHT22Node::onReadyToOperate()
{
setProperty(cTemperatureUnit).send("°C");
setProperty(cHumidityUnit).send("%");
setProperty(cTemperatureUnitTopic).send("°C");
setProperty(cHumidityUnitTopic).send("%");
setProperty(cAbsHumidityUnitTopic).send("g/m³");
};

void DHT22Node::setup()
{
advertise(cStatus);
advertise(cTemperature);
advertise(cTemperatureUnit);
advertise(cHumidity);
advertise(cHumidityUnit);
advertise(cStatusTopic);
advertise(cTemperatureTopic);
advertise(cTemperatureUnitTopic);
advertise(cHumidityTopic);
advertise(cHumidityUnitTopic);
advertise(cAbsHumidityTopic);
advertise(cAbsHumidityUnitTopic);

printCaption();
Homie.getLogger() << cIndent << "Reading interval: " << _measurementInterval << " s" << endl;
Expand Down
9 changes: 6 additions & 3 deletions src/DHT22Node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@
#include <Adafruit_Sensor.h>
#include <DHT_U.h>

#include <Homie.hpp>
#include "SensorNode.hpp"
#include "constants.hpp"

#define DEFAULTPIN -1

class DHT22Node : public HomieNode
class DHT22Node : public SensorNode
{
private:
static const int MEASUREMENT_INTERVAL = 300;
const float cMinTemp = -40.0;
const float cMaxTemp = 125.0;
const float cMinHumid = 0.0;
const float cMaxHumid = 100.0;
const char *cCaption = "• DHT22 sensor";
const char *cIndent = "";

Expand Down
18 changes: 10 additions & 8 deletions src/DS18B20Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "DS18B20Node.hpp"

DS18B20Node::DS18B20Node(const char *name, const int sensorPin, const int measurementInterval)
: HomieNode(name, "DS18N20", "sensor"),
: SensorNode(name, "DS18N20"),
_sensorPin(sensorPin),
_measurementInterval(measurementInterval),
_lastMeasurement(0)
Expand All @@ -34,17 +34,19 @@ void DS18B20Node::loop()
{
dallasTemp->requestTemperatures();
temperature = dallasTemp->getTempCByIndex(0);
fixRange(&temperature, cMinTemp, cMaxTemp);

printCaption();
if (DEVICE_DISCONNECTED_C == temperature)
{
Homie.getLogger() << cIndent << "Error reading from Sensor" << endl;
setProperty(cStatus).send("error");
setProperty(cStatusTopic).send("error");
}
else
{
Homie.getLogger() << cIndent << "Temperature: " << temperature << " °C" << endl;
setProperty(cStatus).send("ok");
setProperty(cTemperature).send(String(temperature));
setProperty(cStatusTopic).send("ok");
setProperty(cTemperatureTopic).send(String(temperature));
}
_lastMeasurement = millis();
}
Expand All @@ -53,14 +55,14 @@ void DS18B20Node::loop()

void DS18B20Node::onReadyToOperate()
{
setProperty(cTemperatureUnit).send("°C");
setProperty(cTemperatureUnitTopic).send("°C");
};

void DS18B20Node::setup()
{
advertise(cStatus);
advertise(cTemperature);
advertise(cTemperatureUnit);
advertise(cStatusTopic);
advertise(cTemperatureTopic);
advertise(cTemperatureUnitTopic);

printCaption();
Homie.getLogger() << cIndent << "Reading interval: " << _measurementInterval << " s" << endl;
Expand Down
7 changes: 4 additions & 3 deletions src/DS18B20Node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
#include <OneWire.h>
#include <DallasTemperature.h>

#include <Homie.hpp>
#include "SensorNode.hpp"
#include "constants.hpp"

#define DEFAULTPIN -1

class DS18B20Node : public HomieNode {
class DS18B20Node : public SensorNode {
private:
static const int MEASUREMENT_INTERVAL = 300;
const float cMinTemp = -55.0;
const float cMaxTemp = 125.0;
const char *cCaption = "• DS18B20 sensor";
const char *cIndent = "";

Expand Down
48 changes: 48 additions & 0 deletions src/SensorNode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* SensorNode.hpp
* Homie Node for genric sensors.
* Provides a limit method for measurement values
*
* Version: 1.0
* Author: Lübbe Onken (http://github.com/luebbe)
*/

#include "SensorNode.hpp"

SensorNode::SensorNode(const char *name, const char *type)
: HomieNode(name, type, "sensor")
{
}

float SensorNode::computeAbsoluteHumidity(float temperature, float percentHumidity) {
// Calculate the absolute humidity in g/m³
// https://carnotcycle.wordpress.com/2012/08/04/how-to-convert-relative-humidity-to-absolute-humidity/

float absHumidity;
float absTemperature;
absTemperature = temperature + 273.15;

absHumidity = 6.112;
absHumidity *= exp((17.67 * temperature) / (243.5 + temperature));
absHumidity *= percentHumidity;
absHumidity *= 2.1674;
absHumidity /= absTemperature;

return absHumidity;
}

void SensorNode::fixRange(float *value, float min, float max)
{
if (isnan(*value))
{
return;
}
else if (*value < min)
{
*value = min;
}
else if (*value > max)
{
*value = max;
};
}
26 changes: 26 additions & 0 deletions src/SensorNode.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* SensorNode.hpp
* Homie Node for genric sensors.
* Provides a limit method for measurement values
*
* Version: 1.0
* Author: Lübbe Onken (http://github.com/luebbe)
*/

#pragma once

#include <Homie.hpp>

class SensorNode : public HomieNode
{
protected:
const float cMinHumid = 0.0;
const float cMaxHumid = 100.0;
static const int MEASUREMENT_INTERVAL = 300;

float computeAbsoluteHumidity(float temperature, float percentHumidity);
void fixRange(float *value, float min, float max);

public:
SensorNode(const char *name, const char *type);
};
Loading

0 comments on commit 93a2c16

Please sign in to comment.