613 lines
26 KiB
C++
613 lines
26 KiB
C++
/**
|
||
Created on: 01.01.2021
|
||
Счётчик воды и протечки WEB морда для ESP8266
|
||
1) Установить: http://wiki.amperka.ru/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:esp8266:esptool
|
||
Для 1MB флешь памяти, файловая система: http://wikihandbk.com/wiki/ESP8266:%D0%9F%D1%80%D0%BE%D1%88%D0%B8%D0%B2%D0%BA%D0%B8/Arduino/%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0_%D1%81_%D1%84%D0%B0%D0%B9%D0%BB%D0%BE%D0%B2%D0%BE%D0%B9_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%BE%D0%B9_%D0%B2_%D0%B0%D0%B4%D0%B4%D0%BE%D0%BD%D0%B5_ESP8266_%D0%B4%D0%BB%D1%8F_IDE_Arduino
|
||
|
||
На борту счётчика выход
|
||
2 входа для счётчика горячей и холодной (Подключено к STM8L051 геркон)
|
||
1 вход для датчика утечки (Подключено к STM8L051 200 ком резистор по моему)
|
||
1 кнопка для включения ESP8266 и перехода в настройки при длительном нажатии (10 секунд) а при коротком просто отправить данные по WIFI (Подключено к STM8L051 кнопка)
|
||
1 кнопочка для открытия кранов не смотря на утеку воды (для пожаробезопасности) (Подключено к STM8L051 кнопка)
|
||
|
||
Подробнее схемотехника на: https://easyeda.com/ru
|
||
Другая документация на O:\MyDocuments\projects\_Doc\Water_meter_observer
|
||
*/
|
||
//----------------------------------------------------------------------------------------------------
|
||
#include <Arduino.h>
|
||
#include <ArduinoJson.h>
|
||
|
||
#include <ESP8266WiFi.h>
|
||
#include <ESP8266WebServer.h> // Include the WebServer library
|
||
#include <DNSServer.h>
|
||
#include <ESP8266mDNS.h>
|
||
#include <Ticker.h> //Ticker Library
|
||
|
||
#include <LittleFS.h> //Прмер: https://github.com/lorol/ESPAsyncWebServer/blob/master/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino
|
||
#include <PubSubClient.h> //Для отправки данных по MQTT см.: https://www.emqx.io/blog/esp8266-connects-to-the-public-mqtt-broker
|
||
|
||
#include "Bounce2.h"
|
||
#include "tools.h"
|
||
//----------------------------------------------------------------------------------------------------
|
||
#define PIN_LED 02 //Пин светодиода
|
||
|
||
Bounce bounce = Bounce(); //Для избавления от дребезга контактов
|
||
|
||
int blink=LOW; //Для мигания при настройке
|
||
int blinkMSec=0; //Для мигания при настройке
|
||
|
||
ESP8266WebServer server(80); // Set web server and port number to 80
|
||
WiFiClient wifiClient;
|
||
WiFiClientSecure wifiClientS;
|
||
IPAddress local_IP(192,168,1,1); //Для точки доступа
|
||
IPAddress gateway(192,168,1,1); //Для точки доступа
|
||
IPAddress subnet(255,255,255,0); //Для точки доступа
|
||
IPAddress DNS_IP(192,168,1,1);
|
||
int lastPS=0; //сколько приконекченных
|
||
|
||
// DNS server
|
||
const byte DNS_PORT = 53;
|
||
DNSServer dnsServer;
|
||
|
||
//Для входа и выхода из режима настройки WIFI
|
||
#define CNF_TIME 300; //Сколько секунд даётся для настройки оборудования (600=5минут)
|
||
int g_ticks = CNF_TIME; //Переменная для отсчёта секунд, как дойдёт до нуля то засыпаем
|
||
Ticker blinker; //Для подсчёта времени до входа в спящий режим (предполагаю просыпание по кнопке ресет)
|
||
|
||
String ssid="Node6";
|
||
String pass="isecretk";
|
||
|
||
PubSubClient mqttClient;
|
||
|
||
String mqtt_protocol = "tcp";
|
||
String mqtt_host = "observer.kz"; // Имя сервера MQTT
|
||
uint16_t mqtt_port = 1883; // Порт для подключения к серверу MQTT
|
||
String mqtt_fingerprint = ""; //Отпечаток сертификата
|
||
String mqtt_user = ""; // Логи для подключения к серверу MQTT
|
||
String mqtt_pass = ""; // Пароль для подключения к серверу MQTT
|
||
String mqtt_topic = "home/water/main"; /* 1=on, 0=off else toggle*/
|
||
#define LED_QOS 1 //0 - Без подтверждения 1 - С подтверждением 2 - С подтверждением и без возможности двойной отправки
|
||
|
||
int time5s=millis(); //Для реконекта каждые 5 секунд
|
||
String uuid=""; //Уникальный ID клиента (загружается из файловой системы)
|
||
|
||
String g_data; //Для накопления данных с последовательного порта
|
||
//----------------------------------------------------------------------------------------------------
|
||
int g_cold = -1; //Показание холодной воды
|
||
int g_hot = -1; //Показание горячей воды
|
||
int g_leak = -1; //Протечка 0 нет 1 есть
|
||
int g_volt = -1; //Вольт на акамуляторе
|
||
int g_tmpr = -100; //Температура на микроконтроллере
|
||
//----------------------------------------------------------------------------------------------------
|
||
bool configWebServer();
|
||
void setLampLight(int mode);
|
||
|
||
//----------------------------------------------------------------------------------------------------
|
||
//Load settings from file system to local variables
|
||
bool loadConfig()
|
||
{
|
||
File f = LittleFS.open("settings.txt", "r");
|
||
String line="";
|
||
do {
|
||
line=readLine(f);
|
||
if(line!=""){
|
||
if(BeforeFirst(line,'=')=="ssid") ssid=AfterFirst(line,'='); //Название сети
|
||
else if(BeforeFirst(line,'=')=="pass") pass=AfterFirst(line,'='); //Номер сети
|
||
else if(BeforeFirst(line,'=')=="mqtt_protocol") mqtt_protocol=AfterFirst(line,'=');
|
||
else if(BeforeFirst(line,'=')=="mqtt_host") mqtt_host=AfterFirst(line,'=');
|
||
else if(BeforeFirst(line,'=')=="mqtt_port") mqtt_port=AfterFirst(line,'=').toInt();
|
||
else if(BeforeFirst(line,'=')=="mqtt_fingerprint") mqtt_fingerprint=AfterFirst(line,'=');
|
||
else if(BeforeFirst(line,'=')=="mqtt_user") mqtt_user=AfterFirst(line,'=');
|
||
else if(BeforeFirst(line,'=')=="mqtt_pass") mqtt_pass=AfterFirst(line,'=');
|
||
else if(BeforeFirst(line,'=')=="mqtt_topic") mqtt_topic=AfterFirst(line,'=');
|
||
}
|
||
} while (line!="");
|
||
f.close();
|
||
|
||
Serial.println("SSID = "+ssid);
|
||
Serial.println("MQTT HOST = "+mqtt_host);
|
||
|
||
return true;
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
//Save settings from local variables to file system
|
||
bool saveConfigs()
|
||
{
|
||
File f = LittleFS.open("settings.txt", "w");
|
||
if (!f) {
|
||
Serial.println("Count file open failed on update.");
|
||
} else {
|
||
f.println("ssid="+ssid);
|
||
f.println("pass="+pass);
|
||
|
||
f.println("mqtt_protocol="+mqtt_protocol);
|
||
f.println("mqtt_host="+mqtt_host);
|
||
f.println("mqtt_port="+String(mqtt_port));
|
||
f.println("mqtt_fingerprint="+mqtt_fingerprint);
|
||
f.println("mqtt_topic="+mqtt_topic);
|
||
f.println("mqtt_user="+mqtt_user);
|
||
f.println("mqtt_pass="+mqtt_pass);
|
||
|
||
f.close();
|
||
}
|
||
return true;
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
//Запрос на получение данных с микроконтроллера
|
||
//Для дебага написал тестовую программу клторая эиетирует STM8L по последовательному порту: O:\MyDocuments\projects\Workspace_C++Builder\NeptuneW01
|
||
bool getMode(){
|
||
Serial.println(addCRC("#0;")); //Запрашиваю для какого режима работы включили WIFI
|
||
return true;
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
// Запрашиваю данные с датчиков
|
||
bool callSensorsData(){
|
||
Serial.println(addCRC("#1;")); //Запрашиваем '1'=холодная
|
||
Serial.println(addCRC("#2;")); //Запрашиваем '2'=горячая
|
||
Serial.println(addCRC("#3;")); //Запрашиваем '3'=протечки
|
||
Serial.println(addCRC("#4;")); //Запрашиваем '4'=вольт на аккумуляторе
|
||
Serial.println(addCRC("#5;")); //Запрашиваем '5'=температура на процессоре
|
||
//Уровень WIFI сигнала берём на ESP8266 а не с STM8L051
|
||
return true;
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
// Отправляю данные на STM8L для сохранения
|
||
bool saveToProc(){
|
||
//
|
||
return true;
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
void handleNotFound() {
|
||
server.send(404, "text/plain", "FileNotFound");
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
//Отправляю показания датчиков для режима настройки
|
||
void handleSensors() {
|
||
|
||
callSensorsData(); //Запрашиваю новые данные датчиков с микроконтроллера
|
||
|
||
String json;
|
||
json.reserve(500); //У меня дома около 500 символов было необходимо
|
||
|
||
//Видимые сети
|
||
json = "{\"networks\":[";
|
||
int n = WiFi.scanNetworks();
|
||
Serial.print(n);
|
||
Serial.println(" network(s) found");
|
||
for (int i = 0; i < n; i++)
|
||
{
|
||
json += "{\"name\":\"";
|
||
json += WiFi.SSID(i); //Название сети
|
||
json += "\",\"lock\":";
|
||
json += WiFi.encryptionType(i); //Шифрование
|
||
json += ",\"strength\":";
|
||
json += WiFi.RSSI(i); //Уровень сигнала
|
||
json += "}";
|
||
if(i!=n-1) json += ",";
|
||
}
|
||
json += "],";
|
||
//Количество тиков до перехода в спящий режим
|
||
json += "\"ticks\":"+String(g_ticks);
|
||
|
||
if(g_cold<0) json += ",\"cold\":null"; else json += ",\"cold\":"+String(g_cold);
|
||
if(g_hot<0) json += ",\"hot\":null"; else json += ",\"hot\":"+String(g_hot);
|
||
if(g_leak==1) json += ",\"leak\":true"; else if(g_leak==0) json += ",\"leak\":false"; else json += ",\"leak\":null";
|
||
if(g_volt<0) json += ",\"volt\":null"; else json += ",\"volt\":"+String(g_volt);
|
||
if(g_tmpr<=-100) json += ",\"tmpr\":null"; else json += ",\"tmpr\":"+String(g_tmpr); // Температура
|
||
|
||
json += "}";
|
||
server.send(200, "application/json", json);
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
//Отправляем настройки сети (для режима настройки)
|
||
void handleData(){
|
||
String json;
|
||
json.reserve(128);
|
||
|
||
json = "{";
|
||
|
||
json += "\"ssid\":\""+ssid+"\"";
|
||
json += ",\"pass\":\""+pass+"\"";
|
||
json += ",\"uuid\":\""+uuid+"\"";
|
||
|
||
json += ",\"mqtt_protocol\":\""+mqtt_protocol+"\"";
|
||
json += ",\"mqtt_host\":\""+mqtt_host+"\"";
|
||
json += ",\"mqtt_port\":\""+String(mqtt_port)+"\"";
|
||
json += ",\"mqtt_fingerprint\":\""+mqtt_fingerprint+"\"";
|
||
json += ",\"mqtt_topic\":\""+mqtt_topic+"\"";
|
||
json += ",\"mqtt_user\":\""+mqtt_user+"\"";
|
||
json += ",\"mqtt_pass\":\""+mqtt_pass+"\"";
|
||
|
||
json += "}";
|
||
|
||
server.send(200, "application/json", json);
|
||
}
|
||
//=======================================================================
|
||
void handleSave(){
|
||
//Serial.println("+++Save+++");
|
||
if(server.args()>0){
|
||
for(int i=0;i<server.args();i++){
|
||
//Serial.println("Nane = "+server.argName(i));
|
||
//Serial.println(server.arg(i));
|
||
|
||
if(server.argName(i)=="ssid")
|
||
ssid=server.arg(i);
|
||
if(server.argName(i)=="pass")
|
||
pass=server.arg(i);
|
||
|
||
if(server.argName(i)=="cold" && server.arg(i)!=""){
|
||
g_cold=server.arg(i);
|
||
}
|
||
if(server.argName(i)=="hot" && server.arg(i)!=""){
|
||
g_hot=server.arg(i);
|
||
}
|
||
|
||
if(server.argName(i)=="mqtt_protocol")
|
||
mqtt_protocol=server.arg(i);
|
||
if(server.argName(i)=="mqtt_host")
|
||
mqtt_host=server.arg(i);
|
||
if(server.argName(i)=="mqtt_port")
|
||
mqtt_port=server.arg(i).toInt();
|
||
if(server.argName(i)=="mqtt_fingerprint")
|
||
mqtt_fingerprint=server.arg(i);
|
||
if(server.argName(i)=="mqtt_topic")
|
||
mqtt_topic=server.arg(i);
|
||
if(server.argName(i)=="mqtt_user")
|
||
mqtt_user=server.arg(i);
|
||
if(server.argName(i)=="mqtt_pass")
|
||
mqtt_pass=server.arg(i);
|
||
}
|
||
}
|
||
server.send(200, "text/html", "ok");
|
||
}
|
||
//=======================================================================
|
||
void handleMain() {
|
||
if(LittleFS.exists("/index.html")){
|
||
//Serial.println("File exists.");
|
||
File file = LittleFS.open("/index.html", "r");
|
||
if(file){
|
||
if(server.streamFile(file, "text/html")!= file.size()){
|
||
Serial.println("Sent less data than expected!"); //Отправленно меньше данных чем ожидалось
|
||
}
|
||
file.close();
|
||
}
|
||
}else{
|
||
Serial.println("File not exists!");
|
||
}
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
//Подключиться к сохраненой точки доступа и поднять HTML сервер
|
||
bool connectToWIFIPoint(){
|
||
|
||
WiFi.mode(WIFI_STA); //WIFI_STA - Режим только клиента
|
||
|
||
WiFi.hostname("Water_meter_V01");
|
||
WiFi.setAutoReconnect(true);
|
||
WiFi.begin(ssid, pass);
|
||
/*Serial.print("Connecting to ");
|
||
int i = 60; //Чтобы больше минуты не ждал
|
||
while (WiFi.status() != WL_CONNECTED && i>0) { // Wait for the Wi-Fi to connect
|
||
delay(1000);
|
||
Serial.print(--i); Serial.print(' ');
|
||
}*/
|
||
|
||
return true;
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
//Отключиться от точки доступа
|
||
bool disconnectFromWIFIPoint(){
|
||
WiFi.setAutoReconnect(false);
|
||
WiFi.disconnect(true);
|
||
return true;
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
//Инициилизировать WIFI точку доступа для настройки выключателя а также поднять HTML сервер
|
||
bool createAP(){
|
||
|
||
//WiFi.mode(WIFI_AP_STA); //WIFI_AP_STA - Режим точки доступа и клиента WIFI_AP - Режим только точки доступа
|
||
WiFi.mode(WIFI_AP); //WIFI_AP - Режим только точки доступа
|
||
|
||
//Настройки точки доступа
|
||
if(WiFi.softAPConfig(local_IP, gateway, subnet)){
|
||
Serial.println("Ready WiFi.softAPConfig");
|
||
}
|
||
|
||
Serial.print("Setting soft-AP ... ");
|
||
boolean result = WiFi.softAP("NeptuneW01");
|
||
if(result == true)
|
||
{
|
||
Serial.println("Ready");
|
||
IPAddress IP = WiFi.softAPIP();
|
||
Serial.println(IP);
|
||
//Serial.println(WiFi.localIP());
|
||
|
||
//Настройте DNS-сервер, перенаправляющий все домены на apIP
|
||
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
|
||
dnsServer.start(DNS_PORT, "*", DNS_IP);
|
||
|
||
configWebServer();
|
||
}
|
||
else
|
||
{
|
||
Serial.println("Failed!");
|
||
}
|
||
return true;
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
//Отключить программную точку доступа
|
||
bool deleteAP(){
|
||
Serial.print("softAPdisconnect();");
|
||
dnsServer.stop();
|
||
bool result=WiFi.softAPdisconnect(true);
|
||
//Гашу светодиод
|
||
digitalWrite(LED_BUILTIN,HIGH); //LOW
|
||
|
||
return result;
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
//Функция для подсчёта времени до перехода в спящий режим
|
||
void tick_1s()
|
||
{
|
||
g_ticks--;
|
||
if(g_ticks==0){ //Переходим в спящий режим
|
||
Serial.print("Deep sleep!");
|
||
Serial.print(addCRC("#d;!")); //Отсылаю команду на STM8 чтобы он на CHIP_PU подал низский сигнал для отключения питания
|
||
}
|
||
//Если в течении 2х минут не перешли в режим глубокого сна то переходим в обычный сон
|
||
if(g_ticks==-600){
|
||
Serial.println("Sleep!");
|
||
Serial.print(addCRC("#d;!")); //Повторно отсылаю команду на STM8 чтобы он на CHIP_PU подал низский сигнал для отключения питания
|
||
ESP.deepSleep(0);
|
||
}
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
bool configWebServer(){
|
||
Serial.println("configWebServer()");
|
||
|
||
server.on("/sensors/", HTTP_GET, handleSensors);
|
||
server.on("/data/", HTTP_GET, handleData);
|
||
server.on("/save/", HTTP_POST, handleSave);
|
||
server.on("/", HTTP_GET, handleMain);
|
||
server.onNotFound(handleNotFound);
|
||
// Start server
|
||
server.begin();
|
||
|
||
return true;
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
// подключаемся к MQTT серверу
|
||
bool connectToMQTT(){
|
||
Serial.println("mqtt_protocol = "+mqtt_protocol+" mqtt_host = "+mqtt_host+" mqtt_port = " + String(mqtt_port));
|
||
|
||
// Fingerprint of the broker CA
|
||
// openssl x509 -in m2mqtt_srv.crt -sha1 -noout -fingerprint
|
||
if(mqtt_protocol=="tcp"){
|
||
mqttClient.setClient(wifiClient);
|
||
}else{
|
||
mqttClient.setClient(wifiClientS);
|
||
wifiClientS.setFingerprint(mqtt_fingerprint.c_str());
|
||
}
|
||
|
||
//Присваиваю настройки
|
||
mqttClient.setServer(mqtt_host.c_str(),mqtt_port);
|
||
|
||
if (WiFi.status() == WL_CONNECTED) {
|
||
if(!mqttClient.connected()) {
|
||
if (mqttClient.connect(uuid.c_str() )) {
|
||
Serial.println("connected");
|
||
/*mqttClient.setCallback(callback);
|
||
if(mqttClient.subscribe(String(mqtt_topic+"/set").c_str(),LED_QOS)) //Подписываемся на топик
|
||
Serial.println(String("Subscribe on ")+mqtt_topic);
|
||
else
|
||
Serial.println("Error subscribe.");*/
|
||
} else {
|
||
Serial.print("failed, status code =");
|
||
Serial.print(mqttClient.state());
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
void setup()
|
||
{
|
||
Serial.begin(115200);
|
||
Serial.println("");
|
||
Serial.println("Init led pin");
|
||
//Настраиваем светодиод на плате
|
||
pinMode(PIN_LED, OUTPUT);
|
||
digitalWrite(PIN_LED, HIGH); // Выключаю светодиод
|
||
|
||
//Инициализирую файловую систему
|
||
if(LittleFS.begin())
|
||
Serial.println("SPIF FS ready");
|
||
else
|
||
Serial.println("SPIF FS failed");
|
||
|
||
uuid=readUUID(); //Загружаю уникальный идентификатор клиента
|
||
|
||
loadConfig(); //Загружаю настройки в локальные переменные
|
||
|
||
blinker.attach(1, tick_1s); //Инициализирую таймер для контроля времени работы ESP8266
|
||
|
||
connectToWIFIPoint(); //Пытаюсь подключиться к настроенной точке доступа
|
||
/*
|
||
connectToMQTT(); //Пытаюсь опубликовать топик
|
||
*/
|
||
//Заранее инициализирую HTTP сервер чтобы не замарачиваться с логигой его работы...
|
||
configWebServer();
|
||
|
||
//Запрашиваю актуальную информацию по датчикам c STM8 микроконтролера по USART
|
||
getMode();
|
||
|
||
}
|
||
//----------------------------------------------------------------------------------------------------
|
||
bool first=true;
|
||
//=======================================================================
|
||
void loop(){
|
||
|
||
mqttClient.loop();
|
||
dnsServer.processNextRequest(); //DNS
|
||
server.handleClient(); //Обрабатываем запрос клиента (без этого не берётся IP адресс)
|
||
|
||
//Как приконнектились отображаю IP адрес
|
||
if(WiFi.status() == WL_CONNECTED){
|
||
if(first){ //Если приконектились или переконектились то отображаю IP адресс
|
||
Serial.println();
|
||
Serial.print("Local IP address:\t");
|
||
Serial.println(WiFi.localIP());
|
||
first=false;
|
||
}
|
||
}else{
|
||
first=true;
|
||
}
|
||
//если кто приконектился то выводим это в консоль
|
||
if(WiFi.softAPgetStationNum()!=lastPS)
|
||
{
|
||
lastPS=WiFi.softAPgetStationNum();
|
||
Serial.printf("Stations connected to soft-AP = %d\n", WiFi.softAPgetStationNum());
|
||
}
|
||
/*
|
||
//После запуска спрашиваем в каком режиме работать настройки или передачи показаний
|
||
if(millis()-time5s>30000){
|
||
getMode();
|
||
time5s=millis();
|
||
}
|
||
*/
|
||
|
||
/*
|
||
mqttClient.loop();
|
||
|
||
dnsServer.processNextRequest(); //DNS
|
||
server.handleClient(); //Обрабатываем запрос клиента (без этого не берётся IP адресс)
|
||
|
||
|
||
|
||
if(g_ticks>0){
|
||
//В режиме конфигурации каждые 500 миллисекунд меняем цвет зелёного светодиода
|
||
if(millis()-blinkMSec>500){
|
||
blink=!blink;
|
||
digitalWrite(LED_BUILTIN,blink);
|
||
blinkMSec=millis();
|
||
}
|
||
}else{
|
||
//Если в нормальном режиме функционирования
|
||
//Проверяю соединение с MQTT и если не соединён то пытаюсь подключиться каждые 10 секунд
|
||
if(millis()-time5s>10000){
|
||
if(!mqttClient.connected()) {
|
||
connectToMQTT();
|
||
}
|
||
time5s=millis();
|
||
}
|
||
}
|
||
|
||
*/
|
||
|
||
|
||
//Блок кода для общения с энергоэфективным микроконтроллером
|
||
int inByte = 0;
|
||
if (Serial.available() > 0) { //если есть доступные данные то обрабатываем их
|
||
//Serial.println("available = "+String(Serial.available()));
|
||
|
||
// считываем байты в строку до символа с символа '#' до символа '*'
|
||
for(int i=0;i<Serial.available();i++){
|
||
inByte = Serial.read();
|
||
if(inByte=='#') g_data=""; //Новая строка
|
||
g_data+=(char)inByte;
|
||
if(inByte=='*') break;
|
||
}
|
||
|
||
//Если первый и последний символ в строке равен нужным сиволам то это полный ответ c CRC суммой
|
||
if(g_data[0]=='#' && g_data[g_data.length()-1]=='*')
|
||
{
|
||
g_data[0]='@'; //Чтобы команда заново не выполнилась
|
||
Serial.print("Length = "+String(g_data.length())+" ansver = "+g_data);
|
||
g_data[0]='#';
|
||
Serial.println("");
|
||
|
||
if(checkCRC(g_data)) //Проверяю CRC принятых данных
|
||
{
|
||
String cmd=CutBeforeFirst(g_data,';',false); //Отделяю команду
|
||
|
||
if(cmd=="#0;"){ //'0'=проверка зачем разбудили WIFI
|
||
String value=CutBeforeFirst(g_data,'!',true); //Если 1 то отправлять данные на сервер если 0 то войти в режим настройки в качестве точки доступа
|
||
Serial.print("value mode = ");
|
||
Serial.println(value);
|
||
if(value=="1"){ //Если разбудили для того чтобы передать данные
|
||
Serial.println("Send data mode");
|
||
if(deleteAP()){
|
||
connectToWIFIPoint();
|
||
}
|
||
}
|
||
if(value=="0"){ //Если разбудили для того чтобы настроить оборудование
|
||
Serial.println("Config mode");
|
||
if(disconnectFromWIFIPoint()){
|
||
if(createAP()){
|
||
g_ticks = CNF_TIME;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if(cmd=="#1;"){ //'1'=холодная
|
||
String value=CutBeforeFirst(g_data,'!',true);
|
||
Serial.print("value cold = ");
|
||
Serial.println(value);
|
||
g_cold=value.toInt();
|
||
}
|
||
if(cmd=="#2;"){ //'2'=горячая
|
||
String value=CutBeforeFirst(g_data,'!',true);
|
||
Serial.print("value hot = ");
|
||
Serial.println(value);
|
||
g_hot=value.toInt();
|
||
}
|
||
if(cmd=="#3;"){ //'3'=протечки
|
||
String value=CutBeforeFirst(g_data,'!',true);
|
||
Serial.print("value leak = ");
|
||
Serial.println(value);
|
||
g_leak=value.toInt();
|
||
}
|
||
if(cmd=="#4;"){ //'4'=вольт на аккумуляторе
|
||
String value=CutBeforeFirst(g_data,'!',true);
|
||
Serial.print("value volt = ");
|
||
Serial.println(value);
|
||
g_volt=value.toInt();
|
||
}
|
||
if(cmd=="#5;"){ //'5'=температура
|
||
String value=CutBeforeFirst(g_data,'!',true);
|
||
Serial.print("value tmrt = ");
|
||
Serial.println(value);
|
||
g_tmpr=value.toInt();
|
||
}
|
||
}
|
||
g_data=""; //Обработали ответ
|
||
}
|
||
}
|
||
|
||
//Как все данные накопились отправляем их по MQTT на сервер
|
||
if(WiFi.status() == WL_CONNECTED && g_cold!=-1 && g_hot!=-1 && g_leak!=-1 && g_volt !=-1){
|
||
|
||
String data="{";
|
||
data+="\"cold\":"+String(g_cold)+","; // Горячая
|
||
data+="\"hot\":"+String(g_hot)+","; // Холодная
|
||
data+="\"leak\":"+String(g_leak)+","; // Протечки
|
||
data+="\"volt\":"+String(g_volt/100.0f); // Вольт на акумуляторе
|
||
if(g_tmpr>-100){
|
||
data+=",\"tmpr\":"+String(g_tmpr); // Температура
|
||
}
|
||
data+=",\"rssi\":"+String(WiFi.RSSI()); //Уровень WIFI сигнала
|
||
data+="}";
|
||
mqttClient.publish(mqtt_topic.c_str(), data.c_str(), true); //Отправляю данные в топик (С флагом RETAIN чтобы слушатели которые подключились поздно получили тек. состояние)
|
||
|
||
Serial.println(data);
|
||
|
||
//Как отправили данные устанавливаю время ожидания входа в сон на 5 секунд чтобы ESP8266 заснул
|
||
g_ticks=5;
|
||
//Очищаю данные
|
||
g_cold=-1;
|
||
g_hot=-1;
|
||
g_leak=-1;
|
||
g_volt=-1;
|
||
g_tmpr=-100;
|
||
}
|
||
}
|