Mini proiect (35) - Micro Weather Station folosind ESP32 MQTT pentru Home Assistant Mosquitto broker

Micro Weather Station folosind ESP32 MQTT pentru Home Assistant Mosquitto broker

În acest articol am continuat folosirea sistemului HomeAssistant instalat în postarea precedentă, și am dezvoltat un micro Weather Station care trimite 4 semnale:

  • Temperatură 
  • Umiditate
  • Presiune
  • Luminozitate

 Acest micro Weather Station l-am instalat în camera de zi, și am în plan să instalez câte o jucărie deasta în fiecare cameră și în balcon. Mai jos am adaugat lista cu componente care pot fi folosite. Linkurile de mai jos conțin adresa mea de afiliere la emag, iar dacă cumperi folosind aceste linkuri vei susține acest site. Mulțumesc!


Componente:


Schema electronica/sistem:

Micro Weather Station folosind ESP32 MQTT pentru Home Assistant Mosquitto broker

Am programat ESP32-ul (folosind codul de mai jos)  să trimită datele formatate pentru Mosquitto MQTT broker. În HomeAssistant în cofigurația de Mosquitto MQTT broker apar 4 entities, cele din imaginea de mai jos:
 


Datele care sunt trimise pe MQTT sunt de fapt mult mai multe din cauza faptului că aceste date sunt formatate și organizate astfel încât să fie ușor recunoscute de Mosquitto MQTT broker și HomeAssistant, după cum se observă in imaginea de mai jos, extrasă din MQTT Explorer:

 
  În HomeAssistant overview dashbord se pot configura și afișa cele 4 semnale trimise de ESP32 Micro Weather station: 



 Codul sursă:
/*
Florin Simedru
Complete project details at https://automatic-house.blogspot.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/
#include <FS.h> //this needs to be first, or it all crashes and burns...
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Adafruit_ST7735.h>
#include <Adafruit_GFX.h>
#include <WiFi.h>
extern "C" {
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
}
#include <ESP_WiFiManager.h>
#include <ArduinoJson.h>
#include <PubSubClient.h>
#include <MD5Builder.h>
#define WIFI_SSID "SSID"
#define WIFI_PASSWORD "password"
#define MQTT_HOST "core-mosquitto"
#define MQTT_PORT 1883
#define PRODUCT "Micro Weather Station"
// The third method is documented below, above USE_MULTIPLE_MQTT.
#define USE_MULTIPLE_STATUS_TOPICS
#define HOME_ASSISTANT_DISCOVERY 1
#if defined(USE_MULTIPLE_MQTT) && !defined(USE_MULTIPLE_STATUS_TOPICS)
# error USE_MULTIPLE_MQTT without USE_MULTIPLE_STATUS_TOPICS is not supported
#endif
enum MQTTName {
MQTT_ESP32,
MQTT_DHT22,
MQTT_DS18B20,
MQTT_BMP280,
MQTT_TEMT6000,
MQTT_HTU21D,
MQTT_APDS9960,
MQTT_BUTTON,
#ifdef USE_MULTIPLE_MQTT
MQTT_LAST,
#else
MQTT_LAST_STATUS,
# define MQTT_LAST 1
#endif
};
// MD5 of chip ID. If you only have a handful of thermometers and use
// your own MQTT broker (instead of iot.eclips.org) you may want to
// truncate the MD5 by changing the 32 to a smaller value.
char machineId[32+1] = "";
char ha_name[32+1] = ""; // Make sure the machineId fits.
unsigned long mqttConnectionPreviousMillis = millis();
const long mqttConnectionInterval = 1000;
char line1_topic[11 + sizeof(machineId)];
char line2_topic[11 + sizeof(machineId)];
char line3_topic[11 + sizeof(machineId)];
char line4_topic[11 + sizeof(machineId)];
char line5_topic[11 + sizeof(machineId)];
char cmnd_restart_topic[13 + sizeof(machineId)];
char cmnd_temp_format[16 + sizeof(machineId)];
char cmnd_altitude_topic[16 + sizeof(machineId)];
// MQTT Broker
const char *mqtt_broker = "192.168.x.x";
const char *topic = "homeassistant/esp32/test";
const char *temperature = "homeassistant/esp32/temperature";
const char *humidity = "homeassistant/esp32/hum";
const char *pressure = "homeassistant/esp32/pres";
const char *mqtt_username = "mqtt user";
const char *mqtt_password = "mqtt password";
const char *workgroup = "workgroup";
const int mqtt_port_i = 1883;
char mqtt_port[6] = "1883";
IPAddress ip(192, 168, x, x);
char mqtt_server[40] ="192.168.x.x";
WiFiClient espClient;
PubSubClient client(espClient);
#define MQTT_PUB_TEMP "homeassistant/esp32/temperature"
#define MQTT_PUB_HUM "homeassistant/esp32/humidity"
#define MQTT_PUB_PRES "homeassistant/esp32/pressure"
// These pins will also work for the 1.8" TFT shield
#define TFT_MOSI 23 // SDA Pin on ESP32
#define TFT_SCLK 18 // SCL Pin on ESP32
#define TFT_CS 5 // Chip select control pin
#define TFT_DC 2 // Data Command control pin
#define TFT_RST 4 // Reset pin (could connect to RST pin)
#define RELAY_PIN 15
#define PIR_PIN 13
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 160 // OLED display height, in pixels
/* TFT ST7735 configuration */
Adafruit_ST7735 display = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
#define LIGHT_SENSOR 34 // define input pin
void LightRead(void);
/******************************************************************************/
class MQTTConnection;
MQTTConnection *mqtt(MQTTName name);
#ifndef USE_MULTIPLE_STATUS_TOPICS
void call_mqtt_connect_cbs(MQTTConnection *conn);
#endif
struct MQTTSpec {
MQTTName name;
const char *topic;
void (*connect_cb)(MQTTConnection *);
bool ever_online; // Not used in USE_MULTIPLE_STATUS_TOPICS mode.
};
class MQTTStatus
{
public:
String availability_topic;
MQTTStatus *status_list;
MQTTConnection *conn;
MQTTStatus();
void set_spec(const MQTTSpec *spec);
void online(bool board = false);
void offline();
const char *topic;
void (*connect_cb)(MQTTConnection *);
void publish_online(bool force_update);
protected:
bool is_online;
bool last_online;
};
class MQTTConnection
{
public:
WiFiClient espClient;
PubSubClient mqttClient;
bool requested;
MQTTConnection();
void set_spec(const MQTTSpec *spec);
void connect();
void reconnect();
MQTTStatus *status_list;
String client_id;
};
MQTTStatus::MQTTStatus()
: status_list(0), topic(0), connect_cb(0),
is_online(false), last_online(false)
{
}
void MQTTStatus::set_spec(const MQTTSpec *spec)
{
topic = spec->topic;
connect_cb = spec->connect_cb;
availability_topic = String(workgroup) + "/" + machineId + "/"
+ "status" + "/" + topic;
}
void MQTTStatus::online(bool board)
{
#ifndef USE_MULTIPLE_STATUS_TOPICS
// If we use a single MQTT status topic, all the status indicators
// except for the board itself (MQTT_ESP32) are disabled. For
// simplicity, the online() notification for MQTT_ESP32 also
// specifies the board argument.
if (!board)
return;
#endif
#ifndef USE_MULTIPLE_MQTT
if (!conn)
{
conn = mqtt(MQTT_ESP32);
// Insert this as the second element on the status_list. The
// first element must always be the status of the ESP32
// itself.
status_list = conn->status_list->status_list;
conn->status_list->status_list = this;
(*connect_cb)(conn);
}
#endif
is_online = true;
if (!conn->requested)
conn->connect();
publish_online(false);
}
void MQTTStatus::offline()
{
#ifdef USE_MULTIPLE_STATUS_TOPICS
is_online = false;
#ifndef USE_MULTIPLE_MQTT
if (!conn)
return;
#endif
if (conn->requested)
publish_online(false);
# else
// If we use a single MQTT status topic, we never publish offline
// messages. The offline message is only sent as a result of the
// MQTT will. So we don't need to do anything here.
#endif
}
void MQTTStatus::publish_online(bool force_update)
{
if (is_online != last_online || force_update)
{
conn->mqttClient.publish(availability_topic.c_str(),
is_online ? "online" : "offline", true);
last_online = is_online;
}
}
MQTTConnection::MQTTConnection()
: espClient(), mqttClient(espClient), requested(false),
status_list(0), client_id(PRODUCT)
{
}
void MQTTConnection::set_spec(const MQTTSpec *spec)
{
String minId(machineId);
if (minId.length() > 5)
{
minId = minId.substring(minId.length() - 5);
}
client_id = String("AHS-") + minId + "-" + spec->topic;
Serial.println("set_spec client_id: " + client_id);
}
void MQTTConnection::connect()
{
requested = true;
reconnect();
}
void MQTTConnection::reconnect()
{
if (!requested || mqttClient.connected())
return;
Serial.print("MQTT ");
Serial.print(status_list->topic);
Serial.print(" ");
if (mqttClient.connect(client_id.c_str(),
mqtt_username, mqtt_password,
status_list->availability_topic.c_str(),
0, 1, "offline"))
{
Serial.println("connection established.");
#if defined(USE_MULTIPLE_MQTT)
(*status_list->connect_cb)(this);
status_list->publish_online(true);
#elif defined(USE_MULTIPLE_STATUS_TOPICS)
MQTTStatus *status = status_list;
while (status != NULL)
{
(*status->connect_cb)(this);
status->publish_online(true);
status = status->status_list;
}
#else
call_mqtt_connect_cbs(this);
status_list->publish_online(true);
#endif
}
else
{
Serial.print("failed, rc=");
Serial.println(mqttClient.state());
}
}
MQTTStatus mqtt_statuses[MQTT_LAST_STATUS];
MQTTConnection mqtt_connections[MQTT_LAST];
/******************************************************************************/
#define SEALEVELPRESSURE_HPA (1013.25)
void printValues();
void PrintInfoServer();
void ON_OFF_Relay_test();
void callback(char *topic, byte *payload, unsigned int length);
void reconnect();
bool publishSensorDiscovery(const char *component,
const char *config_key,
const char *device_class,
const char *name_suffix,
const char *state_topic,
const char *unit,
const char *value_template,
MQTTName mqtt_name);
MQTTStatus *mqtt_status(MQTTName name);
PubSubClient *mqtt_client(MQTTName name);
MQTTConnection *mqtt(MQTTName name);
void calculateMachineId();
void mqtt_online(MQTTName name, bool board);
void mqtt_esp32_connected(MQTTConnection *c);
void mqtt_bmp280_connected(MQTTConnection *c);
void mqtt_temt6000_connected(MQTTConnection *c);
void mqttReconnect();
void setup_mqtt(const char *mqtt_server, const char *mqtt_port);
void nice_restart();
void publishSensorData(MQTTName mqtt_name, const char* subTopic,
const char* key, const float value);
void publishSensorData(MQTTName mqtt_name, const char* subTopic,
const char* key, const String& value);
// The order must match the enum MQTTName.
struct MQTTSpec mqtt_specs[] = {
{MQTT_ESP32, "esp32", mqtt_esp32_connected, false},
{MQTT_DHT22, "dht22", NULL, false},
{MQTT_DS18B20, "ds18b20", NULL, false},
{MQTT_BMP280, "bmp280", mqtt_bmp280_connected, false},
{MQTT_TEMT6000, "TEMT6000", mqtt_temt6000_connected, false},
{MQTT_HTU21D, "htu21d", NULL, false},
{MQTT_APDS9960, "apds9960", NULL, false},
{MQTT_BUTTON, "button", NULL, false},
{MQTT_ESP32, 0, 0, false}, // Sentinel used by call_mqtt_connect_cbs()
};
Adafruit_BME280 bme; // I2C
unsigned long delayTime;
unsigned long previousMillis = 0;
const long interval = 1000;
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;
String client_str;
String client_mqtt_topic;
/*--------------------------------------------------------------------------*/
void setup() {
unsigned status;
Serial.begin(115200);
client_str = "";
while(!Serial); // time to get serial running
Serial.println(F("BME280 test"));
// connecting to a WiFi network
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println(client_str);
// publish and subscribe
client.publish(topic, "Hi Sir, I'm ESP32");
client.subscribe(topic);
client.publish(temperature, "Temperature");
client.subscribe(temperature);
client.publish(humidity, "Humidity");
client.subscribe(humidity);
client.publish(pressure, "Pressure");
client.subscribe(pressure);
// default settings
status = bme.begin();
// You can also pass in a Wire library object like &Wire2
status = bme.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n");
Serial.print(" ID of 0x60 represents a BME 280.\n");
Serial.print(" ID of 0x61 represents a BME 680.\n");
while (1) delay(10);
}
Serial.println("-- Default Test --");
delayTime = 1000;
Serial.println();
// Machine ID
calculateMachineId();
setup_mqtt(mqtt_broker, mqtt_port);
mqtt_online(MQTT_ESP32, true);
}
void loop() {
printValues();
delay(delayTime);
LightRead();
// Reconnect if there is an issue with the MQTT connection
const unsigned long mqttConnectionMillis = millis();
if ( mqttConnectionInterval <= (mqttConnectionMillis - mqttConnectionPreviousMillis) )
{
mqttConnectionPreviousMillis = mqttConnectionMillis;
mqttReconnect();
}
}
void printValues() {
publishSensorDiscovery("sensor",
"bmp280-temp",
"temperature",
"Temperature",
"/air/temperature",
"°C",
"{{ value_json.temperature | round(1) }}",
MQTT_ESP32);
// Publish new temperature value through MQTT
publishSensorData(MQTT_ESP32, "air/temperature", "temperature",
bme.readTemperature());
publishSensorDiscovery("sensor",
"bmp280-humidity",
"humidity",
"BMP280 Humidity",
"/air/humidity",
"%",
"{{ value_json.humidity }}",
MQTT_ESP32);
// Publish new humidity value through MQTT
publishSensorData(MQTT_ESP32, "air/humidity", "humidity",
bme.readHumidity());
publishSensorDiscovery("sensor",
"bmp280-pressure",
"pressure",
"BMP280 Air Pressure",
"/air/BMPpressure",
"hPa",
"{{ value_json.BMPpressure }}",
MQTT_ESP32);
// Publish new pressure value through MQTT
publishSensorData(MQTT_ESP32, "air/BMPpressure", "BMPpressure",
bme.readPressure() / 100.0F);
publishSensorDiscovery("sensor",
"bmp280-altitude",
"",
"BMP280 Altitude",
"/MeasuredAltitude",
"meters",
"{{ value_json.MeasuredAltitude }}",
MQTT_ESP32);
// Publish new measured altitude based on preasure value through MQTT
publishSensorData(MQTT_ESP32, "air/MeasuredAltitude", "MeasuredAltitude",
bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.print("Temperature = ");
Serial.print(bme.readTemperature());
Serial.println(" °C");
Serial.print("Pressure = ");
Serial.print(bme.readPressure() / 100.0F);
Serial.println(" hPa");
Serial.print("Approx. Altitude = ");
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");
Serial.print("Humidity = ");
Serial.print(bme.readHumidity());
Serial.println(" %");
Serial.println();
}
void callback(char *topic, byte *payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
client_mqtt_topic = String(topic);
Serial.print("Message:");
client_str = "";
for (int i = 0; i < length; i++) {
client_str += String((char) payload[i]);
}
Serial.println(client_str);
Serial.println();
Serial.println("-----------------------");
}
void reconnect() {
String client_id = "esp32-client-";
// Loop until we're reconnected
while (!client.connected()) {
client_id += String(WiFi.macAddress());
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
Serial.println("connected");
// Subscribe
client.subscribe("esp32/output");
client.subscribe(topic);
client.subscribe(temperature);
client.subscribe(humidity);
client.subscribe(pressure);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
// Publish an MQTT Discovery message for Home Assistant.
//
// Arguments:
//
// - component: the Home Assistant component type of the device, such
// as "sensor" or "binary_sensor".
//
// - config_key: a string that, when combined with the machineId,
// creates a unique name for this sensor. Used both as the
// <object_id> in the discovery topic, and as part of the unique_id.
//
// - device_class: The device class (see
// <https://www.home-assistant.io/docs/configuration/customizing-devices/#device-class>).
// May be 0.
//
// - name_suffix: This will be appended to ha_name to create the
// human-readable name of this sensor. Should typically be
// capitalized.
//
// - state_topic: The topic where this sensor publishes its state.
// The workgroup and machineId will be prepended to form the actual
// topic. This should always start with a slash.
//
// - unit: The unit_of_measurement, or 0.
//
// - value_template: A template to extract a value from the payload.
bool publishSensorDiscovery(const char *component,
const char *config_key,
const char *device_class,
const char *name_suffix,
const char *state_topic,
const char *unit,
const char *value_template,
MQTTName mqtt_name)
{
static char topic[48 + sizeof(machineId)];
snprintf(topic, sizeof(topic),
"homeassistant/%s/%s/%s/config", component, machineId, config_key);
DynamicJsonDocument json(1024);
if (device_class)
json["device_class"] = device_class;
json["name"] = String(ha_name) + " " + name_suffix;
json["unique_id"] = String("AHS-") + machineId + "-" + config_key;
json["state_topic"] = String(workgroup) + "/" + machineId + state_topic;
if (unit)
json["unit_of_measurement"] = unit;
json["value_template"] = value_template;
json["availability_topic"] = mqtt_status(mqtt_name)->availability_topic;
json["device"]["identifiers"] = machineId;
json["device"]["manufacturer"] = "AutomaticHouseSystems";
json["device"]["model"] = PRODUCT;
json["device"]["name"] = String(ha_name) + " " + name_suffix;
json["device"]["sw_version"] = ESP.getSketchMD5();
JsonArray connections = json["device"].createNestedArray("connections").createNestedArray();
connections.add("mac");
connections.add(WiFi.macAddress());
Serial.print("Home Assistant discovery topic: ");
Serial.println(topic);
int payload_len = measureJson(json);
if (!mqtt_client(mqtt_name)->beginPublish(topic, payload_len, true))
{
Serial.println("beginPublish failed!\n");
display.print(": beginPublish failed!");
return false;
}
if (serializeJson(json, *mqtt_client(mqtt_name)) != payload_len)
{
Serial.println("writing payload: wrong size!\n");
display.print(": writing payload: wrong size!");
return false;
}
if (!mqtt_client(mqtt_name)->endPublish())
{
Serial.println("endPublish failed!\n");
display.print(": endPublish failed!");
return false;
}
return true;
}
void publishSensorData(MQTTName mqtt_name, const char* subTopic,
const char* key, const String& value)
{
StaticJsonDocument<100> json;
json[key] = value;
char payload[100];
serializeJson(json, payload);
char topic[200];
sprintf(topic,"%s/%s/%s", workgroup, machineId, subTopic);
mqtt_client(mqtt_name)->publish(topic, payload, true);
}
void publishSensorData(MQTTName mqtt_name, const char* subTopic,
const char* key, const float value)
{
StaticJsonDocument<100> json;
json[key] = value;
char payload[100];
serializeJson(json, payload);
char topic[200];
sprintf(topic,"%s/%s/%s", workgroup, machineId, subTopic);
mqtt_client(mqtt_name)->publish(topic, payload, true);
}
MQTTStatus *mqtt_status(MQTTName name)
{
return &mqtt_statuses[name];
}
PubSubClient *mqtt_client(MQTTName name)
{
return &mqtt(name)->mqttClient;
}
MQTTConnection *mqtt(MQTTName name)
{
return &mqtt_connections[0];
}
void calculateMachineId()
{
const char *s = "";
MD5Builder md5;
md5.begin();
char chipId[25];
char random = 1;
sprintf(chipId,"%d",random);
md5.add(chipId);
md5.calculate();
md5.toString().toCharArray(machineId, sizeof(machineId));
if (!s)
s = machineId;
snprintf(ha_name, sizeof(ha_name), "%s", s);
// Set MQTT topics
sprintf(line1_topic, "cmnd/%s/line1", machineId);
sprintf(line2_topic, "cmnd/%s/line2", machineId);
sprintf(line3_topic, "cmnd/%s/line3", machineId);
sprintf(line4_topic, "cmnd/%s/line4", machineId);
sprintf(line5_topic, "cmnd/%s/line5", machineId);
sprintf(cmnd_temp_format, "cmnd/%s/tempformat", machineId);
sprintf(cmnd_altitude_topic, "cmnd/%s/altitude", machineId);
#ifdef OTA_UPGRADES
sprintf(cmnd_update_topic, "cmnd/%s/update", machineId);
#endif
#ifdef OTA_FACTORY_RESET
sprintf(cmnd_factory_reset_topic, "cmnd/%s/factory-reset", machineId);
#endif
sprintf(cmnd_restart_topic, "cmnd/%s/restart", machineId);
}
void mqtt_online(MQTTName name, bool board )
{
mqtt_status(name)->online(board);
#ifndef USE_MULTIPLE_STATUS_TOPICS
MQTTSpec *spec = &mqtt_specs[name];
if (!spec->ever_online)
{
(*spec->connect_cb)(mqtt(name));
spec->ever_online = true;
}
#endif
}
void mqtt_esp32_connected(MQTTConnection *c)
{
c->mqttClient.subscribe(line1_topic);
c->mqttClient.subscribe(line2_topic);
c->mqttClient.subscribe(line3_topic);
c->mqttClient.subscribe(line4_topic);
c->mqttClient.subscribe(line5_topic);
#ifdef OTA_UPGRADES
c->mqttClient.subscribe(cmnd_update_topic);
#endif
#ifdef OTA_FACTORY_RESET
c->mqttClient.subscribe(cmnd_factory_reset_topic);
#endif
c->mqttClient.subscribe(cmnd_altitude_topic);
c->mqttClient.subscribe(cmnd_restart_topic);
c->mqttClient.subscribe(cmnd_temp_format);
//publishState();
}
#ifndef USE_MULTIPLE_STATUS_TOPICS
void call_mqtt_connect_cbs(MQTTConnection *conn)
{
for (MQTTSpec *spec = mqtt_specs; spec->topic != 0; spec++)
{
if (spec->ever_online)
(*spec->connect_cb)(conn);
}
}
#endif
void mqttReconnect()
{
for (int i = 0; i < MQTT_LAST; i++)
mqtt_connections[i].reconnect();
}
void setup_mqtt(const char *mqtt_server, const char *mqtt_port)
{
const int mqttPort = atoi(mqtt_port);
for (int n = 0; n < MQTT_LAST; n++)
{
if (mqtt_specs[n].name != n)
{
Serial.print("FATAL: Bad MQTT spec ");
Serial.print(n);
Serial.println(".");
nice_restart();
}
mqtt_connections[n].set_spec(&mqtt_specs[n]);
mqtt_statuses[n].set_spec(&mqtt_specs[n]);
mqtt_connections[n].mqttClient.setCallback(callback);
mqtt_connections[n].status_list = &mqtt_statuses[n];
mqtt_statuses[n].conn = &mqtt_connections[n];
#ifdef MQTT_SERVER
mqtt_connections[n].mqttClient.setServer(MQTT_SERVER, mqttPort);
#else
mqtt_connections[n].mqttClient.setServer(mqtt_server, mqttPort);
#endif
}
#if defined(USE_MULTIPLE_STATUS_TOPICS) && !defined(USE_MULTIPLE_MQTT)
for (int n = 1; mqtt_specs[n].topic != 0; n++)
{
mqtt_statuses[n].set_spec(&mqtt_specs[n]);
mqtt_statuses[n].conn = 0;
}
#endif
}
// ESP32 restarts
void nice_restart()
{
// Wait a short while to give the DHT22 time to start responding.
delayMicroseconds(70);
ESP.restart();
// The restart function seems to sometimes return; the actual
// restart happens a short while later. Enter an eternal loop
// here to avoid doing any more work until the restart actually
// happens.
while (1)
;
}
void mqtt_bmp280_connected(MQTTConnection *c)
{
#ifdef HOME_ASSISTANT_DISCOVERY
publishSensorDiscovery("sensor",
"bmp280-temp",
"temperature",
"sensor",
"/BMPtemperature",
"Celsius",
"{{ value_json.BMPtemperature }}",
MQTT_BMP280);
Serial.println("Sensor temperatura conectat !");
#endif
}
void mqtt_temt6000_connected(MQTTConnection *c)
{
#ifdef HOME_ASSISTANT_DISCOVERY
publishSensorDiscovery("sensor",
"temt6000-light",
"Light sensor",
"TEMT6000 Light",
"/TEMT6000_Light",
"%",
"{{ value_json.TEMT6000_Light }}",
MQTT_ESP32);
Serial.println("Sensor luminozitate conectat !");
#endif
}
void LightRead()
{
int Lvalue = analogRead(LIGHT_SENSOR);// read the light
int mVolt = map(Lvalue,0, 1023, 0, 5000);// map analogue reading to 5000mV
int percent = map(Lvalue,0, 1023, 0, 100);// map analogue reading to 100%
float volt =(double)mVolt/1000;// convert millivolt to volt
Serial.print(mVolt);// print millivolt
Serial.print( "mV ...... ");
Serial.print(volt,3);// print volts with 3 decimal places
Serial.print( "V ...... ");
Serial.print(percent);// print percentage
Serial.println( "%");
publishSensorDiscovery("sensor",
"temt6000-light",
"illuminance",
"TEMT6000 Light",
"/light/TEMT6000_Light",
"%",
"{{ value_json.TEMT6000_Light }}",
MQTT_ESP32);
// Publish new measured light value through MQTT
publishSensorData(MQTT_ESP32, "light/TEMT6000_Light", "TEMT6000_Light",
percent);
}

 

 

 

  Carcasa și instalare:

    Carcasa am luat-o de pe thingiverse, dar i-am făcut câteva modificări pentru a putea conecta mai sigur senzorii. Pe lângă asta i-am prevăzut și o gaică pentru prinderea cu un holșurub.



Documentatie proiect:

 

To do:

  • Adăugarea funcționalității de WifiManager si MQTT manager
  • Adăgarea unui senzor de ultraviolete
  • Adaptarea carcasei pentru a fi mai ușor de printat și de montat

 

Pentru întrebari și/sau consultanță tehnică vă stau la dispozitie pe blog sau pe email simedruflorin@automatic-house.ro. O seară/zi plăcută tuturor !

Etichete

Afișați mai multe

Arhiva

Afișați mai multe