Compare commits
6 Commits
standalone
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
02a5095bf6 | ||
|
210222799a | ||
|
c93c76ab52 | ||
|
33ef6bc21b | ||
|
c0aa9c8da1 | ||
|
21ba43bbf9 |
@ -54,15 +54,7 @@ The following pins are used:
|
||||
* BMP280 sensor
|
||||
* some wire
|
||||
|
||||
# Webserver
|
||||
|
||||
This version has a webserver activated, if MQTT server is set to **localhost**.
|
||||
|
||||
Every 20 seconds a measurement is performed.
|
||||
This is shown in a diagram via chart.js
|
||||
|
||||
# Sources
|
||||
For the Witty board
|
||||
* [https://github.com/amkuipers/witty Witty pinout]
|
||||
* [https://arduino.ua/products_pictures/large_AOC361-5.jpg Schematics]
|
||||
* [https://www.chartjs.org/docs/latest/getting-started/integration.html]
|
||||
|
@ -1,37 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<title>IKEA Home Sensor Diagram</title>
|
||||
<script src="/chart.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function onBodyLoad(){
|
||||
|
||||
const xhttp = new XMLHttpRequest();
|
||||
xhttp.responseType = 'json';
|
||||
xhttp.onload = function() {
|
||||
var jsonResponse = this.response;
|
||||
console.log("JSON received");
|
||||
const ctx = document.getElementById('myChart');
|
||||
const myChart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: jsonResponse,
|
||||
options: {
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: false
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
console.log("Diagram generated");
|
||||
}
|
||||
xhttp.open("GET", "/diagram", true);
|
||||
xhttp.send();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body id="body" onload="onBodyLoad()">
|
||||
<canvas id="myChart" width="100%" height="100"></canvas>
|
||||
</body>
|
||||
</html>
|
13
data/chart.min.js
vendored
13
data/chart.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,96 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<title>IKEA Home Sensor</title>
|
||||
<style type="text/css">
|
||||
tr.heading td {
|
||||
background-color: black; color: white;
|
||||
}
|
||||
tr.d0 td {
|
||||
background-color: #ffffff; color: black;
|
||||
}
|
||||
tr.d1 td {
|
||||
background-color: #b8b8b8; color: black;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function mySensorTimer(){
|
||||
const xhttp = new XMLHttpRequest();
|
||||
xhttp.responseType = 'json';
|
||||
xhttp.onload = function() {
|
||||
var jsonResponse = this.response;
|
||||
document.getElementById("temp").innerHTML = jsonResponse.temp
|
||||
document.getElementById("altitude").innerHTML = jsonResponse.altitude;
|
||||
document.getElementById("pressure").innerHTML = jsonResponse.pressure;
|
||||
document.getElementById("particle").innerHTML = jsonResponse.particle;
|
||||
if (jsonResponse.gas) {
|
||||
document.getElementById("gas").innerHTML = jsonResponse.gas;
|
||||
} else {
|
||||
document.getElementById("rowGas").hidden = true;
|
||||
}
|
||||
if (jsonResponse.humidity) {
|
||||
document.getElementById("humidity").innerHTML = jsonResponse.humidity;
|
||||
} else {
|
||||
document.getElementById("rowHumidity").hidden = true;
|
||||
}
|
||||
console.log(this.responseText);
|
||||
}
|
||||
xhttp.open("GET", "/sensors", true);
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
function onBodyLoad(){
|
||||
setInterval(mySensorTimer, 5000);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body id="body" onload="onBodyLoad()">
|
||||
<h1>Room Sensor</h1>
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="heading">
|
||||
<td>Sensor</td>
|
||||
<td>Value</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="d0">
|
||||
<td>Temperatur</td>
|
||||
<td id="temp">temp</td>
|
||||
<td>°C</td>
|
||||
</tr>
|
||||
<tr id="rowHumidity" class="d1">
|
||||
<td>Humidity</td>
|
||||
<td id="humidity">humidity</td>
|
||||
<td>%</td>
|
||||
</tr>
|
||||
<tr id="rowGas" class="d0">
|
||||
<td>Gas</td>
|
||||
<td id="gas">gas</td>
|
||||
<td> KOhms</td>
|
||||
</tr>
|
||||
<tr class="d1">
|
||||
<td>Altitude</td>
|
||||
<td id="altitude">altitude</td>
|
||||
<td>m</td>
|
||||
</tr>
|
||||
<tr class="d0">
|
||||
<td>Pressure</td>
|
||||
<td id="pressure">pressure</td>
|
||||
<td>hPa</td>
|
||||
</tr>
|
||||
<tr class="d1">
|
||||
<td>Particle</td>
|
||||
<td id="particle">particle</td>
|
||||
<td>micro gram per quibik</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h1>Diagram</h1>
|
||||
<p>
|
||||
Can be found on the <a href="chart.htm">next page</a>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -13,6 +13,6 @@
|
||||
#define HOMIE_SETTINGS
|
||||
|
||||
#define HOMIE_FIRMWARE_NAME "RoomSensor"
|
||||
#define HOMIE_FIRMWARE_VERSION "2.2.0"
|
||||
#define HOMIE_FIRMWARE_VERSION "2.3.0"
|
||||
|
||||
#endif
|
||||
|
@ -12,7 +12,7 @@
|
||||
platform = espressif8266
|
||||
board = d1_mini
|
||||
framework = arduino
|
||||
build_flags = -D PIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY -DBMP280
|
||||
build_flags = -D PIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY -D BME680
|
||||
; build_flag needs define the Bosch sensor...
|
||||
; -D BMP280
|
||||
;or
|
||||
@ -25,4 +25,4 @@ lib_deps = https://github.com/homieiot/homie-esp8266.git#develop
|
||||
adafruit/Adafruit BMP280 Library @ ^2.4.2
|
||||
adafruit/Adafruit BME680 Library @ ^2.0.1
|
||||
|
||||
upload_port = /dev/ttyUSB1
|
||||
upload_port = /dev/ttyUSB0
|
287
src/main.cpp
287
src/main.cpp
@ -20,7 +20,7 @@
|
||||
#include <Adafruit_Sensor.h>
|
||||
#ifdef BME680
|
||||
#include "Adafruit_BME680.h"
|
||||
#else
|
||||
#else
|
||||
#ifdef BMP280
|
||||
#include "Adafruit_BMP280.h"
|
||||
#else
|
||||
@ -51,6 +51,9 @@
|
||||
#define BUTTON_MIN_ACTION_CYCLE 55U /**< Minimum cycle to react on the button (e.g. 5 second) */
|
||||
#define BUTTON_CHECK_INTERVALL 100U /**< Check every 100 ms the button state */
|
||||
|
||||
#define MIN_MEASURED_CYCLES 2
|
||||
#define PM_MAX 1001 /**< According datasheet https://en.gassensor.com.cn/ParticulateMatterSensor/info_itemid_105.html 1000 is the maximum */
|
||||
|
||||
#define LOG_TOPIC "log\0"
|
||||
#define MQTT_LEVEL_ERROR 1
|
||||
#define MQTT_LEVEL_WARNING 10
|
||||
@ -81,29 +84,12 @@
|
||||
#define NODE_GAS "gas"
|
||||
#define NODE_HUMIDITY "humidity"
|
||||
#define NODE_AMBIENT "ambient"
|
||||
|
||||
#define NODE_BUTTON "button"
|
||||
|
||||
#define PORTNUMBER_HTTP 80 /**< IANA TCP/IP port number, used for HTTP / web traffic */
|
||||
|
||||
#define SERIAL_RCEVBUF_MAX 80 /**< Maximum 80 characters can be received from the PM1006 sensor */
|
||||
#define MEASURE_POINT_MAX 1024 /**< Amount of measure point, that can be stored */
|
||||
|
||||
/******************************************************************************
|
||||
* TYPE DEFS
|
||||
******************************************************************************/
|
||||
|
||||
typedef struct s_point {
|
||||
long timestamp;
|
||||
float temp;
|
||||
#ifdef BME680
|
||||
uint32_t gas;
|
||||
float humidity;
|
||||
#endif
|
||||
float pressure;
|
||||
int pm25;
|
||||
} sensor_point;
|
||||
|
||||
/******************************************************************************
|
||||
* FUNCTION PROTOTYPES
|
||||
******************************************************************************/
|
||||
@ -116,8 +102,8 @@ void log(int level, String message, int code);
|
||||
|
||||
bool mConfigured = false;
|
||||
bool mConnected = false;
|
||||
bool mOTAactive = false; /**< Stop sleeping, if OTA is running */
|
||||
bool mFailedI2Cinitialization = false;
|
||||
AsyncWebServer* mHttp = NULL;
|
||||
long mLastButtonAction = 0;
|
||||
|
||||
/******************************* Sensor data **************************/
|
||||
@ -149,6 +135,7 @@ HomieSetting<bool> i2cEnable("i2c",
|
||||
);
|
||||
HomieSetting<bool> rgbTemp("rgbTemp", "Show temperature via red (>20 °C) and blue (< 20°C)");
|
||||
HomieSetting<long> rgbDim("rgbDim", "Factor (1 to 200%) of the status LEDs");
|
||||
HomieSetting<long> deepsleep("deepsleep", "Amount of seconds to sleep (default 0 - always online, maximum 4294 - 71 minutes)");
|
||||
|
||||
static SoftwareSerial pmSerial(SENSOR_PM1006_RX, SENSOR_PM1006_TX);
|
||||
#ifdef BME680
|
||||
@ -168,9 +155,7 @@ int mParticle_pM25 = 0;
|
||||
int last = 0;
|
||||
unsigned int mButtonPressed = 0;
|
||||
bool mSomethingReceived = false;
|
||||
bool mConnectedNonMQTT = false;
|
||||
|
||||
sensor_point* mMeasureSeries;
|
||||
uint32_t mMeasureIndex = 0;
|
||||
|
||||
/******************************************************************************
|
||||
@ -211,7 +196,12 @@ int getSensorData() {
|
||||
// Header und Prüfsumme checken
|
||||
if (serialRxBuf[0] == 0x16 && serialRxBuf[1] == 0x11 && serialRxBuf[2] == 0x0B /* && checksum == 0 */)
|
||||
{
|
||||
return (serialRxBuf[5] << 8 | serialRxBuf[6]);
|
||||
int pmValue = (serialRxBuf[5] << 8 | serialRxBuf[6]);
|
||||
if (pmValue > PM_MAX) {
|
||||
return (-1);
|
||||
} else {
|
||||
return pmValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -227,22 +217,29 @@ void onHomieEvent(const HomieEvent &event)
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case HomieEventType::WIFI_CONNECTED:
|
||||
case HomieEventType::READY_TO_SLEEP:
|
||||
if (mOTAactive) {
|
||||
Homie.getLogger() << "Skip sleeping, as OTA was started" << endl;
|
||||
return;
|
||||
} else if (deepsleep.get() > 0) {
|
||||
long sleepInSeconds = deepsleep.get();
|
||||
Homie.doDeepSleep(sleepInSeconds * 1000000, RF_NO_CAL);
|
||||
}
|
||||
break;
|
||||
case HomieEventType::MQTT_READY:
|
||||
mConnected=true;
|
||||
digitalWrite(WITTY_RGB_R, LOW);
|
||||
if (!i2cEnable.get()) { /** keep green LED activated to power I2C sensor */
|
||||
digitalWrite(WITTY_RGB_G, LOW);
|
||||
log(MQTT_LEVEL_INFO, F("I2C powersupply deactivated"), MQTT_LOG_I2CINIT);
|
||||
}
|
||||
digitalWrite(WITTY_RGB_B, LOW);
|
||||
strip.fill(strip.Color(0,0,128));
|
||||
strip.show();
|
||||
if (mHttp != NULL) {
|
||||
strip.fill(strip.Color(0,64,0));
|
||||
mConnectedNonMQTT = true;
|
||||
/* Update LED only, if not sleeping */
|
||||
if (deepsleep.get() <= 0) {
|
||||
strip.fill(strip.Color(0,0,PERCENT2FACTOR(127, rgbDim)));
|
||||
strip.show();
|
||||
}
|
||||
break;
|
||||
case HomieEventType::MQTT_READY:
|
||||
mConnected=true;
|
||||
|
||||
if (mFailedI2Cinitialization) {
|
||||
log(MQTT_LEVEL_DEBUG,
|
||||
#ifdef BME680
|
||||
@ -259,42 +256,29 @@ void onHomieEvent(const HomieEvent &event)
|
||||
log(MQTT_LEVEL_INFO, F("BME680 sensor found"), MQTT_LOG_I2CINIT);
|
||||
}
|
||||
break;
|
||||
case HomieEventType::READY_TO_SLEEP:
|
||||
break;
|
||||
case HomieEventType::OTA_STARTED:
|
||||
mOTAactive = true;
|
||||
break;
|
||||
case HomieEventType::OTA_SUCCESSFUL:
|
||||
ESP.restart();
|
||||
break;
|
||||
case HomieEventType::WIFI_CONNECTED:
|
||||
digitalWrite(WITTY_RGB_B, HIGH);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void updateLEDs() {
|
||||
void bmpPublishValues() {
|
||||
#ifdef BME680
|
||||
// Tell BME680 to begin measurement.
|
||||
unsigned long endTime = bmx.beginReading();
|
||||
if (endTime == 0) {
|
||||
log(MQTT_LEVEL_ERROR, "BME680 not accessible", MQTT_LOG_I2READ);
|
||||
log(MQTT_LEVEL_ERROR, "BMX not accessible", MQTT_LOG_I2READ);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if ( (rgbTemp.get()) && (!mSomethingReceived) ) {
|
||||
if (bmx.readTemperature() < TEMPBORDER) {
|
||||
strip.setPixelColor(0, strip.Color(0,0,255));
|
||||
} else {
|
||||
strip.setPixelColor(0, strip.Color(255,0,0));
|
||||
}
|
||||
strip.show();
|
||||
} else {
|
||||
#ifdef BME680
|
||||
bmx.performReading();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void bmpPublishValues() {
|
||||
// Publish the values
|
||||
temperaturNode.setProperty(NODE_TEMPERATUR).send(String(bmx.readTemperature()));
|
||||
pressureNode.setProperty(NODE_PRESSURE).send(String(bmx.readPressure() / 100.0F));
|
||||
@ -316,130 +300,6 @@ void bmpPublishValues() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generate JSON with last measured values
|
||||
* For the update interval, please check @see PM1006_MQTT_UPDATE
|
||||
* @return String with JSON
|
||||
*/
|
||||
String sensorAsJSON(void) {
|
||||
String buffer;
|
||||
StaticJsonDocument<500> doc;
|
||||
|
||||
if (mMeasureIndex > 0) {
|
||||
int lastIdx = mMeasureIndex - 1;
|
||||
doc["temp"] = String(mMeasureSeries[lastIdx].temp);
|
||||
#ifdef BME680
|
||||
doc["gas"] = String(mMeasureSeries[lastIdx].gas);
|
||||
doc["humidity"] = String(mMeasureSeries[lastIdx].humidity);
|
||||
#endif
|
||||
float atmospheric = mMeasureSeries[lastIdx].pressure;
|
||||
float altitude = 44330.0 * (1.0 - pow(atmospheric / SEALEVELPRESSURE_HPA, 0.1903));
|
||||
doc["altitude"] = String(altitude);
|
||||
doc["pressure"] = String(atmospheric);
|
||||
doc["particle"] = String(mMeasureSeries[lastIdx].pm25);
|
||||
}
|
||||
doc["cycle"] = String(mMeasureIndex);
|
||||
serializeJson(doc, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generate JSON with all available sensors
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
String sensorHeader(void) {
|
||||
String buffer;
|
||||
StaticJsonDocument<500> doc;
|
||||
doc.add("milli");
|
||||
doc.add("temp");
|
||||
#ifdef BME680
|
||||
doc.add("gas");
|
||||
doc.add("humidity");
|
||||
#endif
|
||||
doc.add("altitude");
|
||||
doc.add("pressure");
|
||||
doc.add("particle");
|
||||
serializeJson(doc, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generate JSON with all sensor values
|
||||
* Array of JSON with all measured elements to show in the web browser.
|
||||
* Example:
|
||||
* <code>
|
||||
* dynamicData = {
|
||||
* labels: [ "0", "-30", "-60", "-90", "-120", "-160" ],
|
||||
* datasets: [{
|
||||
* label: 'temp',
|
||||
* data: [24, 22, 23, 25, 22, 23],
|
||||
* borderColor: "rgba(255,0,0,1)"
|
||||
* }, {
|
||||
* label: 'pressure',
|
||||
* data: [1000, 1002, 1003, 999, 996, 1000],
|
||||
* borderColor: "rgba(0,0,255,1)"
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
String diagramJson(void) {
|
||||
int i;
|
||||
String buffer;
|
||||
String bufferLabels = "\"\"";
|
||||
String bufferDataTemp = "\"\"";
|
||||
String bufferDataPressure = "\"\"";
|
||||
String bufferDataPM = "\"\"";
|
||||
String bufferDatasets;
|
||||
String bufferData;
|
||||
if (mMeasureSeries == NULL) {
|
||||
buffer = "{ \"error\": \"Malloc failed\" }";
|
||||
return buffer;
|
||||
}
|
||||
|
||||
long now = millis();
|
||||
if (mMeasureIndex > 0) {
|
||||
bufferLabels = "[ \"" + String((now - mMeasureSeries[0].timestamp) / 1000) + "s";
|
||||
bufferDataTemp = "[ \"" + String(mMeasureSeries[0].temp);
|
||||
bufferDataPressure = "[ \"" + String(mMeasureSeries[0].pressure);
|
||||
bufferDataPM = "[ \"" + String(mMeasureSeries[0].pm25);
|
||||
}
|
||||
for(i=1; i < mMeasureIndex; i++) {
|
||||
bufferLabels += "\", \"" + String((now - mMeasureSeries[i].timestamp) / 1000) + "s";
|
||||
bufferDataTemp += "\", \"" + String(mMeasureSeries[i].temp);
|
||||
bufferDataPressure += "\", \"" + String(mMeasureSeries[i].pressure);
|
||||
bufferDataPM += "\", \"" + String(mMeasureSeries[i].pm25);
|
||||
}
|
||||
if (mMeasureIndex > 0) {
|
||||
bufferLabels += "\" ]";
|
||||
bufferDataTemp += "\" ]";
|
||||
bufferDataPressure += "\" ]";
|
||||
bufferDataPM += "\" ]";
|
||||
}
|
||||
/* Generate label */
|
||||
buffer = "{ \"labels\" : " + bufferLabels + ",\n";
|
||||
buffer += "\"datasets\" : [";
|
||||
|
||||
/* generate first block for Temperature */
|
||||
buffer += "{\n \"label\" : \"Temp\",\n \"data\" : " + bufferDataTemp + ",\n \"borderColor\" : \"rgba(255,0,0,1)\" \n}";
|
||||
|
||||
/* generate second block for Pressure */
|
||||
buffer += ", ";
|
||||
buffer += "{\n \"label\" : \"Pressure\",\n \"data\" : " + bufferDataPressure + ",\n \"borderColor\" : \"rgba(0,0,255,1)\" \n}";
|
||||
|
||||
/* generate third block for PM2.5 values */
|
||||
buffer += ", ";
|
||||
buffer += "{\n \"label\" : \"PM 2.5\",\n \"data\" : " + bufferDataPM + ",\n \"borderColor\" : \"rgba(0,255,0,1)\" \n}";
|
||||
|
||||
/* TODO, next ones ... */
|
||||
|
||||
buffer += "]\n }";
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main loop, triggered by the Homie API
|
||||
* All logic needs to be done here.
|
||||
@ -457,9 +317,7 @@ void loopHandler()
|
||||
if ((millis() - lastRead) > PM1006_MQTT_UPDATE) {
|
||||
mParticle_pM25 = getSensorData();
|
||||
if (mParticle_pM25 >= 0) {
|
||||
if (!mConnectedNonMQTT) {
|
||||
particle.setProperty(NODE_PARTICLE).send(String(mParticle_pM25));
|
||||
}
|
||||
if (!mSomethingReceived) {
|
||||
if (mParticle_pM25 < 35) {
|
||||
strip.fill(strip.Color(0, PERCENT2FACTOR(127, rgbDim), 0)); /* green */
|
||||
@ -474,35 +332,27 @@ void loopHandler()
|
||||
|
||||
/* Read BOSCH sensor */
|
||||
if (i2cEnable.get() && (!mFailedI2Cinitialization)) {
|
||||
updateLEDs();
|
||||
if (!mConnectedNonMQTT) {
|
||||
bmpPublishValues();
|
||||
}
|
||||
bmpPublishValues();
|
||||
}
|
||||
|
||||
// FIXME: add the measured data into the big list
|
||||
if (mMeasureSeries != NULL) {
|
||||
mMeasureSeries[mMeasureIndex].timestamp = millis();
|
||||
mMeasureSeries[mMeasureIndex].temp = bmx.readTemperature();
|
||||
#ifdef BME680
|
||||
mMeasureSeries[mMeasureIndex].gas = (bmx.gas_resistance / 1000.0);
|
||||
mMeasureSeries[mMeasureIndex].humidity = bmx.humidity;
|
||||
#endif
|
||||
float atmospheric = bmx.readPressure() / 100.0F;
|
||||
mMeasureSeries[mMeasureIndex].pressure = atmospheric;
|
||||
mMeasureSeries[mMeasureIndex].pm25 = mParticle_pM25;
|
||||
mMeasureIndex++;
|
||||
}
|
||||
mMeasureIndex++;
|
||||
|
||||
/* Clean cycles buttons */
|
||||
if ((!mConnectedNonMQTT) && (mButtonPressed <= BUTTON_MIN_ACTION_CYCLE)) {
|
||||
if (mButtonPressed <= BUTTON_MIN_ACTION_CYCLE) {
|
||||
buttonNode.setProperty(NODE_BUTTON).send("0");
|
||||
}
|
||||
lastRead = millis();
|
||||
|
||||
/* If nothing needs to be done, sleep and the time is ready for sleeping */
|
||||
if (mMeasureIndex > MIN_MEASURED_CYCLES && (deepsleep.get() > 0) ) {
|
||||
Homie.prepareToSleep();
|
||||
delay(100);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* if the user sees something via the LEDs, inform MQTT, too */
|
||||
if ((!mConnectedNonMQTT) && (mButtonPressed > BUTTON_MIN_ACTION_CYCLE)) {
|
||||
if (mButtonPressed > BUTTON_MIN_ACTION_CYCLE) {
|
||||
buttonNode.setProperty(NODE_BUTTON).send(String(mButtonPressed));
|
||||
}
|
||||
|
||||
@ -543,6 +393,8 @@ bool ledHandler(const HomieRange& range, const String& value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GLOBAL FUNCTIONS
|
||||
*****************************************************************************/
|
||||
@ -562,11 +414,14 @@ void setup()
|
||||
Homie_setFirmware(HOMIE_FIRMWARE_NAME, HOMIE_FIRMWARE_VERSION);
|
||||
Homie.setLoopFunction(loopHandler);
|
||||
Homie.onEvent(onHomieEvent);
|
||||
i2cEnable.setDefaultValue(true);
|
||||
i2cEnable.setDefaultValue(false);
|
||||
rgbTemp.setDefaultValue(false);
|
||||
rgbDim.setDefaultValue(100).setValidator([] (long candidate) {
|
||||
return (candidate > 1) && (candidate <= 200);
|
||||
});
|
||||
deepsleep.setDefaultValue(0).setValidator([] (long candidate) {
|
||||
return ((candidate >= 0) && (candidate < 4294)); /* between 0 (deactivated) and 71 minutes */
|
||||
});
|
||||
memset(serialRxBuf, 0, SERIAL_RCEVBUF_MAX);
|
||||
|
||||
pmSerial.begin(PM1006_BIT_RATE);
|
||||
@ -602,8 +457,6 @@ void setup()
|
||||
digitalWrite(WITTY_RGB_G, HIGH);
|
||||
if (mConfigured)
|
||||
{
|
||||
mMeasureSeries = (sensor_point *) malloc(sizeof(sensor_point) * MEASURE_POINT_MAX);
|
||||
memset(mMeasureSeries, 0, sizeof(sensor_point) * MEASURE_POINT_MAX);
|
||||
if (i2cEnable.get()) {
|
||||
#ifdef BME680
|
||||
printf("Wait 1 second...\r\n");
|
||||
@ -638,39 +491,27 @@ void setup()
|
||||
printf("Failed to initialize I2C bus\r\n");
|
||||
}
|
||||
}
|
||||
strip.fill(strip.Color(0,0,0));
|
||||
|
||||
/* Nothing when sleeping */
|
||||
if (deepsleep.get() <= 0) {
|
||||
strip.fill(strip.Color(0,0,0));
|
||||
for (int i=0;i < (PIXEL_COUNT / 2); i++) {
|
||||
strip.setPixelColor(0, strip.Color(0,128,0));
|
||||
strip.setPixelColor(0, strip.Color(0,0,128 * rgbDim.get()));
|
||||
}
|
||||
mHttp = new AsyncWebServer(PORTNUMBER_HTTP);
|
||||
mHttp->on("/heap", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(200, "text/plain", String(ESP.getFreeHeap()));
|
||||
});
|
||||
mHttp->on("/sensors", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(200, "application/json", sensorAsJSON());
|
||||
});
|
||||
mHttp->on("/header", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(200, "application/json", sensorHeader());
|
||||
});
|
||||
mHttp->on("/diagram", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(200, "application/json", diagramJson());
|
||||
});
|
||||
mHttp->serveStatic("/", SPIFFS, "/").setDefaultFile("standalone.htm");
|
||||
mHttp->begin();
|
||||
Homie.getLogger() << "Webserver started" << endl;
|
||||
strip.show();
|
||||
}
|
||||
} else {
|
||||
digitalWrite(WITTY_RGB_R, HIGH);
|
||||
strip.fill(strip.Color(128,0,0));
|
||||
for (int i=0;i < (PIXEL_COUNT / 2); i++) {
|
||||
strip.setPixelColor(0, strip.Color(0,0,128));
|
||||
}
|
||||
strip.show();
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (!mConnectedNonMQTT) {
|
||||
Homie.loop();
|
||||
} else {
|
||||
/* call the custom loop directly, as Homie is deactivated */
|
||||
loopHandler();
|
||||
}
|
||||
Homie.loop();
|
||||
/* use the pin, receiving the soft serial additionally as button */
|
||||
if (digitalRead(GPIO_BUTTON) == LOW) {
|
||||
if ((millis() - mLastButtonAction) > BUTTON_CHECK_INTERVALL) {
|
||||
|
Loading…
Reference in New Issue
Block a user