Sensor para fluxo de água ESP8266 + MQTT no Home Assistant
Este tutorial vai auxiliar como criar um sensor de fluxo de água para ser instalado na entrada da caixa d'água, e medir o consumo de água através do Home Assistant.Como Funciona?
O sensor de vazão é uma ventoinha que gira com a passagem da água. A informação de quantas vezes está girando é passada para o ESP8266, e este passa para o Home Assistant por MQTT.Confira o vídeo do funcionamento: VIDEO
Ao baixar o nível da caixa, a bóia afunda deixando entrar água na caixa. Esta água que caia direto na caixa agora passo pelo sensor de fluxo de água para contabilizar a água.
Do que precisa
Para este projeto vai precisa de:
1 - Placa Esp82661 - Sensor de fluxo de água 5v1 - Mangueira com 2 roscas femeas de 1/2 |
Sobre ESP8266
Pode utilizar o esp01, pois só vai necessitar de 1 porta para receber as informações do sensor de fluxo de água.Sobre o Sensor de Fluxo de Água
Deve escolher um com a vazão compatível com a pressão de sua tubulação, aqui na minha casa a entrada de água da caixa d'água não passa de 10 litros por minutos, este sensor que comprei é até 30 litros por minutos.Não é recomendado usar sensores pequenos para tubulações pressurizadas, pois vai estancar e diminuir a pressão de toda a tubulação.
Instalar o sensor sempre antes da pressurização. A pressão da rua em alguns casos também é bem elevada, é bom estudar sobre a vazão necessária para dimensionar corretamente o sensor sem perder pressão.
Sobre a Mangueira
Eu optei em instalar este sensor sem cortar nenhum cano, e utilizei um mangueira muito utilizada para ligar máquina de lavar, esta mangueira cortei ao meio para instalar o sensor e não deixar o sensor dentro da caixa d'água, pois acredito que irá resistir a humidade.Com a mangueira também evitei de cortar ou furar a caixa para passar fios ou sensores.
Código no Esp8266:
Para subir o código no ESP8266 utilizar a IDE do Arduino, para saber como ler este tópico aqui no forum.IMPORTANTE: Utilizar a bibliote do esp na versão 2.4.1
Antes de enviar o código para a placa, deve adicionar as informações de seu MQTT, altere as linha no código:
- #define MQTT_USERNAME "usuario_do_mqtt"
- #define MQTT_PASSWORD "senha_do_mqtt"
- const char *MQTT_SERVER = "IP_do_MQTT";
A base deste código foi utilizado o do medir consumo de energia de Bruno Horta
//MQTT - como instalar -> https://www.youtube.com/watch?v=GMMH6qT8_f4
#include <PubSubClient.h>
//ESP - como instalar -> https://www.youtube.com/watch?v=4d8joORYTIA&t=1s
#include <ESP8266WiFi.h>
//Wi-Fi Manager como instalar -> https://www.youtube.com/watch?v=wWO9n5DnuLA
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
//OTA -> já está incluida no IDE do Arudino
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
IPAddress ip(192,168,15,155);
// Configuração do acesso ao Broker MQTT
#define MQTT_AUTH true
#define MQTT_USERNAME "usuario_do_mqtt"
#define MQTT_PASSWORD "senha_do_mqtt"
// Wifi: SSID and password
//Constantes
const String HOSTNAME = "Medir_Agua"; //NOME DO DEVICE, este nome tambem é utilizado apra criar o Access Point para configuração
const char *OTA_PASSWORD = ""; // Password para atualizar o Firmware Over the Air
const char *MQTT_LOG = "system/log"; // Topico onde o Device Publica informações relacionadas com o sistema
const char *MQTT_SYSTEM_CONTROL_TOPIC = "system/set"; // Topico onde o Device subscreve para aceitar instruções de sistema
const char *MQTT_TEST_TOPIC = "superTopic"; //Topico de exemplo onde o Device subscreve (por exemplo controlar uma lâmpada)
const char *MQTT_SERVER = "IP_do_MQTT"; //IP ou DNS do Broker MQTT
WiFiClient wclient;
PubSubClient client(MQTT_SERVER, 1883, wclient);
//FLAGS de Controlo
bool OTA = false; //O Serviço OTA é muito pesado para estar sempre ativo por isso é ligado via MQTT e fica disponivel até ser desligado ou até o device ser reiniciado
bool OTABegin = false;
//Variareis da Agua
float vazao; //Variável para armazenar o valor em L/min
float media=0; //Variável para tirar a média a cada 1 minuto
int contaPulso; //Variável para a quantidade de pulsos
int i=0; //Variável para contagem
void setup() {
Serial.begin(9600);
WiFiManager wifiManager;
//wifiManager.resetSettings(); //Limpa a configuração anterior do Wi-Fi SSID e Password, procedimento, 1º descomentar a linha, 2º Fazer Upload do código para o ESP e deixar o ESP arrancar, 3º Voltar a comentar a linha e enviar novamente o código para o ESP
/*define o tempo limite até o portal de configuração ficar novamente inátivo,
útil para quando alteramos a password do AP*/
wifiManager.setTimeout(180);
wifiManager.autoConnect(HOSTNAME.c_str());
client.setCallback(callback); //Registo da função que vai responder ás mensagens vindos do MQTT
//Setup da agua
pinMode(2, INPUT); //D3
attachInterrupt(0, incpulso, RISING); //Configura o pino 2(Interrupção 0) para trabalhar como interrupção
Serial.println("\n\nInicio\n\n"); //Imprime Inicio na serial
}
//Chamada de recepção de mensagem
void callback(char *topic, byte *payload, unsigned int length) {
String payloadStr = "";
for (int i = 0; i < length; i++) {
payloadStr += (char)payload[i];
}
String topicStr = String(topic);
if (topicStr.equals(MQTT_SYSTEM_CONTROL_TOPIC)) {
if (payloadStr.equals("OTA_ON_" + String(HOSTNAME))) {
Serial.println("OTA ON");
OTA = true;
OTABegin = true;
} else if (payloadStr.equals("OTA_OFF_" + String(HOSTNAME))) {
Serial.println("OTA OFF");
OTA = false;
OTABegin = false;
} else if (payloadStr.equals("REBOOT_" + String(HOSTNAME))) {
Serial.println("REBOOT");
ESP.restart();
}
} else if (topicStr.equals(MQTT_TEST_TOPIC)) {
//TOPICO DE TESTE
Serial.println(payloadStr);
}
}
bool checkMqttConnection() {
if (!client.connected()) {
if (MQTT_AUTH ? client.connect(HOSTNAME.c_str(), MQTT_USERNAME, MQTT_PASSWORD) : client.connect(HOSTNAME.c_str())) {
Serial.println("CONNECTED TO MQTT BROKER " + String(MQTT_SERVER));
client.publish(MQTT_LOG, String("CONNECTED_" + HOSTNAME).c_str());
//SUBSCRIÇÃO DE TOPICOS
client.subscribe(MQTT_SYSTEM_CONTROL_TOPIC);
client.subscribe(MQTT_TEST_TOPIC);
}
}
return client.connected();
}
void loop() {
if (WiFi.status() == WL_CONNECTED) {
if (checkMqttConnection()) {
client.loop();
if (OTA) {
if (OTABegin) {
setupOTA();
OTABegin = false;
}
ArduinoOTA.handle();
}
//Inicio Agua
contaPulso = 0; //Zera a variável para contar os giros por segundos
sei(); //Habilita interrupção
delay (1000); //Aguarda 1 segundo
cli(); //Desabilita interrupção
vazao = contaPulso / 5.5; //Converte para L/min
media=media+vazao; //Soma a vazão para o calculo da media
i++;
Serial.print(vazao); //Imprime na serial o valor da vazão
Serial.print(" L/min - "); //Imprime L/min
Serial.print(i); //Imprime a contagem i (segundos)
Serial.println("s"); //Imprime s indicando que está em segundos
String consumo_agua = String(vazao);
String payload = "{";
payload += "\"consumo_agua\":"; payload += consumo_agua;
payload += "}";
char attributes[100];
payload.toCharArray( attributes, 100 );
client.publish( "system/contagem", attributes );
Serial.println( attributes );
if(i==60)
{
media = media/60; //Tira a media dividindo por 60
Serial.print("\nMedia por minuto = "); //Imprime a frase Media por minuto =
Serial.print(media); //Imprime o valor da media
Serial.println(" L/min - "); //Imprime L/min
media = 0; //Zera a variável media para uma nova contagem
i=0; //Zera a variável i para uma nova contagem
Serial.println("\n\nInicio\n\n"); //Imprime Inicio indicando que a contagem iniciou
}
// Fim agua
}
}
}
void incpulso () {
contaPulso++; //Incrementa a variável de pulsos
}
void setupOTA() {
if (WiFi.status() == WL_CONNECTED && checkMqttConnection()) {
client.publish(MQTT_LOG, "OTA SETUP");
ArduinoOTA.setHostname(HOSTNAME.c_str());
ArduinoOTA.setPassword(OTA_PASSWORD);
ArduinoOTA.onStart([]() {
client.publish(MQTT_LOG, "START");
});
ArduinoOTA.onEnd([]() {
client.publish(MQTT_LOG, "END");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
String p = "Progress: " + String((progress / (total / 100)));
client.publish(MQTT_LOG, p.c_str());
});
ArduinoOTA.onError([](ota_error_t error) {
if (error == OTA_AUTH_ERROR)
client.publish(MQTT_LOG, "Auth Failed");
else if (error == OTA_BEGIN_ERROR)
client.publish(MQTT_LOG, "Begin Failed");
else if (error == OTA_CONNECT_ERROR)
client.publish(MQTT_LOG, "Connect Failed");
else if (error == OTA_RECEIVE_ERROR)
client.publish(MQTT_LOG, "Receive Failed");
else if (error == OTA_END_ERROR)
client.publish(MQTT_LOG, "End Failed");
});
ArduinoOTA.begin();
}
}
Instalação
Usar uma mangueira para conectar na entrada da caixa d'água, cortar a mangueira para passar pelo sensor de fluxo de água e retornar a mangueira para a caixa d'água. |
Esquema de Ligação
Com uma fonte de celular 5v, alimente o ESP8266 e o sensor de fluxo de água.O fio de comunicação do sensor deve ser ligado na porta D3 do ESP8266
Calibrar o sensor
Este código está calibrado para um sensor de 1/2, caso tenha outro talvez seja necessário calibrar.Após a instalação do sensor na caixa d´água. Encha um balde de água de 10litros por exemplo e verifique se está medindo corretamente o consumo. Caso tenha alguma diferença, faça o ajuste alterando (o valor 5.5) na linha no código:
- vazao = contaPulso / 5.5;
Configuração no HA
Adicionar os códigos abaixo no configuration.yamlSensor que vai medir o consumo em tempo real da água que passa pelo sensor de água.
sensor:
- platform: mqtt
state_topic: 'system/contagem'
name: 'Consumo Agua'
unit_of_measurement: 'litros'
value_template: '{{ value_json.consumo_agua }}'
Adicionar UtilityMeter para acompanhar o consumo:
utility_meter:
consumo_agua_dia:
source: sensor.consumo_agua
cycle: daily
consumo_agua_semana:
source: sensor.consumo_agua
cycle: weekly
consumo_agua_mes:
source: sensor.consumo_agua
cycle: monthly
consumo_agua_ano:
source: sensor.consumo_agua
cycle: yearly
Automações
Não fiz nenhuma até o momento, mas é possível fazer automações, que enviem notificações no caso de consumo maior que a média estipulada por exemplo. Ou fazer uma automação para notificar torneira ligada, ou detecção de vazamento.Este tutorial é um exemplo, caso tenha melhorias e sugestões não deixe de enviar!
Este projeto está funcionando em aproximadamente 1 mês em minha casa, não sou profissional nesta área, e minha intenção é compartilhar este projeto para ser melhorado ou implantado por sua conta e risco.
Ajude a comunidade Home Assitant Brasil, compartilhando seu projeto e participamento neste forum!