Compare commits
3 Commits
67a1a317fc
...
75755ada63
| Author | SHA1 | Date | |
|---|---|---|---|
| 75755ada63 | |||
| 118bef8f72 | |||
| 528c12c70f |
@ -7,25 +7,205 @@
|
|||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
font-size: 4vw;
|
font-size: 12vw;
|
||||||
margin: 1em;
|
margin: 0;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
background-color: #5c875c;
|
||||||
}
|
}
|
||||||
|
|
||||||
div {
|
div {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
.heading {
|
||||||
|
padding: 0.25em 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
background-color: #93da93;
|
||||||
|
border-bottom: 1px solid gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
clear: both;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 50%;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.valueAndUnit {
|
||||||
|
clear: both;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unit {
|
||||||
|
float: left;
|
||||||
|
margin-left: 0.25em;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputNull {
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputBlue {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputGreen {
|
||||||
|
color: #00ff00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputRed {
|
||||||
|
color: #ba0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Gewächshaus</h1>
|
<div class="heading">Gewächshaus</div>
|
||||||
TODO
|
|
||||||
|
<div class="content">
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="title">Temperatur</div>
|
||||||
|
<div class="valueAndUnit">
|
||||||
|
<div class="value" id="temperature"></div>
|
||||||
|
<div class="unit">°C</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="title">Relative Luftfeuchte</div>
|
||||||
|
<div class="valueAndUnit">
|
||||||
|
<div class="value" id="relative"></div>
|
||||||
|
<div class="unit">%</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="title">Absolute Luftfeuchte</div>
|
||||||
|
<div class="valueAndUnit">
|
||||||
|
<div class="value" id="absolute"></div>
|
||||||
|
<div class="unit">g/m³</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="title">Helligkeit</div>
|
||||||
|
<div class="valueAndUnit">
|
||||||
|
<div class="value" id="illuminance"></div>
|
||||||
|
<div class="unit">lux</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const NO_VALUE = "- - -";
|
||||||
|
|
||||||
|
const TEMPERATURE_BLUE = 10;
|
||||||
|
const TEMPERATURE_RED = 35;
|
||||||
|
|
||||||
|
const RELATIVE_BLUE = 60;
|
||||||
|
const RELATIVE_RED = 80;
|
||||||
|
|
||||||
|
const htmlTemperature = document.getElementById('temperature');
|
||||||
|
const htmlRelative = document.getElementById('relative');
|
||||||
|
const htmlAbsolute = document.getElementById('absolute');
|
||||||
|
const htmlIlluminance = document.getElementById('illuminance');
|
||||||
|
|
||||||
|
function status() {
|
||||||
|
get("/status");
|
||||||
|
}
|
||||||
|
|
||||||
|
function get(path) {
|
||||||
|
const request = new XMLHttpRequest();
|
||||||
|
request.onreadystatechange = function () {
|
||||||
|
if (request.readyState === 4) {
|
||||||
|
update(request.responseText);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
request.open('GET', (location.hostname === "localhost" ? "http://10.0.0.160" : "") + path);
|
||||||
|
request.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function format(value, decimals) {
|
||||||
|
return value?.toLocaleString(undefined, {minimumFractionDigits: decimals, maximumFractionDigits: decimals});
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(response) {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(response);
|
||||||
|
htmlTemperature.innerText = format(data?.temperature, 1) || NO_VALUE;
|
||||||
|
htmlRelative.innerText = format(data?.relative, 0) || NO_VALUE;
|
||||||
|
htmlAbsolute.innerText = format(data?.absolute, 1) || NO_VALUE;
|
||||||
|
htmlIlluminance.innerText = format(data?.illuminance, 0) || NO_VALUE;
|
||||||
|
|
||||||
|
const relativeNull = !isSet(data?.relative);
|
||||||
|
const relativeBlue = !relativeNull && data?.relative < RELATIVE_BLUE;
|
||||||
|
const relativeRed = !relativeNull && data?.relative > RELATIVE_RED;
|
||||||
|
const relativeGreen = !relativeNull && !relativeBlue && !relativeRed;
|
||||||
|
setClass(htmlRelative.parentElement, "inputNull", relativeNull);
|
||||||
|
setClass(htmlRelative.parentElement, "inputRed", relativeBlue);
|
||||||
|
setClass(htmlRelative.parentElement, "inputGreen", relativeGreen);
|
||||||
|
setClass(htmlRelative.parentElement, "inputBlue", relativeRed);
|
||||||
|
|
||||||
|
const temperatureNull = !isSet(data?.temperature);
|
||||||
|
const temperatureBlue = !temperatureNull && data?.temperature < TEMPERATURE_BLUE;
|
||||||
|
const temperatureRed = !temperatureNull && data?.temperature > TEMPERATURE_RED;
|
||||||
|
const temperatureGreen = !temperatureNull && !temperatureBlue && !temperatureRed;
|
||||||
|
setClass(htmlTemperature.parentElement, "inputNull", temperatureNull);
|
||||||
|
setClass(htmlTemperature.parentElement, "inputBlue", temperatureBlue);
|
||||||
|
setClass(htmlTemperature.parentElement, "inputGreen", temperatureGreen);
|
||||||
|
setClass(htmlTemperature.parentElement, "inputRed", temperatureRed);
|
||||||
|
} catch (e) {
|
||||||
|
reset(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSet(v) {
|
||||||
|
return v !== null && v !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset(e) {
|
||||||
|
console.error("Failed to handle data:", e);
|
||||||
|
htmlTemperature.innerText = NO_VALUE;
|
||||||
|
htmlRelative.innerText = NO_VALUE;
|
||||||
|
htmlAbsolute.innerText = NO_VALUE;
|
||||||
|
htmlIlluminance.innerText = NO_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {HTMLElement} element
|
||||||
|
* @param {string} className
|
||||||
|
* @param {boolean} enabled
|
||||||
|
*/
|
||||||
|
function setClass(element, className, enabled) {
|
||||||
|
if (element.classList.contains(className) !== enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
element.classList.add(className);
|
||||||
|
} else {
|
||||||
|
element.classList.remove(className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status();
|
||||||
|
setInterval(() => status(), 2000);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@ -39,10 +39,10 @@ lib_deps = ${common.lib_deps}
|
|||||||
build_flags = ${common.build_flags} -DNODE_GREENHOUSE -DHOSTNAME=\"Greenhouse\"
|
build_flags = ${common.build_flags} -DNODE_GREENHOUSE -DHOSTNAME=\"Greenhouse\"
|
||||||
board_build.filesystem = ${common.board_build.filesystem}
|
board_build.filesystem = ${common.board_build.filesystem}
|
||||||
monitor_speed = ${common.monitor_speed}
|
monitor_speed = ${common.monitor_speed}
|
||||||
;upload_protocol = ${common.upload_protocol}
|
upload_protocol = ${common.upload_protocol}
|
||||||
;upload_port = 10.0.0.160
|
upload_port = 10.0.0.160
|
||||||
upload_port = ${common.upload_port}
|
;upload_port = ${common.upload_port}
|
||||||
upload_speed = ${common.upload_speed}
|
;upload_speed = ${common.upload_speed}
|
||||||
|
|
||||||
[env:Fermenter]
|
[env:Fermenter]
|
||||||
platform = ${esp12e.platform}
|
platform = ${esp12e.platform}
|
||||||
@ -54,6 +54,6 @@ board_build.filesystem = ${common.board_build.filesystem}
|
|||||||
monitor_speed = ${common.monitor_speed}
|
monitor_speed = ${common.monitor_speed}
|
||||||
upload_flags = --auth=OtaAuthPatrixFermenter
|
upload_flags = --auth=OtaAuthPatrixFermenter
|
||||||
upload_protocol = ${common.upload_protocol}
|
upload_protocol = ${common.upload_protocol}
|
||||||
upload_port = 10.0.0.169
|
upload_port = 10.0.0.164
|
||||||
;upload_port = ${common.upload_port}
|
;upload_port = ${common.upload_port}
|
||||||
;upload_speed = ${common.upload_speed}
|
;upload_speed = ${common.upload_speed}
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
#ifdef NODE_GREENHOUSE
|
|
||||||
|
|
||||||
#include "patrix/tsl2561.h"
|
|
||||||
#include "patrix/bmp280_aht20.h"
|
|
||||||
|
|
||||||
TSL2561 greenhouse_TSL2561("greenhouse");
|
|
||||||
|
|
||||||
BMP280_AHT20 greenhouse_BMP280_AHT20("greenhouse");
|
|
||||||
|
|
||||||
void patrixSetup() {
|
|
||||||
greenhouse_TSL2561.setup();
|
|
||||||
greenhouse_BMP280_AHT20.setup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void patrixLoop() {
|
|
||||||
greenhouse_TSL2561.loop();
|
|
||||||
greenhouse_BMP280_AHT20.loop();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
15
src/node/Greenhouse/Greenhouse.cpp
Normal file
15
src/node/Greenhouse/Greenhouse.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifdef NODE_GREENHOUSE
|
||||||
|
|
||||||
|
#include "http.h"
|
||||||
|
#include "sensors.h"
|
||||||
|
|
||||||
|
void patrixSetup() {
|
||||||
|
sensorsSetup();
|
||||||
|
httpSetup2();
|
||||||
|
}
|
||||||
|
|
||||||
|
void patrixLoop() {
|
||||||
|
sensorsLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
25
src/node/Greenhouse/http.cpp
Normal file
25
src/node/Greenhouse/http.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifdef NODE_GREENHOUSE
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
#include "http.h"
|
||||||
|
#include "sensors.h"
|
||||||
|
#include "../../patrix/mqtt.h"
|
||||||
|
|
||||||
|
void httpStatus(AsyncWebServerRequest* request) {
|
||||||
|
JsonDocument json;
|
||||||
|
json["illuminance"] = greenhouseTSL.getIlluminance();;
|
||||||
|
json["temperature"] = greenhouseDHT22.getTemperature();
|
||||||
|
json["relative"] = greenhouseDHT22.getRelative();
|
||||||
|
json["absolute"] = greenhouseDHT22.getAbsolute();
|
||||||
|
|
||||||
|
AsyncResponseStream* stream = request->beginResponseStream("application/json");
|
||||||
|
serializeJson(json, *stream);
|
||||||
|
request->send(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
void httpSetup2() {
|
||||||
|
server.on("/status", httpStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
16
src/node/Greenhouse/http.h
Normal file
16
src/node/Greenhouse/http.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifdef NODE_GREENHOUSE
|
||||||
|
|
||||||
|
#ifndef HTTP_H
|
||||||
|
#define HTTP_H
|
||||||
|
|
||||||
|
#include "patrix/http.h"
|
||||||
|
|
||||||
|
void httpStatus(AsyncWebServerRequest* request);
|
||||||
|
|
||||||
|
void httpTargetAdd(AsyncWebServerRequest* request);
|
||||||
|
|
||||||
|
void httpSetup2();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
19
src/node/Greenhouse/sensors.cpp
Normal file
19
src/node/Greenhouse/sensors.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifdef NODE_GREENHOUSE
|
||||||
|
|
||||||
|
#include "sensors.h"
|
||||||
|
|
||||||
|
TSL2561 greenhouseTSL("greenhouse");
|
||||||
|
|
||||||
|
DHT22Sensor greenhouseDHT22("greenhouse", D5);
|
||||||
|
|
||||||
|
void sensorsSetup() {
|
||||||
|
greenhouseTSL.setup();
|
||||||
|
greenhouseDHT22.setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sensorsLoop() {
|
||||||
|
greenhouseTSL.loop();
|
||||||
|
greenhouseDHT22.loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
19
src/node/Greenhouse/sensors.h
Normal file
19
src/node/Greenhouse/sensors.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifdef NODE_GREENHOUSE
|
||||||
|
|
||||||
|
#ifndef SENSORS_H
|
||||||
|
#define SENSORS_H
|
||||||
|
|
||||||
|
#include "patrix/DHT22.h"
|
||||||
|
#include "patrix/tsl2561.h"
|
||||||
|
|
||||||
|
extern TSL2561 greenhouseTSL;
|
||||||
|
|
||||||
|
extern DHT22Sensor greenhouseDHT22;
|
||||||
|
|
||||||
|
void sensorsSetup();
|
||||||
|
|
||||||
|
void sensorsLoop();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1,8 +1,9 @@
|
|||||||
#ifndef DHT22_H
|
#ifndef DHT22_H
|
||||||
#define DHT22_H
|
#define DHT22_H
|
||||||
|
|
||||||
#include "mqtt.h"
|
|
||||||
#include "DHT_U.h"
|
#include "DHT_U.h"
|
||||||
|
#include "humidityRelative.h"
|
||||||
|
#include "mqtt.h"
|
||||||
|
|
||||||
class DHT22Sensor {
|
class DHT22Sensor {
|
||||||
|
|
||||||
@ -12,6 +13,12 @@ class DHT22Sensor {
|
|||||||
|
|
||||||
unsigned long last = 0UL;
|
unsigned long last = 0UL;
|
||||||
|
|
||||||
|
double temperature = NAN;
|
||||||
|
|
||||||
|
double relative = NAN;
|
||||||
|
|
||||||
|
double absolute = NAN;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
const String name;
|
const String name;
|
||||||
@ -24,30 +31,33 @@ public:
|
|||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
dht.begin();
|
dht.begin();
|
||||||
|
last = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
const auto now = max(1UL, millis());
|
const auto now = max(1UL, millis());
|
||||||
float temperature = NAN;
|
if (now - last >= intervalMs) {
|
||||||
if (last == 0 || now - last >= intervalMs) {
|
|
||||||
sensors_event_t event;
|
sensors_event_t event;
|
||||||
|
|
||||||
dht.temperature().getEvent(&event);
|
dht.temperature().getEvent(&event);
|
||||||
if (isnan(event.temperature)) {
|
temperature = event.temperature;
|
||||||
|
if (isnan(temperature)) {
|
||||||
|
absolute = NAN;
|
||||||
Log.error("Error reading temperature!");
|
Log.error("Error reading temperature!");
|
||||||
} else {
|
} else {
|
||||||
temperature = event.temperature;
|
|
||||||
mqttPublishValue(name + "/temperature", temperature, "TEMPERATURE_C");
|
mqttPublishValue(name + "/temperature", temperature, "TEMPERATURE_C");
|
||||||
}
|
}
|
||||||
|
|
||||||
dht.humidity().getEvent(&event);
|
dht.humidity().getEvent(&event);
|
||||||
if (isnan(event.relative_humidity)) {
|
relative = event.relative_humidity;
|
||||||
|
if (isnan(relative)) {
|
||||||
|
absolute = NAN;
|
||||||
Log.error("Error reading humidity!");
|
Log.error("Error reading humidity!");
|
||||||
} else {
|
} else {
|
||||||
mqttPublishValue(name + "/humidity/relative", event.relative_humidity, "HUMIDITY_RELATIVE_PERCENT");
|
mqttPublishValue(name + "/humidity/relative", relative, "HUMIDITY_RELATIVE_PERCENT");
|
||||||
if (!isnan(temperature)) {
|
if (!isnan(temperature)) {
|
||||||
double absHumid = calculateHumidityAbsolute(event.temperature, event.relative_humidity);
|
absolute = calculateHumidityAbsolute(temperature, relative);
|
||||||
mqttPublishValue(name + "/humidity/absolute", absHumid, "HUMIDITY_ABSOLUTE_GM3");
|
mqttPublishValue(name + "/humidity/absolute", absolute, "HUMIDITY_ABSOLUTE_GM3");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,16 +65,16 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static double calculateHumidityAbsolute(const double temperature, const double humidityRelative) {
|
[[nodiscard]] double getTemperature() const {
|
||||||
constexpr auto A = 6.112;
|
return temperature;
|
||||||
constexpr auto m = 17.67;
|
}
|
||||||
constexpr auto Tn = 243.5;
|
|
||||||
constexpr auto Mw = 18.01534;
|
[[nodiscard]] double getRelative() const {
|
||||||
constexpr auto R = 8.314462618;
|
return relative;
|
||||||
const auto Tk = temperature + 273.15;
|
}
|
||||||
const auto P_sat = A * exp((m * temperature) / (temperature + Tn));
|
|
||||||
const auto P_act = P_sat * (humidityRelative / 100.0);
|
[[nodiscard]] double getAbsolute() const {
|
||||||
return (P_act * Mw) / (R * Tk);
|
return absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#define BME680_H
|
#define BME680_H
|
||||||
|
|
||||||
#include "Adafruit_BME680.h"
|
#include "Adafruit_BME680.h"
|
||||||
|
#include "humidityRelative.h"
|
||||||
#include "mqtt.h"
|
#include "mqtt.h"
|
||||||
|
|
||||||
class BME680 {
|
class BME680 {
|
||||||
@ -59,18 +60,6 @@ public:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static double calculateHumidityAbsolute(const double temperature, const double humidityRelative) {
|
|
||||||
constexpr auto A = 6.112;
|
|
||||||
constexpr auto m = 17.67;
|
|
||||||
constexpr auto Tn = 243.5;
|
|
||||||
constexpr auto Mw = 18.01534;
|
|
||||||
constexpr auto R = 8.314462618;
|
|
||||||
const auto Tk = temperature + 273.15;
|
|
||||||
const auto P_sat = A * exp((m * temperature) / (temperature + Tn));
|
|
||||||
const auto P_act = P_sat * (humidityRelative / 100.0);
|
|
||||||
return (P_act * Mw) / (R * Tk);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "Adafruit_BMP280.h"
|
#include "Adafruit_BMP280.h"
|
||||||
#include "Adafruit_AHTX0.h"
|
#include "Adafruit_AHTX0.h"
|
||||||
|
#include "humidityRelative.h"
|
||||||
#include "mqtt.h"
|
#include "mqtt.h"
|
||||||
|
|
||||||
class BMP280_AHT20 {
|
class BMP280_AHT20 {
|
||||||
@ -88,18 +89,6 @@ public:
|
|||||||
mqttPublishValue(name + "/absolute", absolute, "HUMIDITY_ABSOLUTE_GM3");
|
mqttPublishValue(name + "/absolute", absolute, "HUMIDITY_ABSOLUTE_GM3");
|
||||||
}
|
}
|
||||||
|
|
||||||
static double calculateHumidityAbsolute(const double temperature, const double humidityRelative) {
|
|
||||||
constexpr auto A = 6.112;
|
|
||||||
constexpr auto m = 17.67;
|
|
||||||
constexpr auto Tn = 243.5;
|
|
||||||
constexpr auto Mw = 18.01534;
|
|
||||||
constexpr auto R = 8.314462618;
|
|
||||||
const auto Tk = temperature + 273.15;
|
|
||||||
const auto P_sat = A * exp((m * temperature) / (temperature + Tn));
|
|
||||||
const auto P_act = P_sat * (humidityRelative / 100.0);
|
|
||||||
return (P_act * Mw) / (R * Tk);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
15
src/patrix/humidityRelative.cpp
Normal file
15
src/patrix/humidityRelative.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include "humidityRelative.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
double calculateHumidityAbsolute(const double temperatureCelsius, const double humidityRelativePercent) {
|
||||||
|
constexpr auto A = 6.112;
|
||||||
|
constexpr auto m = 17.67;
|
||||||
|
constexpr auto Tn = 243.5;
|
||||||
|
constexpr auto Mw = 18.01534;
|
||||||
|
constexpr auto R = 8.314462618;
|
||||||
|
const auto Tk = temperatureCelsius + 273.15;
|
||||||
|
const auto P_sat = A * exp((m * temperatureCelsius) / (temperatureCelsius + Tn));
|
||||||
|
const auto P_act = P_sat * humidityRelativePercent;
|
||||||
|
return (P_act * Mw) / (R * Tk);
|
||||||
|
}
|
||||||
6
src/patrix/humidityRelative.h
Normal file
6
src/patrix/humidityRelative.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef HUMIDITY_RELATIVE_H
|
||||||
|
#define HUMIDITY_RELATIVE_H
|
||||||
|
|
||||||
|
double calculateHumidityAbsolute(double temperatureCelsius, double humidityRelativePercent);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -10,6 +10,8 @@ class TSL2561 {
|
|||||||
|
|
||||||
unsigned long last = 0UL;
|
unsigned long last = 0UL;
|
||||||
|
|
||||||
|
int64_t illuminance = -1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
const String name;
|
const String name;
|
||||||
@ -38,14 +40,19 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] int64_t getIlluminance() const {
|
||||||
|
return illuminance;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void read() {
|
void read() {
|
||||||
uint16_t broadband;
|
uint16_t broadband;
|
||||||
uint16_t ir;
|
uint16_t ir;
|
||||||
tsl.getLuminosity(&broadband, &ir);
|
tsl.getLuminosity(&broadband, &ir);
|
||||||
const auto illuminance = tsl.calculateLux(broadband, ir);
|
illuminance = tsl.calculateLux(broadband, ir);
|
||||||
if (illuminance == 65536) {
|
if (illuminance == 65536) {
|
||||||
|
illuminance = -1;
|
||||||
Log.error("TSL2561 \"%s\": Failed to read.", name.c_str());
|
Log.error("TSL2561 \"%s\": Failed to read.", name.c_str());
|
||||||
setup();
|
setup();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user