Refactor globals/mqtt (#521)
This commit is contained in:
parent
5f4cf7fa3c
commit
cec2c719c3
|
@ -1,5 +1,6 @@
|
|||
#include <regex>
|
||||
#include <string_utils.h>
|
||||
#include <SPIFFS.h>
|
||||
|
||||
std::string ltrim(const std::string &s, char toTrim)
|
||||
{
|
||||
|
@ -106,3 +107,12 @@ bool prefixExists(const String &prefixes, const String &s)
|
|||
auto sub = prefixes.substring(start);
|
||||
return !sub.isEmpty() && s.indexOf(sub) != -1;
|
||||
}
|
||||
|
||||
bool spurt(const String &fn, const String &content)
|
||||
{
|
||||
File f = SPIFFS.open(fn, "w");
|
||||
if (!f) return false;
|
||||
auto w = f.print(content);
|
||||
f.close();
|
||||
return w == content.length();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include <WString.h>
|
||||
#include <string>
|
||||
|
@ -26,3 +25,4 @@ std::string hexStrRev(const uint8_t *data, int len);
|
|||
std::string hexStrRev(const char *data, int len);
|
||||
std::string hexStrRev(const std::string &s);
|
||||
bool prefixExists(const String& prefixes, const String& s);
|
||||
bool spurt(const String &fn, const String &content);
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
#ifdef SENSORS
|
||||
#include "BH1750.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "mqtt.h"
|
||||
#include "defaults.h"
|
||||
#include <WiFiSettings.h>
|
||||
#include <AsyncMqttClient.h>
|
||||
#include "string_utils.h"
|
||||
|
||||
#include <hp_BH1750.h>
|
||||
|
||||
namespace BH1750
|
||||
{
|
||||
hp_BH1750 BH1750;
|
||||
unsigned long ms_BH1750;
|
||||
float lux_BH1750;
|
||||
int lux_BH1750_MQTT;
|
||||
String BH1750_I2c;
|
||||
int BH1750_I2c_Bus;
|
||||
bool initialized = false;
|
||||
|
||||
void Setup()
|
||||
{
|
||||
if (!I2C_Bus_1_Enabled && !I2C_Bus_2_Enabled) return;
|
||||
if (BH1750_I2c != "0x23" && BH1750_I2c != "0x5C") return;
|
||||
|
||||
int rc;
|
||||
unsigned long m; // milli for calibration
|
||||
bool state = false;
|
||||
|
||||
if (BH1750_I2c == "0x23" && BH1750_I2c_Bus == 1)
|
||||
{
|
||||
state = BH1750.begin(BH1750_TO_GROUND, &Wire);
|
||||
}
|
||||
else if (BH1750_I2c == "0x5C" && BH1750_I2c_Bus == 1)
|
||||
{
|
||||
state = BH1750.begin(BH1750_TO_VCC, &Wire);
|
||||
}
|
||||
else if (BH1750_I2c == "0x23" && BH1750_I2c_Bus == 2)
|
||||
{
|
||||
state = BH1750.begin(BH1750_TO_GROUND, &Wire1);
|
||||
}
|
||||
else if (BH1750_I2c == "0x5C" && BH1750_I2c_Bus == 2)
|
||||
{
|
||||
state = BH1750.begin(BH1750_TO_VCC, &Wire1);
|
||||
}
|
||||
|
||||
if (!state)
|
||||
{
|
||||
Serial.println("Error on initialisation BH1750 GY-302");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("initialisation BH1750 GY-302 success");
|
||||
m = millis();
|
||||
rc = BH1750.calibrateTiming();
|
||||
m = millis() - m;
|
||||
Serial.print("Lux Sensor BH1750 GY-302 calibrated (Time: ");
|
||||
Serial.print(m);
|
||||
Serial.print(" ms)");
|
||||
if (rc != 0)
|
||||
{
|
||||
Serial.print(" - Lux Sensor Error code ");
|
||||
Serial.print(rc);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
// start first measure and timecount
|
||||
lux_BH1750 = -1; // nothing to compare
|
||||
BH1750.start(BH1750_QUALITY_HIGH, 1);
|
||||
ms_BH1750 = millis();
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectToWifi()
|
||||
{
|
||||
WiFiSettings.html("h4", "BH1750 - Ambient Light Sensor:");
|
||||
BH1750_I2c_Bus = WiFiSettings.integer("BH1750_I2c_Bus", 1, 2, DEFAULT_I2C_BUS, "I2C Bus");
|
||||
BH1750_I2c = WiFiSettings.string("BH1750_I2c", "", "I2C address (0x23 or 0x5C)");
|
||||
}
|
||||
|
||||
void SerialReport()
|
||||
{
|
||||
Serial.print("BH1750_I2c Sensor: ");
|
||||
Serial.println(BH1750_I2c + " on bus " + BH1750_I2c_Bus);
|
||||
}
|
||||
|
||||
void Loop()
|
||||
{
|
||||
if (!I2C_Bus_1_Enabled && !I2C_Bus_2_Enabled) return;
|
||||
if (!initialized) return;
|
||||
|
||||
if (BH1750_I2c == "0x23" || BH1750_I2c == "0x5C")
|
||||
{
|
||||
float lux;
|
||||
int lux_mqtt;
|
||||
|
||||
if (BH1750.hasValue())
|
||||
{
|
||||
ms_BH1750 = millis() - ms_BH1750;
|
||||
if (!BH1750.saturated())
|
||||
{
|
||||
lux = BH1750.getLux();
|
||||
lux_mqtt = int(lux);
|
||||
|
||||
if (lux != lux_BH1750)
|
||||
{
|
||||
lux_BH1750 = lux;
|
||||
// Serial.print("BH1750 (");
|
||||
// Serial.print(ms_BH1750);
|
||||
// Serial.print(" ms): ");
|
||||
// Serial.print(lux);
|
||||
// Serial.println(" lx");
|
||||
}
|
||||
|
||||
//convert lx to integer to reduce mqtt traffic, send only if lx changed
|
||||
if (lux_mqtt != lux_BH1750_MQTT)
|
||||
{
|
||||
lux_BH1750_MQTT = lux_mqtt;
|
||||
Serial.print("BH1750 (");
|
||||
Serial.print(ms_BH1750);
|
||||
Serial.print(" ms): ");
|
||||
Serial.print(lux_mqtt);
|
||||
Serial.println(" lx");
|
||||
mqttClient.publish((roomsTopic + "/lux").c_str(), 0, 1, String(lux_mqtt).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
BH1750.adjustSettings(90);
|
||||
BH1750.start();
|
||||
ms_BH1750 = millis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SendDiscovery()
|
||||
{
|
||||
if (BH1750_I2c.isEmpty()) return true;
|
||||
|
||||
return sendSensorDiscovery("Lux", "", "illuminance", "lx");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
#ifdef SENSORS
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
// Forward declares
|
||||
class AsyncMqttClient;
|
||||
|
||||
namespace BH1750
|
||||
{
|
||||
void Setup();
|
||||
void ConnectToWifi();
|
||||
void SerialReport();
|
||||
void Loop();
|
||||
bool SendDiscovery();
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,24 +1,13 @@
|
|||
#ifdef SENSORS
|
||||
|
||||
#include "defaults.h"
|
||||
#include "BME280Sensor.h"
|
||||
#include <WiFiSettings.h>
|
||||
#include <AsyncMqttClient.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
|
||||
// for #define ESPMAC
|
||||
#include "globals.h"
|
||||
#include "mqtt.h"
|
||||
#include "defaults.h"
|
||||
#include <WiFiSettings.h>
|
||||
#include "string_utils.h"
|
||||
|
||||
// TODO: Not a fan of externs, but this helps refactoring for now
|
||||
extern bool I2C_Bus_1_Enabled;
|
||||
extern bool I2C_Bus_2_Enabled;
|
||||
extern unsigned long sensorInterval;
|
||||
|
||||
extern char buffer[2048];
|
||||
extern String room;
|
||||
extern String roomsTopic;
|
||||
extern void commonDiscovery();
|
||||
extern bool pub(const char *topic, uint8_t qos, bool retain, const char *payload, size_t length = 0, bool dup = false, uint16_t message_id = 0);
|
||||
#include <Adafruit_BME280.h>
|
||||
|
||||
namespace BME280
|
||||
{
|
||||
|
@ -27,10 +16,38 @@ namespace BME280
|
|||
String BME280_I2c;
|
||||
int BME280_I2c_Bus;
|
||||
unsigned long bme280PreviousMillis = 0;
|
||||
int sensorInterval = 60000;
|
||||
bool initialized = false;
|
||||
|
||||
void Setup()
|
||||
{
|
||||
if (!I2C_Bus_1_Enabled && !I2C_Bus_2_Enabled) return;
|
||||
|
||||
if (BME280_I2c == "0x76" && BME280_I2c_Bus == 1) {
|
||||
BME280_status = BME280.begin(0x76, &Wire);
|
||||
} else if (BME280_I2c == "0x77" && BME280_I2c_Bus == 1) {
|
||||
BME280_status = BME280.begin(0x77, &Wire);
|
||||
} else if (BME280_I2c == "0x76" && BME280_I2c_Bus == 2) {
|
||||
BME280_status = BME280.begin(0x76, &Wire1);
|
||||
} else if (BME280_I2c == "0x77" && BME280_I2c_Bus == 2) {
|
||||
BME280_status = BME280.begin(0x77, &Wire1);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!BME280_status) {
|
||||
Serial.println("[BME280] Couldn't find a sensor, check your wiring and I2C address!");
|
||||
} else {
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
BME280.setSampling(
|
||||
Adafruit_BME280::MODE_FORCED,
|
||||
Adafruit_BME280::SAMPLING_X1, // Temperature
|
||||
Adafruit_BME280::SAMPLING_X1, // Pressure
|
||||
Adafruit_BME280::SAMPLING_X1, // Humidity
|
||||
Adafruit_BME280::FILTER_OFF
|
||||
);
|
||||
}
|
||||
|
||||
void ConnectToWifi()
|
||||
|
@ -46,35 +63,10 @@ namespace BME280
|
|||
Serial.println(BME280_I2c + " on bus " + BME280_I2c_Bus);
|
||||
}
|
||||
|
||||
void Loop(AsyncMqttClient& mqttClient)
|
||||
void Loop()
|
||||
{
|
||||
if (!I2C_Bus_1_Enabled && !I2C_Bus_2_Enabled) return;
|
||||
|
||||
// TODO: This should move to setup
|
||||
if (BME280_I2c == "0x76" && BME280_I2c_Bus == 1) {
|
||||
BME280_status = BME280.begin(0x76, &Wire);
|
||||
} else if (BME280_I2c == "0x77" && BME280_I2c_Bus == 1) {
|
||||
BME280_status = BME280.begin(0x77, &Wire);
|
||||
} else if (BME280_I2c == "0x76" && BME280_I2c_Bus == 2) {
|
||||
BME280_status = BME280.begin(0x76, &Wire1);
|
||||
} else if (BME280_I2c == "0x77" && BME280_I2c_Bus == 2) {
|
||||
BME280_status = BME280.begin(0x77, &Wire1);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!BME280_status) {
|
||||
Serial.println("[BME280] Couldn't find a sensor, check your wiring and I2C address!");
|
||||
}
|
||||
|
||||
BME280.setSampling(
|
||||
Adafruit_BME280::MODE_FORCED,
|
||||
Adafruit_BME280::SAMPLING_X1, // Temperature
|
||||
Adafruit_BME280::SAMPLING_X1, // Pressure
|
||||
Adafruit_BME280::SAMPLING_X1, // Humidity
|
||||
//Adafruit_BME280::FILTER_X16,
|
||||
Adafruit_BME280::FILTER_OFF
|
||||
);
|
||||
if (!initialized) return;
|
||||
|
||||
float temperature = BME280.readTemperature();
|
||||
float humidity = BME280.readHumidity();
|
||||
|
@ -90,65 +82,13 @@ namespace BME280
|
|||
}
|
||||
}
|
||||
|
||||
static bool SendTemperature(DynamicJsonDocument& doc)
|
||||
{
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = "ESPresense " + room + " BME280 Temperature";
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_bme280_temperature", CHIPID);
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/bme280_temperature";
|
||||
doc["dev_cla"] = "temperature";
|
||||
doc["unit_of_meas"] = "°C";
|
||||
doc["frc_upd"] = true;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/sensor/espresense_" + ESPMAC + "/bme280_temperature/config";
|
||||
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
static bool SendHumidity(DynamicJsonDocument& doc)
|
||||
{
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = "ESPresense " + room + " BME280 Humidity";
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_bme280_humidity", CHIPID);
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/bme280_humidity";
|
||||
doc["dev_cla"] = "humidity";
|
||||
doc["unit_of_meas"] = "%";
|
||||
doc["frc_upd"] = true;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/sensor/espresense_" + ESPMAC + "/bme280_humidity/config";
|
||||
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
static bool SendPressure(DynamicJsonDocument& doc)
|
||||
{
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = "ESPresense " + room + " BME280 Pressure";
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_bme280_pressure", CHIPID);
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/bme280_pressure";
|
||||
doc["dev_cla"] = "pressure";
|
||||
doc["unit_of_meas"] = "hPa";
|
||||
doc["frc_upd"] = true;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/sensor/espresense_" + ESPMAC + "/bme280_pressure/config";
|
||||
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool SendDiscovery(DynamicJsonDocument& doc)
|
||||
bool SendDiscovery()
|
||||
{
|
||||
if (BME280_I2c.isEmpty()) return true;
|
||||
|
||||
return SendTemperature(doc) && SendHumidity(doc) && SendPressure(doc);
|
||||
return sendSensorDiscovery("BME Temperature", "", "temperature", "°C")
|
||||
&& sendSensorDiscovery("BME Humidity", "", "humidity", "%")
|
||||
&& sendSensorDiscovery("BME Pressure", "", "pressure", "hPa");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
#ifdef SENSORS
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
// Forward declares
|
||||
class AsyncMqttClient;
|
||||
|
||||
namespace BME280
|
||||
{
|
||||
void Setup();
|
||||
void ConnectToWifi();
|
||||
void SerialReport();
|
||||
void Loop(AsyncMqttClient& mqttClient);
|
||||
bool SendDiscovery(DynamicJsonDocument& doc);
|
||||
}
|
||||
|
||||
#endif
|
||||
#pragma once
|
||||
#ifdef SENSORS
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
namespace BME280
|
||||
{
|
||||
void Setup();
|
||||
void ConnectToWifi();
|
||||
void SerialReport();
|
||||
void Loop();
|
||||
bool SendDiscovery();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
#ifdef SENSORS
|
||||
#include "DHT.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "mqtt.h"
|
||||
#include "defaults.h"
|
||||
#include <WiFiSettings.h>
|
||||
#include <AsyncMqttClient.h>
|
||||
#include "string_utils.h"
|
||||
|
||||
#include <DHTesp.h>
|
||||
#include <Ticker.h>
|
||||
|
||||
namespace DHT
|
||||
{
|
||||
uint8_t dht11Pin;
|
||||
uint8_t dht22Pin;
|
||||
float dhtTempOffset;
|
||||
|
||||
/** Initialize DHT sensor 1 */
|
||||
DHTesp dhtSensor;
|
||||
|
||||
/** Task handle for the light value read task */
|
||||
TaskHandle_t dhtTempTaskHandle = NULL;
|
||||
|
||||
/** Ticker for temperature reading */
|
||||
Ticker tempTicker;
|
||||
|
||||
/** Flags for temperature readings finished */
|
||||
bool gotNewTemperature = false;
|
||||
|
||||
/** Data from dht sensor 1 */
|
||||
TempAndHumidity dhtSensorData;
|
||||
|
||||
/* Flag if main loop is running */
|
||||
bool dhtTasksEnabled = false;
|
||||
|
||||
/* update time */
|
||||
int dhtUpdateTime = 10; //ToDo: maybe make this a user choise via settings menu
|
||||
|
||||
/**
|
||||
* Task to reads temperature from DHT11 sensor
|
||||
* @param pvParameters
|
||||
* pointer to task parameters
|
||||
*/
|
||||
void tempTask(void *pvParameters)
|
||||
{
|
||||
Serial.println("tempTask loop started");
|
||||
while (1) // tempTask loop
|
||||
{
|
||||
if (dhtTasksEnabled && !gotNewTemperature)
|
||||
{
|
||||
// Read temperature only if old data was processed already
|
||||
// Reading temperature for humidity takes about 250 milliseconds!
|
||||
// Sensor readings may also be up to 2 seconds 'old' (it's a very slow sensor)
|
||||
dhtSensorData = dhtSensor.getTempAndHumidity(); // Read values from sensor 1
|
||||
gotNewTemperature = true;
|
||||
}
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* triggerGetTemp
|
||||
* Sets flag dhtUpdated to true for handling in loop()
|
||||
* called by Ticker tempTicker
|
||||
*/
|
||||
void triggerGetTemp()
|
||||
{
|
||||
if (dhtTempTaskHandle != NULL)
|
||||
{
|
||||
xTaskResumeFromISR(dhtTempTaskHandle);
|
||||
}
|
||||
}
|
||||
|
||||
void Setup()
|
||||
{
|
||||
if (dht11Pin) dhtSensor.setup(dht11Pin, DHTesp::DHT11);
|
||||
if (dht22Pin) dhtSensor.setup(dht22Pin, DHTesp::DHT22); //(AM2302)
|
||||
|
||||
if (dht11Pin || dht22Pin)
|
||||
{
|
||||
// Start task to get temperature
|
||||
xTaskCreatePinnedToCore(
|
||||
tempTask, /* Function to implement the task */
|
||||
"tempTask ", /* Name of the task */
|
||||
4000, /* Stack size in words */
|
||||
NULL, /* Task input parameter */
|
||||
5, /* Priority of the task */
|
||||
&dhtTempTaskHandle, /* Task handle. */
|
||||
1); /* Core where the task should run */
|
||||
|
||||
if (dhtTempTaskHandle == NULL)
|
||||
{
|
||||
Serial.println("[ERROR] Failed to start task for temperature update");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start update of environment data every 10 seconds
|
||||
tempTicker.attach(dhtUpdateTime, triggerGetTemp);
|
||||
}
|
||||
|
||||
// Signal end of setup() to tasks
|
||||
dhtTasksEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectToWifi()
|
||||
{
|
||||
dht11Pin = WiFiSettings.integer("dht11_pin", 0, "DHT11 sensor pin (0 for disable)");
|
||||
dht22Pin = WiFiSettings.integer("dht22_pin", 0, "DHT22 sensor pin (0 for disable)");
|
||||
dhtTempOffset = WiFiSettings.floating("dhtTemp_offset", -40, 125, 0.0, "DHT temperature offset");
|
||||
}
|
||||
|
||||
void SerialReport()
|
||||
{
|
||||
Serial.print("DHT11 Sensor: ");
|
||||
Serial.println(dht11Pin ? "enabled" : "disabled");
|
||||
Serial.print("DHT22 Sensor: ");
|
||||
Serial.println(dht22Pin ? "enabled" : "disabled");
|
||||
Serial.print("DHT Temp Offset: ");
|
||||
Serial.println(dhtTempOffset ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
void Loop()
|
||||
{
|
||||
if (!dht11Pin && !dht22Pin) return;
|
||||
|
||||
if (gotNewTemperature)
|
||||
{
|
||||
float humidity = dhtSensorData.humidity;
|
||||
float temperature = dhtSensorData.temperature + dhtTempOffset;
|
||||
Serial.println("Temp: " + String(temperature, 1) + "'C Humidity: " + String(humidity, 1) + "%");
|
||||
|
||||
mqttClient.publish((roomsTopic + "/humidity").c_str(), 0, 1, String(humidity, 1).c_str());
|
||||
mqttClient.publish((roomsTopic + "/temperature").c_str(), 0, 1, String(temperature, 1).c_str());
|
||||
|
||||
gotNewTemperature = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SendDiscovery()
|
||||
{
|
||||
if (!dht11Pin && !dht22Pin) return true;
|
||||
|
||||
return sendSensorDiscovery("Temperature", "", "temperature", "°C") && sendSensorDiscovery("Humidity", "", "humidity", "%");
|
||||
}
|
||||
|
||||
bool Command(String& command, String& pay)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SendOnline()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
#ifdef SENSORS
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
namespace DHT
|
||||
{
|
||||
void Setup();
|
||||
void ConnectToWifi();
|
||||
void SerialReport();
|
||||
void Loop();
|
||||
bool SendDiscovery();
|
||||
bool SendOnline();
|
||||
bool Command(String& command, String& pay);
|
||||
}
|
||||
#endif
|
|
@ -1,20 +1,13 @@
|
|||
#ifdef SENSORS
|
||||
|
||||
#include "defaults.h"
|
||||
#include "HX711.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "mqtt.h"
|
||||
#include "defaults.h"
|
||||
#include <WiFiSettings.h>
|
||||
#include <AsyncMqttClient.h>
|
||||
|
||||
// for #define ESPMAC
|
||||
#include "string_utils.h"
|
||||
|
||||
// TODO: Not a fan of externs, but this helps refactoring for now
|
||||
extern char buffer[2048];
|
||||
extern String room;
|
||||
extern String roomsTopic;
|
||||
extern void commonDiscovery();
|
||||
extern bool pub(const char *topic, uint8_t qos, bool retain, const char *payload, size_t length = 0, bool dup = false, uint16_t message_id = 0);
|
||||
|
||||
namespace HX711
|
||||
{
|
||||
int sckPin = 0;
|
||||
|
@ -45,7 +38,7 @@ namespace HX711
|
|||
Serial.println(String(sckPin) + "/" + String(doutPin));
|
||||
}
|
||||
|
||||
void Loop(AsyncMqttClient& mqttClient)
|
||||
void Loop()
|
||||
{
|
||||
if (!sckPin && !doutPin) return;
|
||||
if (millis() - lastMillis < sensorInterval) return;
|
||||
|
@ -83,26 +76,10 @@ namespace HX711
|
|||
pub((roomsTopic + "/raw_weight").c_str(), 0, true, String(data).c_str());
|
||||
}
|
||||
|
||||
static bool SendWeight(DynamicJsonDocument& doc)
|
||||
{
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = "ESPresense " + room + " Raw Weight";
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_raw_weight", CHIPID);
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/raw_weight";
|
||||
doc["frc_upd"] = true;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/sensor/espresense_" + ESPMAC + "/raw_weight/config";
|
||||
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool SendDiscovery(DynamicJsonDocument& doc)
|
||||
bool SendDiscovery()
|
||||
{
|
||||
if (!sckPin && !doutPin) return true;
|
||||
return SendWeight(doc);
|
||||
return sendSensorDiscovery("Raw Weight", "", "", "");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
18
src/HX711.h
18
src/HX711.h
|
@ -1,26 +1,14 @@
|
|||
#pragma once
|
||||
#ifdef SENSORS
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
// Forward declares
|
||||
class AsyncMqttClient;
|
||||
|
||||
namespace HX711
|
||||
{
|
||||
|
||||
enum HX711Gain {
|
||||
HX711_GAIN_128 = 1,
|
||||
HX711_GAIN_32 = 2,
|
||||
HX711_GAIN_64 = 3,
|
||||
};
|
||||
|
||||
void Setup();
|
||||
void ConnectToWifi();
|
||||
void SerialReport();
|
||||
void Loop(AsyncMqttClient& mqttClient);
|
||||
bool SendDiscovery(DynamicJsonDocument& doc);
|
||||
void Loop();
|
||||
bool SendDiscovery();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,21 +1,12 @@
|
|||
#include "MotionSensors.h"
|
||||
#include <WiFiSettings.h>
|
||||
#include <AsyncMqttClient.h>
|
||||
|
||||
// for #define ESPMAC
|
||||
#include "globals.h"
|
||||
#include "mqtt.h"
|
||||
#include "string_utils.h"
|
||||
#include "defaults.h"
|
||||
#include "GUI.h"
|
||||
|
||||
// TODO: Not a fan of externs, but this helps refactoring for now
|
||||
extern char buffer[2048];
|
||||
extern String room;
|
||||
extern String roomsTopic;
|
||||
extern void commonDiscovery();
|
||||
extern bool sendNumberDiscovery(const String& name, const String& entityCategory);
|
||||
extern bool pub(const char *topic, uint8_t qos, bool retain, const char *payload, size_t length = 0, bool dup = false, uint16_t message_id = 0);
|
||||
extern bool spurt(const String& fn, const String& content);
|
||||
|
||||
namespace Motion
|
||||
{
|
||||
int lastMotionValue = -1;
|
||||
|
@ -54,7 +45,7 @@ namespace Motion
|
|||
Serial.println(radarPin ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
static void PirLoop(AsyncMqttClient& mqttClient)
|
||||
static void pirLoop()
|
||||
{
|
||||
if (!pirPin) return;
|
||||
bool detected = digitalRead(pirPin) == HIGH;
|
||||
|
@ -68,7 +59,7 @@ namespace Motion
|
|||
lastPirValue = pirValue;
|
||||
}
|
||||
|
||||
static void RadarLoop(AsyncMqttClient& mqttClient)
|
||||
static void radarLoop()
|
||||
{
|
||||
if (!radarPin) return;
|
||||
bool detected = digitalRead(radarPin) == HIGH;
|
||||
|
@ -82,34 +73,23 @@ namespace Motion
|
|||
lastRadarValue = radarValue;
|
||||
}
|
||||
|
||||
void Loop(AsyncMqttClient& mqttClient)
|
||||
void Loop()
|
||||
{
|
||||
PirLoop(mqttClient);
|
||||
RadarLoop(mqttClient);
|
||||
pirLoop();
|
||||
radarLoop();
|
||||
int motionValue = (lastRadarValue == HIGH || lastPirValue == HIGH) ? HIGH : LOW;
|
||||
if (lastMotionValue == motionValue) return;
|
||||
mqttClient.publish((roomsTopic + "/motion").c_str(), 0, true, motionValue == HIGH ? "ON" : "OFF");
|
||||
lastMotionValue = motionValue;
|
||||
}
|
||||
|
||||
bool SendDiscovery(DynamicJsonDocument& doc)
|
||||
bool SendDiscovery()
|
||||
{
|
||||
if (!pirPin && !radarPin)
|
||||
return true;
|
||||
if (!pirPin && !radarPin) return true;
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = "ESPresense " + room + " Motion";
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_motion", CHIPID);
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/motion";
|
||||
doc["dev_cla"] = "motion";
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/binary_sensor/espresense_" + ESPMAC + "/motion/config";
|
||||
|
||||
if (!pub(discoveryTopic.c_str(), 0, true, buffer)) return false;
|
||||
return (!pirPin || sendNumberDiscovery("Pir Timeout", EC_CONFIG)) && (!radarPin || sendNumberDiscovery("Radar Timeout", EC_CONFIG));
|
||||
if (pirPin && !sendNumberDiscovery("Pir Timeout", EC_CONFIG)) return false;
|
||||
if (radarPin && !sendNumberDiscovery("Radar Timeout", EC_CONFIG)) return false;
|
||||
return sendSensorDiscovery("Motion", "", "", "motion");
|
||||
}
|
||||
|
||||
bool Command(String& command, String& pay)
|
||||
|
@ -128,7 +108,7 @@ namespace Motion
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SendOnline(DynamicJsonDocument& doc)
|
||||
bool SendOnline()
|
||||
{
|
||||
return pub((roomsTopic + "/pir_timeout").c_str(), 0, true, String(pirTimeout).c_str())
|
||||
&& pub((roomsTopic + "/radar_timeout").c_str(), 0, true, String(radarTimeout).c_str());
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
// Forward declares
|
||||
class AsyncMqttClient;
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
|
||||
namespace Motion
|
||||
{
|
||||
void Setup();
|
||||
void ConnectToWifi();
|
||||
void SerialReport();
|
||||
void Loop(AsyncMqttClient& mqttClient);
|
||||
bool SendDiscovery(DynamicJsonDocument& doc);
|
||||
bool SendOnline(DynamicJsonDocument& doc);
|
||||
void Loop();
|
||||
bool SendDiscovery();
|
||||
bool SendOnline();
|
||||
bool Command(String& command, String& pay);
|
||||
}
|
||||
|
|
|
@ -1,31 +1,21 @@
|
|||
#ifdef SENSORS
|
||||
|
||||
#include "globals.h"
|
||||
#include "defaults.h"
|
||||
#include "mqtt.h"
|
||||
#include "TSL2561Sensor.h"
|
||||
#include <WiFiSettings.h>
|
||||
#include <AsyncMqttClient.h>
|
||||
#include <Adafruit_TSL2561_U.h>
|
||||
|
||||
// for #define ESPMAC
|
||||
#include "string_utils.h"
|
||||
|
||||
// TODO: Not a fan of externs, but this helps refactoring for now
|
||||
extern bool I2C_Bus_1_Enabled;
|
||||
extern bool I2C_Bus_2_Enabled;
|
||||
extern unsigned long sensorInterval;
|
||||
|
||||
extern char buffer[2048];
|
||||
extern String room;
|
||||
extern String roomsTopic;
|
||||
extern void commonDiscovery();
|
||||
extern bool pub(const char *topic, uint8_t qos, bool retain, const char *payload, size_t length = 0, bool dup = false, uint16_t message_id = 0);
|
||||
|
||||
namespace TSL2561
|
||||
{
|
||||
String TSL2561_I2c;
|
||||
int TSL2561_I2c_Bus;
|
||||
String TSL2561_I2c_Gain;
|
||||
unsigned long tsl2561PreviousMillis = 0;
|
||||
int sensorInterval = 60000;
|
||||
|
||||
void Setup()
|
||||
{
|
||||
|
@ -45,7 +35,7 @@ namespace TSL2561
|
|||
Serial.println(TSL2561_I2c + " on bus " + TSL2561_I2c_Bus);
|
||||
}
|
||||
|
||||
void Loop(AsyncMqttClient& mqttClient)
|
||||
void Loop()
|
||||
{
|
||||
if (!I2C_Bus_1_Enabled && !I2C_Bus_2_Enabled) return;
|
||||
|
||||
|
@ -97,24 +87,11 @@ namespace TSL2561
|
|||
}
|
||||
}
|
||||
|
||||
bool SendDiscovery(DynamicJsonDocument& doc)
|
||||
bool SendDiscovery()
|
||||
{
|
||||
if (TSL2561_I2c.isEmpty()) return true;
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = "ESPresense " + room + " TSL2561 Lux";
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_tsl2561_lux", CHIPID);
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/tsl2561_lux";
|
||||
doc["dev_cla"] = "illuminance";
|
||||
doc["unit_of_meas"] = "lx";
|
||||
doc["frc_upd"] = true;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/sensor/espresense_" + ESPMAC + "/tsl2561_lux/config";
|
||||
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
return sendSensorDiscovery("TSL2561 Lux", "", "illuminance", "lx");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
#ifdef SENSORS
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
// Forward declares
|
||||
class AsyncMqttClient;
|
||||
|
||||
namespace TSL2561
|
||||
{
|
||||
void Setup();
|
||||
void ConnectToWifi();
|
||||
void SerialReport();
|
||||
void Loop(AsyncMqttClient& mqttClient);
|
||||
bool SendDiscovery(DynamicJsonDocument& doc);
|
||||
}
|
||||
|
||||
#endif
|
||||
#pragma once
|
||||
#ifdef SENSORS
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
namespace TSL2561
|
||||
{
|
||||
void Setup();
|
||||
void ConnectToWifi();
|
||||
void SerialReport();
|
||||
void Loop();
|
||||
bool SendDiscovery();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include <AsyncMqttClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
globals.h
|
||||
|
||||
Note: #define VAR_DECLS 1 before including this file to DECLARE and INITIALIZE
|
||||
global variables. Include this file without defining VAR_DECLS to extern
|
||||
these variables.
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------
|
||||
Setup variable declaration macros.
|
||||
----------------------------------------------*/
|
||||
#ifndef VAR_DECLS
|
||||
# define _DECL extern
|
||||
# define _INIT(x)
|
||||
# define _INIT_N(x)
|
||||
#else
|
||||
# define _DECL
|
||||
# define _INIT(x) = x
|
||||
# define UNPACK( ... ) __VA_ARGS__
|
||||
# define _INIT_N(x) UNPACK x
|
||||
#endif
|
||||
|
||||
_DECL char buffer[2048];
|
||||
_DECL String room, id, statusTopic, teleTopic, roomsTopic, setTopic;
|
||||
_DECL AsyncMqttClient mqttClient;
|
||||
_DECL DynamicJsonDocument doc _INIT_N(((2048)));
|
||||
_DECL String localIp;
|
||||
|
||||
// I2C
|
||||
_DECL int I2C_Bus_1_SDA;
|
||||
_DECL int I2C_Bus_1_SCL;
|
||||
_DECL int I2C_Bus_2_SDA;
|
||||
_DECL int I2C_Bus_2_SCL;
|
||||
_DECL bool I2CDebug;
|
||||
_DECL bool I2C_Bus_1_Enabled;
|
||||
_DECL bool I2C_Bus_2_Enabled;
|
240
src/main.cpp
240
src/main.cpp
|
@ -1,14 +1,12 @@
|
|||
#define VAR_DECLS
|
||||
#include "main.h"
|
||||
|
||||
#include "Network.h"
|
||||
#include "MotionSensors.h"
|
||||
|
||||
bool sendTelemetry(int totalSeen, int totalFpSeen, int totalFpQueried, int totalFpReported, int count)
|
||||
{
|
||||
if (!online)
|
||||
{
|
||||
if (pub(statusTopic.c_str(), 0, true, "online") && pub((roomsTopic + "/max_distance").c_str(), 0, true, String(BleFingerprintCollection::maxDistance).c_str()) && pub((roomsTopic + "/absorption").c_str(), 0, true, String(BleFingerprintCollection::absorption).c_str()) && pub((roomsTopic + "/query").c_str(), 0, true, BleFingerprintCollection::query.c_str()) && pub((roomsTopic + "/include").c_str(), 0, true, BleFingerprintCollection::include.c_str()) && pub((roomsTopic + "/exclude").c_str(), 0, true, BleFingerprintCollection::exclude.c_str()) && pub((roomsTopic + "/known_macs").c_str(), 0, true, BleFingerprintCollection::knownMacs.c_str()) && pub((roomsTopic + "/count_ids").c_str(), 0, true, BleFingerprintCollection::countIds.c_str()) && pub((roomsTopic + "/status_led").c_str(), 0, true, String(GUI::statusLed ? "ON" : "OFF").c_str()) && pub((roomsTopic + "/arduino_ota").c_str(), 0, true, String(arduinoOta ? "ON" : "OFF").c_str()) &&
|
||||
pub((roomsTopic + "/auto_update").c_str(), 0, true, String(autoUpdate ? "ON" : "OFF").c_str()) && pub((roomsTopic + "/prerelease").c_str(), 0, true, String(prerelease ? "ON" : "OFF").c_str()) && pub((roomsTopic + "/active_scan").c_str(), 0, true, String(activeScan ? "ON" : "OFF").c_str()) && Motion::SendOnline(doc))
|
||||
pub((roomsTopic + "/auto_update").c_str(), 0, true, String(autoUpdate ? "ON" : "OFF").c_str()) && pub((roomsTopic + "/prerelease").c_str(), 0, true, String(prerelease ? "ON" : "OFF").c_str()) && pub((roomsTopic + "/active_scan").c_str(), 0, true, String(activeScan ? "ON" : "OFF").c_str()) && Motion::SendOnline())
|
||||
{
|
||||
online = true;
|
||||
reconnectTries = 0;
|
||||
|
@ -21,7 +19,7 @@ bool sendTelemetry(int totalSeen, int totalFpSeen, int totalFpQueried, int total
|
|||
|
||||
if (discovery && !sentDiscovery)
|
||||
{
|
||||
if (sendDiscoveryConnectivity()
|
||||
if (sendConnectivityDiscovery()
|
||||
&& sendTeleSensorDiscovery("Uptime", EC_DIAGNOSTIC, "{{ value_json.uptime }}", "s")
|
||||
&& sendTeleSensorDiscovery("Free Mem", EC_DIAGNOSTIC, "{{ value_json.freeHeap }}", "bytes")
|
||||
&& (BleFingerprintCollection::countIds.isEmpty() ? sendDeleteDiscovery("sensor", "Count") : sendTeleSensorDiscovery("Count", "", "{{ value_json.count }}", ""))
|
||||
|
@ -33,19 +31,17 @@ bool sendTelemetry(int totalSeen, int totalFpSeen, int totalFpQueried, int total
|
|||
&& sendSwitchDiscovery("Auto Update", EC_CONFIG)
|
||||
&& sendSwitchDiscovery("Arduino OTA", EC_CONFIG)
|
||||
&& sendSwitchDiscovery("Prerelease", EC_CONFIG)
|
||||
&& sendDeleteDiscovery("switch", "OTA Update")
|
||||
&& Motion::SendDiscovery(doc)
|
||||
&& Motion::SendDiscovery()
|
||||
#ifdef MACCHINA_A0
|
||||
&& sendTeleSensorDiscovery("Battery", "", "{{ value_json.batt }}", "%", "battery")
|
||||
&& sendTeleBinarySensorDiscovery("Charging", "", "{{ value_json.charging }}", "battery_charging")
|
||||
#endif
|
||||
#ifdef SENSORS
|
||||
&& sendDiscoveryHumidity()
|
||||
&& sendDiscoveryTemperature()
|
||||
&& sendDiscoveryLux()
|
||||
&& BME280::SendDiscovery(doc)
|
||||
&& TSL2561::SendDiscovery(doc)
|
||||
&& HX711::SendDiscovery(doc)
|
||||
&& DHT::SendDiscovery()
|
||||
&& BH1750::SendDiscovery()
|
||||
&& BME280::SendDiscovery()
|
||||
&& TSL2561::SendDiscovery()
|
||||
&& HX711::SendDiscovery()
|
||||
#endif
|
||||
)
|
||||
{
|
||||
|
@ -199,10 +195,9 @@ void setupNetwork()
|
|||
GUI::statusLed = WiFiSettings.checkbox("status_led", true, "Status LED");
|
||||
|
||||
Motion::ConnectToWifi();
|
||||
|
||||
#ifdef SENSORS
|
||||
dht11Pin = WiFiSettings.integer("dht11_pin", 0, "DHT11 sensor pin (0 for disable)");
|
||||
dht22Pin = WiFiSettings.integer("dht22_pin", 0, "DHT22 sensor pin (0 for disable)");
|
||||
dhtTempOffset = WiFiSettings.floating("dhtTemp_offset", -40, 125, 0.0, "DHT temperature offset");
|
||||
DHT::ConnectToWifi();
|
||||
|
||||
WiFiSettings.heading("I2C Settings <a href='https://espresense.com/configuration/settings#i2c-settings' target='_blank'>ℹ️</a>", false);
|
||||
|
||||
|
@ -219,14 +214,9 @@ void setupNetwork()
|
|||
|
||||
WiFiSettings.heading("I2C Sensors <a href='https://espresense.com/configuration/settings#i2c-sensors' target='_blank'>ℹ️</a>", false);
|
||||
|
||||
WiFiSettings.html("h4", "BH1750 - Ambient Light Sensor:");
|
||||
BH1750_I2c_Bus = WiFiSettings.integer("BH1750_I2c_Bus", 1, 2, DEFAULT_I2C_BUS, "I2C Bus");
|
||||
BH1750_I2c = WiFiSettings.string("BH1750_I2c", "", "I2C address (0x23 or 0x5C)");
|
||||
|
||||
BH1750::ConnectToWifi();
|
||||
BME280::ConnectToWifi();
|
||||
|
||||
TSL2561::ConnectToWifi();
|
||||
|
||||
HX711::ConnectToWifi();
|
||||
#endif
|
||||
|
||||
|
@ -257,14 +247,8 @@ void setupNetwork()
|
|||
Serial.printf("Max Distance: %.2f\n", BleFingerprintCollection::maxDistance);
|
||||
Motion::SerialReport();
|
||||
#ifdef SENSORS
|
||||
Serial.print("DHT11 Sensor: ");
|
||||
Serial.println(dht11Pin ? "enabled" : "disabled");
|
||||
Serial.print("DHT22 Sensor: ");
|
||||
Serial.println(dht22Pin ? "enabled" : "disabled");
|
||||
Serial.print("DHT Temp Offset: ");
|
||||
Serial.println(dhtTempOffset ? "enabled" : "disabled");
|
||||
Serial.print("BH1750_I2c Sensor: ");
|
||||
Serial.println(BH1750_I2c + " on bus " + BH1750_I2c_Bus);
|
||||
DHT::SerialReport();
|
||||
BH1750::SerialReport();
|
||||
BME280::SerialReport();
|
||||
TSL2561::SerialReport();
|
||||
HX711::SerialReport();
|
||||
|
@ -546,40 +530,7 @@ void scanTask(void *parameter)
|
|||
}
|
||||
|
||||
#ifdef SENSORS
|
||||
/**
|
||||
* Task to reads temperature from DHT11 sensor
|
||||
* @param pvParameters
|
||||
* pointer to task parameters
|
||||
*/
|
||||
void tempTask(void *pvParameters)
|
||||
{
|
||||
Serial.println("tempTask loop started");
|
||||
while (1) // tempTask loop
|
||||
{
|
||||
if (dhtTasksEnabled && !gotNewTemperature)
|
||||
{
|
||||
// Read temperature only if old data was processed already
|
||||
// Reading temperature for humidity takes about 250 milliseconds!
|
||||
// Sensor readings may also be up to 2 seconds 'old' (it's a very slow sensor)
|
||||
dhtSensorData = dhtSensor.getTempAndHumidity(); // Read values from sensor 1
|
||||
gotNewTemperature = true;
|
||||
}
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* triggerGetTemp
|
||||
* Sets flag dhtUpdated to true for handling in loop()
|
||||
* called by Ticker tempTicker
|
||||
*/
|
||||
void triggerGetTemp()
|
||||
{
|
||||
if (dhtTempTaskHandle != NULL)
|
||||
{
|
||||
xTaskResumeFromISR(dhtTempTaskHandle);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void setup()
|
||||
|
@ -609,34 +560,7 @@ void setup()
|
|||
pinMode(GPIO_NUM_35, INPUT);
|
||||
#endif
|
||||
#ifdef SENSORS
|
||||
if (dht11Pin) dhtSensor.setup(dht11Pin, DHTesp::DHT11);
|
||||
if (dht22Pin) dhtSensor.setup(dht22Pin, DHTesp::DHT22); //(AM2302)
|
||||
|
||||
if (dht11Pin || dht22Pin)
|
||||
{
|
||||
// Start task to get temperature
|
||||
xTaskCreatePinnedToCore(
|
||||
tempTask, /* Function to implement the task */
|
||||
"tempTask ", /* Name of the task */
|
||||
4000, /* Stack size in words */
|
||||
NULL, /* Task input parameter */
|
||||
5, /* Priority of the task */
|
||||
&dhtTempTaskHandle, /* Task handle. */
|
||||
1); /* Core where the task should run */
|
||||
|
||||
if (dhtTempTaskHandle == NULL)
|
||||
{
|
||||
Serial.println("[ERROR] Failed to start task for temperature update");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start update of environment data every 10 seconds
|
||||
tempTicker.attach(dhtUpdateTime, triggerGetTemp);
|
||||
}
|
||||
|
||||
// Signal end of setup() to tasks
|
||||
dhtTasksEnabled = true;
|
||||
}
|
||||
DHT::Setup();
|
||||
|
||||
if (I2C_Bus_1_SDA != 0 && I2C_Bus_1_SDA != 0) {
|
||||
Wire.begin(I2C_Bus_1_SDA, I2C_Bus_1_SCL);
|
||||
|
@ -655,64 +579,7 @@ void setup()
|
|||
Serial.println("\nI2C Scanner");
|
||||
}
|
||||
|
||||
|
||||
if (I2C_Bus_1_Enabled || I2C_Bus_2_Enabled) {
|
||||
// BH1750_I2c
|
||||
// BH1750_updateFr
|
||||
if (BH1750_I2c == "0x23" || BH1750_I2c == "0x5C")
|
||||
{
|
||||
// Init BH1750 (witch default l2c adres)
|
||||
int rc; // Returncode
|
||||
unsigned long m; // milli for calibration
|
||||
bool state = false;
|
||||
|
||||
// if (! BH1750.begin(BH1750_TO_GROUND))
|
||||
if (BH1750_I2c == "0x23" && BH1750_I2c_Bus == 1)
|
||||
{
|
||||
state = BH1750.begin(BH1750_TO_GROUND, &Wire);
|
||||
}
|
||||
else if (BH1750_I2c == "0x5C" && BH1750_I2c_Bus == 1)
|
||||
{
|
||||
state = BH1750.begin(BH1750_TO_VCC, &Wire);
|
||||
}
|
||||
else if (BH1750_I2c == "0x23" && BH1750_I2c_Bus == 2)
|
||||
{
|
||||
state = BH1750.begin(BH1750_TO_GROUND, &Wire1);
|
||||
}
|
||||
else if (BH1750_I2c == "0x5C" && BH1750_I2c_Bus == 2)
|
||||
{
|
||||
state = BH1750.begin(BH1750_TO_VCC, &Wire1);
|
||||
}
|
||||
|
||||
if (!state)
|
||||
{
|
||||
Serial.println("Error on initialisation BH1750 GY-302");
|
||||
}
|
||||
else
|
||||
{
|
||||
sendDiscoveryLux();
|
||||
Serial.println("initialisation BH1750 GY-302 success");
|
||||
m = millis();
|
||||
rc = BH1750.calibrateTiming();
|
||||
m = millis() - m;
|
||||
Serial.print("Lux Sensor BH1750 GY-302 calibrated (Time: ");
|
||||
Serial.print(m);
|
||||
Serial.print(" ms)");
|
||||
if (rc != 0)
|
||||
{
|
||||
Serial.print(" - Lux Sensor Error code ");
|
||||
Serial.print(rc);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
// start first measure and timecount
|
||||
lux_BH1750 = -1; // nothing to compare
|
||||
BH1750.start(BH1750_QUALITY_HIGH, 1);
|
||||
ms_BH1750 = millis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BH1750::Setup();
|
||||
//BME280::Setup();
|
||||
//TSL2561::Setup();
|
||||
HX711::Setup();
|
||||
|
@ -723,72 +590,9 @@ void setup()
|
|||
}
|
||||
|
||||
#ifdef SENSORS
|
||||
void dhtLoop()
|
||||
{
|
||||
if (!dht11Pin && !dht22Pin) return;
|
||||
|
||||
if (gotNewTemperature)
|
||||
{
|
||||
float humidity = dhtSensorData.humidity;
|
||||
float temperature = dhtSensorData.temperature + dhtTempOffset;
|
||||
Serial.println("Temp: " + String(temperature, 1) + "'C Humidity: " + String(humidity, 1) + "%");
|
||||
|
||||
mqttClient.publish((roomsTopic + "/humidity").c_str(), 0, 1, String(humidity, 1).c_str());
|
||||
mqttClient.publish((roomsTopic + "/temperature").c_str(), 0, 1, String(temperature, 1).c_str());
|
||||
|
||||
gotNewTemperature = false;
|
||||
}
|
||||
}
|
||||
|
||||
//non blocking ambient sensor
|
||||
void luxLoop()
|
||||
{
|
||||
if (I2C_Bus_1_Enabled || I2C_Bus_2_Enabled) {
|
||||
|
||||
if (BH1750_I2c == "0x23" || BH1750_I2c == "0x5C")
|
||||
{
|
||||
|
||||
float lux;
|
||||
int lux_mqtt;
|
||||
|
||||
if (BH1750.hasValue())
|
||||
{
|
||||
ms_BH1750 = millis() - ms_BH1750;
|
||||
if (!BH1750.saturated())
|
||||
{
|
||||
lux = BH1750.getLux();
|
||||
lux_mqtt = int(lux);
|
||||
|
||||
if (lux != lux_BH1750)
|
||||
{
|
||||
lux_BH1750 = lux;
|
||||
// Serial.print("BH1750 (");
|
||||
// Serial.print(ms_BH1750);
|
||||
// Serial.print(" ms): ");
|
||||
// Serial.print(lux);
|
||||
// Serial.println(" lx");
|
||||
}
|
||||
|
||||
//convert lx to integer to reduce mqtt traffic, send only if lx changed
|
||||
if (lux_mqtt != lux_BH1750_MQTT)
|
||||
{
|
||||
lux_BH1750_MQTT = lux_mqtt;
|
||||
Serial.print("BH1750 (");
|
||||
Serial.print(ms_BH1750);
|
||||
Serial.print(" ms): ");
|
||||
Serial.print(lux_mqtt);
|
||||
Serial.println(" lx");
|
||||
mqttClient.publish((roomsTopic + "/lux").c_str(), 0, 1, String(lux_mqtt).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
BH1750.adjustSettings(90);
|
||||
BH1750.start();
|
||||
ms_BH1750 = millis();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void l2cScanner()
|
||||
{
|
||||
|
@ -876,13 +680,13 @@ void loop()
|
|||
ArduinoOTA.handle();
|
||||
if (freeHeap < 10000) Serial.printf("Low memory: %u bytes free", freeHeap);
|
||||
firmwareUpdate();
|
||||
Motion::Loop(mqttClient);
|
||||
Motion::Loop();
|
||||
#ifdef SENSORS
|
||||
dhtLoop();
|
||||
luxLoop();
|
||||
BME280::Loop(mqttClient);
|
||||
TSL2561::Loop(mqttClient);
|
||||
HX711::Loop(mqttClient);
|
||||
DHT::Loop();
|
||||
BH1750::Loop();
|
||||
BME280::Loop();
|
||||
TSL2561::Loop();
|
||||
HX711::Loop();
|
||||
l2cScanner();
|
||||
#endif
|
||||
WiFiSettings.httpLoop();
|
||||
|
|
288
src/main.h
288
src/main.h
|
@ -1,70 +1,44 @@
|
|||
#include "BleFingerprint.h"
|
||||
#include "BleFingerprintCollection.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "mqtt.h"
|
||||
#include "GUI.h"
|
||||
#include "defaults.h"
|
||||
#include "string_utils.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <ArduinoOTA.h>
|
||||
#include <AsyncMqttClient.h>
|
||||
#include <AsyncTCP.h>
|
||||
|
||||
#include <HTTPClient.h>
|
||||
#include <HTTPUpdate.h>
|
||||
#include <NimBLEDevice.h>
|
||||
#include <SPIFFS.h>
|
||||
#include <Ticker.h>
|
||||
#include <WebServer.h>
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <WiFiSettings.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/timers.h>
|
||||
#include <rom/rtc.h>
|
||||
#include "Network.h"
|
||||
|
||||
#include "MotionSensors.h"
|
||||
#ifdef SENSORS
|
||||
#include <DHTesp.h>
|
||||
#include <Wire.h>
|
||||
// I2C
|
||||
int I2C_Bus_1_SDA;
|
||||
int I2C_Bus_1_SCL;
|
||||
int I2C_Bus_2_SDA;
|
||||
int I2C_Bus_2_SCL;
|
||||
bool I2CDebug;
|
||||
bool I2C_Bus_1_Enabled;
|
||||
bool I2C_Bus_2_Enabled;
|
||||
|
||||
unsigned long sensorInterval = 60000;
|
||||
|
||||
//GY-302 lux sensor
|
||||
#include <hp_BH1750.h>
|
||||
hp_BH1750 BH1750;
|
||||
unsigned long ms_BH1750;
|
||||
float lux_BH1750;
|
||||
int lux_BH1750_MQTT;
|
||||
String BH1750_I2c;
|
||||
int BH1750_I2c_Bus;
|
||||
|
||||
//I2C BME280 sensor
|
||||
#include "BME280Sensor.h"
|
||||
|
||||
//I2C TSL2561 sensor
|
||||
#include "TSL2561Sensor.h"
|
||||
|
||||
#include "HX711.h"
|
||||
#include "DHT.h"
|
||||
#include "BH1750.h"
|
||||
#endif
|
||||
|
||||
AsyncMqttClient mqttClient;
|
||||
TimerHandle_t reconnectTimer;
|
||||
TaskHandle_t scanTaskHandle, reportTaskHandle;
|
||||
|
||||
DynamicJsonDocument doc(2048);
|
||||
char buffer[2048];
|
||||
|
||||
bool updateInProgress = false;
|
||||
String localIp;
|
||||
unsigned long lastTeleMillis;
|
||||
int reconnectTries = 0;
|
||||
int teleFails = 0;
|
||||
|
@ -75,38 +49,10 @@ String offline = "offline";
|
|||
int ethernetType = 0;
|
||||
String mqttHost, mqttUser, mqttPass;
|
||||
uint16_t mqttPort;
|
||||
String room, id, statusTopic, teleTopic, roomsTopic, setTopic;
|
||||
|
||||
bool autoUpdate, arduinoOta, prerelease;
|
||||
bool discovery, activeScan, publishTele, publishRooms, publishDevices;
|
||||
|
||||
#ifdef SENSORS
|
||||
|
||||
uint8_t dht11Pin;
|
||||
uint8_t dht22Pin;
|
||||
float dhtTempOffset;
|
||||
|
||||
/** Initialize DHT sensor 1 */
|
||||
DHTesp dhtSensor;
|
||||
|
||||
/** Task handle for the light value read task */
|
||||
TaskHandle_t dhtTempTaskHandle = NULL;
|
||||
|
||||
/** Ticker for temperature reading */
|
||||
Ticker tempTicker;
|
||||
|
||||
/** Flags for temperature readings finished */
|
||||
bool gotNewTemperature = false;
|
||||
|
||||
/** Data from dht sensor 1 */
|
||||
TempAndHumidity dhtSensorData;
|
||||
|
||||
/* Flag if main loop is running */
|
||||
bool dhtTasksEnabled = false;
|
||||
|
||||
/* update time */
|
||||
int dhtUpdateTime = 10; //ToDo: maybe make this a user choise via settings menu
|
||||
#endif
|
||||
BleFingerprintCollection fingerprints;
|
||||
|
||||
String resetReason(RESET_REASON reason)
|
||||
|
@ -314,226 +260,6 @@ void spiffsInit()
|
|||
SPIFFS.begin(true);
|
||||
}
|
||||
|
||||
bool pub(const char *topic, uint8_t qos, bool retain, const char *payload, size_t length = 0, bool dup = false, uint16_t message_id = 0)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (mqttClient.publish(topic, qos, retain, payload, length, dup, message_id))
|
||||
return true;
|
||||
delay(50);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void commonDiscovery()
|
||||
{
|
||||
doc.clear();
|
||||
auto identifiers = doc["dev"].createNestedArray("ids");
|
||||
identifiers.add(Sprintf("espresense_%06" PRIx64, CHIPID));
|
||||
auto connections = doc["dev"].createNestedArray("cns");
|
||||
auto mac = connections.createNestedArray();
|
||||
mac.add("mac");
|
||||
mac.add(WiFi.macAddress());
|
||||
doc["dev"]["name"] = "ESPresense " + room;
|
||||
doc["dev"]["sa"] = room;
|
||||
#ifdef VERSION
|
||||
doc["dev"]["sw"] = VERSION;
|
||||
#endif
|
||||
#ifdef FIRMWARE
|
||||
doc["dev"]["mf"] = "ESPresense (" FIRMWARE ")";
|
||||
#endif
|
||||
doc["dev"]["cu"] = "http://" + localIp;
|
||||
doc["dev"]["mdl"] = String(ESP.getChipModel());
|
||||
}
|
||||
|
||||
bool sendDiscoveryConnectivity()
|
||||
{
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = "ESPresense " + room;
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_connectivity", CHIPID);
|
||||
doc["json_attr_t"] = "~/telemetry";
|
||||
doc["stat_t"] = "~/status";
|
||||
doc["dev_cla"] = "connectivity";
|
||||
doc["pl_on"] = "online";
|
||||
doc["pl_off"] = "offline";
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/binary_sensor/espresense_" + ESPMAC + "/connectivity/config";
|
||||
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool sendTeleBinarySensorDiscovery(const String &name, const String &entityCategory, const String &temp, const String &devClass)
|
||||
{
|
||||
auto slug = slugify(name);
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = Sprintf("ESPresense %s %s", room.c_str(), name.c_str());
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_%s", CHIPID, slug.c_str());
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/telemetry";
|
||||
if (!entityCategory.isEmpty()) doc["entity_category"] = entityCategory;
|
||||
doc["value_template"] = temp;
|
||||
if (!devClass.isEmpty()) doc["dev_cla"] = devClass;
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/binary_sensor/espresense_" + ESPMAC + "/" + slug + "/config";
|
||||
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool sendTeleSensorDiscovery(const String &name, const String &entityCategory, const String &temp, const String &units, const String &devClass = "")
|
||||
{
|
||||
auto slug = slugify(name);
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = Sprintf("ESPresense %s %s", room.c_str(), name.c_str());
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_%s", CHIPID, slug.c_str());
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/telemetry";
|
||||
if (!entityCategory.isEmpty()) doc["entity_category"] = entityCategory;
|
||||
doc["value_template"] = temp;
|
||||
if (!units.isEmpty()) doc["unit_of_measurement"] = units;
|
||||
if (!devClass.isEmpty()) doc["dev_cla"] = devClass;
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/sensor/espresense_" + ESPMAC + "/" + slug + "/config";
|
||||
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
#ifdef SENSORS
|
||||
bool sendDiscoveryTemperature()
|
||||
{
|
||||
if (!dht11Pin && !dht22Pin) return true;
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = "ESPresense " + room + " Temperature";
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_temperature", CHIPID);
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/temperature";
|
||||
doc["dev_cla"] = "temperature";
|
||||
doc["unit_of_meas"] = "°C";
|
||||
doc["frc_upd"] = true;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/sensor/espresense_" + ESPMAC + "/temperature/config";
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool sendDiscoveryHumidity()
|
||||
{
|
||||
if (!dht11Pin && !dht22Pin) return true;
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = "ESPresense " + room + " Humidity";
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_humidity", CHIPID);
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/humidity";
|
||||
doc["dev_cla"] = "humidity";
|
||||
doc["unit_of_meas"] = "%";
|
||||
doc["frc_upd"] = true;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/sensor/espresense_" + ESPMAC + "/humidity/config";
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool sendDiscoveryLux()
|
||||
{
|
||||
if (BH1750_I2c.isEmpty()) return true;
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = "ESPresense " + room + " Lux";
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_lux", CHIPID);
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/lux";
|
||||
doc["dev_cla"] = "illuminance";
|
||||
doc["unit_of_meas"] = "lx";
|
||||
doc["frc_upd"] = true;
|
||||
|
||||
char buffer[1200];
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/sensor/espresense_" + ESPMAC + "/lux/config";
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool sendButtonDiscovery(const String &name, const String &entityCategory)
|
||||
{
|
||||
auto slug = slugify(name);
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = Sprintf("ESPresense %s %s", room.c_str(), name.c_str());
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_%s", CHIPID, slug.c_str());
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/" + slug;
|
||||
doc["cmd_t"] = "~/" + slug + "/set";
|
||||
doc["entity_category"] = entityCategory;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/button/espresense_" + ESPMAC + "/" + slug + "/config";
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool sendSwitchDiscovery(const String &name, const String &entityCategory)
|
||||
{
|
||||
auto slug = slugify(name);
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = Sprintf("ESPresense %s %s", room.c_str(), name.c_str());
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_%s", CHIPID, slug.c_str());
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/" + slug;
|
||||
doc["cmd_t"] = "~/" + slug + "/set";
|
||||
doc["entity_category"] = entityCategory;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/switch/espresense_" + ESPMAC + "/" + slug + "/config";
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool sendDeleteDiscovery(const String &domain, const String &name)
|
||||
{
|
||||
auto slug = slugify(name);
|
||||
String discoveryTopic = "homeassistant/" + domain + "/espresense_" + ESPMAC + "/" + slug + "/config";
|
||||
return pub(discoveryTopic.c_str(), 0, false, "");
|
||||
}
|
||||
|
||||
bool sendNumberDiscovery(const String &name, const String &entityCategory)
|
||||
{
|
||||
auto slug = slugify(name);
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = Sprintf("ESPresense %s %s", room.c_str(), name.c_str());
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_%s", CHIPID, slug.c_str());
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/" + slug;
|
||||
doc["cmd_t"] = "~/" + slug + "/set";
|
||||
doc["step"] = "0.1";
|
||||
doc["entity_category"] = entityCategory;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = "homeassistant/number/espresense_" + ESPMAC + "/" + slug + "/config";
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool spurt(const String &fn, const String &content)
|
||||
{
|
||||
File f = SPIFFS.open(fn, "w");
|
||||
if (!f) return false;
|
||||
auto w = f.print(content);
|
||||
f.close();
|
||||
return w == content.length();
|
||||
}
|
||||
|
||||
#ifdef MACCHINA_A0
|
||||
|
||||
int smoothMilliVolts;
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
#include "globals.h"
|
||||
#include "string_utils.h"
|
||||
#include <WiFi.h>
|
||||
|
||||
bool pub(const char *topic, uint8_t qos, bool retain, const char *payload, size_t length = 0, bool dup = false, uint16_t message_id = 0)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (mqttClient.publish(topic, qos, retain, payload, length, dup, message_id))
|
||||
return true;
|
||||
delay(50);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void commonDiscovery()
|
||||
{
|
||||
doc.clear();
|
||||
auto identifiers = doc["dev"].createNestedArray("ids");
|
||||
identifiers.add(Sprintf("espresense_%06lx", CHIPID));
|
||||
auto connections = doc["dev"].createNestedArray("cns");
|
||||
auto mac = connections.createNestedArray();
|
||||
mac.add("mac");
|
||||
mac.add(WiFi.macAddress());
|
||||
doc["dev"]["name"] = "ESPresense " + room;
|
||||
doc["dev"]["sa"] = room;
|
||||
#ifdef VERSION
|
||||
doc["dev"]["sw"] = VERSION;
|
||||
#endif
|
||||
#ifdef FIRMWARE
|
||||
doc["dev"]["mf"] = "ESPresense (" FIRMWARE ")";
|
||||
#endif
|
||||
doc["dev"]["cu"] = "http://" + localIp;
|
||||
doc["dev"]["mdl"] = String(ESP.getChipModel());
|
||||
}
|
||||
|
||||
bool sendConnectivityDiscovery()
|
||||
{
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = "ESPresense " + room;
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_connectivity", CHIPID);
|
||||
doc["json_attr_t"] = "~/telemetry";
|
||||
doc["stat_t"] = "~/status";
|
||||
doc["dev_cla"] = "connectivity";
|
||||
doc["pl_on"] = "online";
|
||||
doc["pl_off"] = "offline";
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = Sprintf("homeassistant/binary_sensor/espresense_%06lx/connectivity/config", CHIPID);
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool sendTeleBinarySensorDiscovery(const String &name, const String &entityCategory, const String &temp, const String &devClass)
|
||||
{
|
||||
auto slug = slugify(name);
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = Sprintf("ESPresense %s %s", room.c_str(), name.c_str());
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_%s", CHIPID, slug.c_str());
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/telemetry";
|
||||
doc["value_template"] = temp;
|
||||
if (!entityCategory.isEmpty()) doc["entity_category"] = entityCategory;
|
||||
if (!devClass.isEmpty()) doc["dev_cla"] = devClass;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = Sprintf("homeassistant/binary_sensor/espresense_%06lx/%s/config", CHIPID, slug.c_str());
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool sendTeleSensorDiscovery(const String &name, const String &entityCategory, const String &temp, const String &units, const String &devClass)
|
||||
{
|
||||
auto slug = slugify(name);
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = Sprintf("ESPresense %s %s", room.c_str(), name.c_str());
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_%s", CHIPID, slug.c_str());
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/telemetry";
|
||||
doc["value_template"] = temp;
|
||||
if (!entityCategory.isEmpty()) doc["entity_category"] = entityCategory;
|
||||
if (!units.isEmpty()) doc["unit_of_meas"] = units;
|
||||
if (!devClass.isEmpty()) doc["dev_cla"] = devClass;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = Sprintf("homeassistant/sensor/espresense_%06lx/%s/config", CHIPID, slug.c_str());
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool sendSensorDiscovery(const String &name, const String &entityCategory, const String &units, const String &devClass)
|
||||
{
|
||||
auto slug = slugify(name);
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = Sprintf("ESPresense %s %s", room.c_str(), name.c_str());
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_%s", CHIPID, slug.c_str());
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/" + slug;
|
||||
if (!entityCategory.isEmpty()) doc["entity_category"] = entityCategory;
|
||||
if (!units.isEmpty()) doc["unit_of_meas"] = units;
|
||||
if (!devClass.isEmpty()) doc["dev_cla"] = devClass;
|
||||
doc["frc_upd"] = true;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = Sprintf("homeassistant/sensor/espresense_%06lx/%s/config", CHIPID, slug.c_str());
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool sendButtonDiscovery(const String &name, const String &entityCategory)
|
||||
{
|
||||
auto slug = slugify(name);
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = Sprintf("ESPresense %s %s", room.c_str(), name.c_str());
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_%s", CHIPID, slug.c_str());
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/" + slug;
|
||||
doc["cmd_t"] = "~/" + slug + "/set";
|
||||
doc["entity_category"] = entityCategory;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = Sprintf("homeassistant/button/espresense_%06lx/%s/config", CHIPID, slug.c_str());
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool sendSwitchDiscovery(const String &name, const String &entityCategory)
|
||||
{
|
||||
auto slug = slugify(name);
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = Sprintf("ESPresense %s %s", room.c_str(), name.c_str());
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_%s", CHIPID, slug.c_str());
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/" + slug;
|
||||
doc["cmd_t"] = "~/" + slug + "/set";
|
||||
doc["entity_category"] = entityCategory;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = Sprintf("homeassistant/switch/espresense_%06lx/%s/config", CHIPID, slug.c_str());
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer, 0);
|
||||
}
|
||||
|
||||
bool sendNumberDiscovery(const String &name, const String &entityCategory)
|
||||
{
|
||||
auto slug = slugify(name);
|
||||
|
||||
commonDiscovery();
|
||||
doc["~"] = roomsTopic;
|
||||
doc["name"] = Sprintf("ESPresense %s %s", room.c_str(), name.c_str());
|
||||
doc["uniq_id"] = Sprintf("espresense_%06lx_%s", CHIPID, slug.c_str());
|
||||
doc["avty_t"] = "~/status";
|
||||
doc["stat_t"] = "~/" + slug;
|
||||
doc["cmd_t"] = "~/" + slug + "/set";
|
||||
doc["step"] = "0.1";
|
||||
doc["entity_category"] = entityCategory;
|
||||
|
||||
serializeJson(doc, buffer);
|
||||
String discoveryTopic = Sprintf("homeassistant/number/espresense_%06lx/%s/config", CHIPID, slug.c_str());
|
||||
return pub(discoveryTopic.c_str(), 0, true, buffer);
|
||||
}
|
||||
|
||||
bool sendDeleteDiscovery(const String &domain, const String &name)
|
||||
{
|
||||
auto slug = slugify(name);
|
||||
String discoveryTopic = Sprintf("homeassistant/%s/espresense_%06lx/%s/config", domain, CHIPID, slug.c_str());
|
||||
return pub(discoveryTopic.c_str(), 0, false, "");
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
#include <Arduino.h>
|
||||
|
||||
bool pub(const char *topic, uint8_t qos, bool retain, const char *payload, size_t length = 0, bool dup = false, uint16_t message_id = 0);
|
||||
void commonDiscovery();
|
||||
|
||||
bool sendConnectivityDiscovery();
|
||||
|
||||
bool sendTeleBinarySensorDiscovery(const String &name, const String &entityCategory, const String &temp, const String &devClass);
|
||||
bool sendTeleSensorDiscovery(const String &name, const String &entityCategory, const String &temp, const String &units, const String &devClass = "");
|
||||
|
||||
bool sendSensorDiscovery(const String &name, const String &entityCategory, const String &units, const String &devClass);
|
||||
bool sendButtonDiscovery(const String &name, const String &entityCategory);
|
||||
bool sendSwitchDiscovery(const String &name, const String &entityCategory);
|
||||
bool sendNumberDiscovery(const String &name, const String &entityCategory);
|
||||
|
||||
bool sendDeleteDiscovery(const String &domain, const String &name);
|
Loading…
Reference in New Issue