You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
793 lines
35 KiB
793 lines
35 KiB
//08:3A:F2:A7:80:6C //esp32 желтые ноги
|
|
//08:3A:F2:66:31:30 //esp32 lilygo2,3
|
|
//08:3A:F2: //esp32 lilygo4,7
|
|
//EC:94:CB:6C:EC:A4 esp32 самоделка
|
|
//SD Карта подкл к любым ногам SPI железный H_SPIClass sdSPI(HSPI); или V_ SPIClass sdSPI(VSPI);
|
|
#define SD_MISO 23
|
|
#define SD_MOSI 13
|
|
#define SD_SCLK 14
|
|
//#define SD_CS 15
|
|
#define SD_CS 2
|
|
|
|
#include <esp_task_wdt.h>
|
|
#define WDT_TIMEOUT 30
|
|
#include <WiFi.h>
|
|
#include <AsyncTCP.h>
|
|
#include "ESPAsyncWebSrv.h"
|
|
#include <esp_now.h>
|
|
#include "SPI.h"
|
|
#include <SPIFFS.h>
|
|
#include <esp_task_wdt.h>
|
|
#include "NTPClient.h"
|
|
#include "WiFiUdp.h"
|
|
#include <Arduino_JSON.h>
|
|
|
|
#include "FS.h"
|
|
#include "SD.h"
|
|
#include <UnixTime.h>
|
|
UnixTime stamp(0); // указать GMT (3 для Москвы)
|
|
// Define deep sleep options
|
|
String dataMessage;
|
|
// Define NTP Client to get time
|
|
WiFiUDP ntpUDP;
|
|
NTPClient timeClient(ntpUDP);
|
|
#include "RTClib.h"
|
|
RTC_DS3231 rtc;
|
|
#include "nRF24L01.h"
|
|
#include "RF24.h"
|
|
#include <RCSwitch.h>
|
|
|
|
RCSwitch mySwitch = RCSwitch();
|
|
|
|
char msg[16];
|
|
//RF24 radio(12, 14, 26, 25, 27);
|
|
//RF24 radio(27, 26, 32, 33, 25);//server (ce,csn,sck,miso,mosi)esp32
|
|
//gpio19
|
|
RF24 radio(17, 16, 32, 33, 25);//server (ce,csn,sck,miso,mosi)esp32
|
|
|
|
const uint64_t pip = 0x02E423E4E2LL;
|
|
SPIClass sdSPI(HSPI);
|
|
File myFile;
|
|
|
|
const char* ssid = "VOVA-47";
|
|
const char* password = "vovak26102003";
|
|
|
|
const int LED_PIN = 2;
|
|
|
|
AsyncWebServer server(80);
|
|
AsyncWebSocket webSocket("/ws");
|
|
|
|
int ledState = LOW;
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// Задайте свой статический IP-адрес
|
|
IPAddress local_IP(192, 168, 1, 115);
|
|
// Укажите IP-адрес шлюза
|
|
IPAddress gateway(192, 168, 1, 1);
|
|
|
|
IPAddress subnet(255, 255, 0, 0);
|
|
IPAddress primaryDNS(8, 8, 8, 8); // опционально
|
|
IPAddress secondaryDNS(8, 8, 4, 4); // опционально
|
|
|
|
|
|
//****************************************************************************
|
|
// ntp
|
|
int countTimeWas;
|
|
int countVal;
|
|
int countVal1;
|
|
String formattedDate;
|
|
String formattedTime;
|
|
String dayStamp;
|
|
String timeStamp;
|
|
String timerweek="{\"id\":\"week\",\"timer1_week\":\"0111100\",\"timer2_week\":\"1000011\",\"timer3_week\":\"0101010\"}";
|
|
bool tweek; // флаг обновления строки timerweek для записи на SD
|
|
String timerdata="{\"timer1\":[\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\"],\"timer2\":[\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\"],\"timer3\":[\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\",\"00:00\"]}";//данные с таймеров
|
|
bool tdat=0;// флаг обновления строки timerdat для записи на SD
|
|
String timerout="{\"id\":\"tout\",\"t1\":\"011\",\"t2\":\"100\",\"t3\":\"010\"}";//подключние таймеров т1 т2 и т3 к выходам gpio4,gpio26,gpio27
|
|
bool tout=0;// флаг обновления строки timerout для записи на SD
|
|
bool ntp_on=0;
|
|
//**************************JSON***************************************************
|
|
JSONVar board;
|
|
JSONVar board1;
|
|
JSONVar board2;
|
|
JSONVar board3;
|
|
JSONVar board4;
|
|
JSONVar board5;
|
|
|
|
//String jsonString="{\"id\":\"0\",\"temperature\":\"9.67\",\"humidity\":50.41815185546875,\"tim2\":\"10:10\",\"tim3\":\"11:11\",\"dataserv\":\"12\",\"timeserv\":\"15:30\",\"munthserv\":\"январь\",\"weekserv\":\"среда\"}";
|
|
String jsonString="{\"id\":\"0\",\"temperature\":9.6757548,\"humidity\":50.41815185546875,\"tim2\":\"10:10\",\"tim3\":\"11:11\",\"dataserv\":\"12\",\"munthserv\":\"январь\",\"weekserv\":\"среда\"}";
|
|
String jsonString1;
|
|
String jsonString2="{\"id\":\"2\",\"tkom1\":\"20.0\",\"hkom1\":\"30.0\",\"batkom1\":\"4.10\",\"timekom1\":\"07:08\",\"tkom2\":\"20.5\",\"hkom2\":\"80.5\",\"batkom2\":\"3.95\",\"timekom2\":\"15:15\",\"tkor\":\"23.5\",\"hkor\":\"90.5\",\"batkor\":\"3.75\",\"timekor\":\"13:13\",\"tbal\":\"13.5\",\"hbal\":\"80.5\",\"batbal\":\"3.45\",\"timebal\":\"11:11\",\"tul1\":\"7.3\",\"hul1\":\"75.5\",\"osv1\":\"50\",\"timeul1\":\"12:12\"}";
|
|
String jsonStringout= "{\"id\":\"out\",\"out1\":\"1011\"}";// 0-выкл 1-вкл вых1 вых2 вых3 таймер(работаем по кнопкам или по таймеру
|
|
String jsonString77="{\"Time\":\"0:17\",\"temperatura\":\"19.73 C\",\"humidity\":\"73.59 %\"}\n{\"Time\":\"0:37\",\"temperatura\":\"19.65 C\",\"humidity\":\"74.34 %\"}\n{\"Time\":\"0:57\",\"temperatura\":\"19.57 C\",\"humidity\":\"74.99 %\"}";
|
|
String jsonStringakva="{\"id\":\"akva\",\"tempakv1\":\"20,1\",\"light1\":\"80 %\",\"timakv1\":\"12.31\",\"fan1\":\"OFF\",\"tempakv2\":\"20,2\",\"light2\":\"82 %\",\"timakv2\":\"12.32\",\"fan2\":\"OFF\",\"tempakv3\":\"20,3\",\"light3\":\"83 %\",\"timakv3\":\"12.33\",\"fan3\":\"OFF\"}";
|
|
//String jsonString77="{\"id\":\"77\",\"Time\":\"21:23\",\"temperatura\":\"8.88 C\",\"humidity\":\"90.97 %\"}\n";
|
|
//String jsonString78="{\"id\":\"77\",\"data\":\'\"Time\":\"21:23\",\"temperatura\":\"8.88 C\",\"humidity\":\"90.97 %\"\'}";
|
|
//{"timer1":["00:00","00:00","00:00","00:00","00:00","00:00","00:00","00:00","00:00","00:00"],"timer2":["00:00","00:00","00:00","00:00","00:00","00:00","00:00","00:00","00:00","00:00"],"timer3":["00:00","00:00","00:00","00:00","00:00","00:00","00:00","00:00","00:00","00:00"]}
|
|
//String jsonString7="{\"id\":\"week\",\"timer1_week\":\"0111100\",\"timer2_week\":\"1000011\",\"timer3_week\":\"0101010\"}";
|
|
//****************************************************************************
|
|
int idcon=0;// ID соединения
|
|
//*************************************************************************************************
|
|
char* strd[] = {"01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"};
|
|
char* strm[] = {"январь","февраль","март","апрель","май","июнь","июль","август","сентябрь","октябрь","ноябрь","декабрь"};
|
|
char* strweek[] = {"воскресенье","понедельник","вторник","среда","четверг","пятница","суббота","воскресенье"};
|
|
int nt=0;//номер термометра
|
|
int nti=0;//номер термометра для сайта
|
|
int temperature1=10;
|
|
String ts;
|
|
String hs;
|
|
String t1;
|
|
String h1;
|
|
String t10;//время работы сервера
|
|
String tim3;// время от нтп сервера при приходе данных с NOW
|
|
String tim2;//время получ от устройства NOW
|
|
String batz;//заря бат термометра ул запад
|
|
String munthserv;//месяц
|
|
String weekserv;//день недели
|
|
String timer1;//таймер1
|
|
String timer2;//таймер2
|
|
int timerbut1=0;
|
|
int timerbut2=0;
|
|
bool tbut1=0;//флаг таймера1
|
|
bool tbut2=0;//флаг таймера2
|
|
bool res = 0;//флаг разрешения сброса
|
|
int timebut=0;// подсчет времени по таймерам
|
|
|
|
String tkom1;//температура
|
|
String hkom1;//влажность
|
|
String batkom1;
|
|
String timekom1;//время прихода данных комната1
|
|
|
|
String tkom2;
|
|
String hkom2;
|
|
String batkom2;
|
|
String timekom2;
|
|
|
|
String tkor;
|
|
String hkor;
|
|
String batkor;
|
|
String timekor;
|
|
|
|
String tbal;
|
|
String hbal;
|
|
String batbal;
|
|
String timebal;
|
|
|
|
String timeul1;
|
|
String tul1;
|
|
String hul1;
|
|
String osv1;
|
|
|
|
String takva1;
|
|
String takva2;
|
|
String takva3;
|
|
String timeakva;
|
|
String light;
|
|
String fan1;
|
|
String fan2;
|
|
String fan3;
|
|
bool fanak1;
|
|
bool fanak2;
|
|
bool fanak3;
|
|
int lightakv=80;
|
|
bool akva=0;//флаг прихода дааных с акваконрол
|
|
|
|
int ct1=0;//счетчик пропуска данные каждые 3 минуты записываем каждые 20 те 7 пропусков
|
|
int wreset=0;//счетчик времени сброса esp(1 раз в 8 часов)
|
|
String out1;//выход1 gpio4
|
|
String out2;//выход2 gpio26
|
|
String out3;//выход3 gpio27
|
|
int tweekday=1;//день недели для таймеров
|
|
int time17=0;
|
|
int hour1=10;
|
|
int min1=7;
|
|
int sek=0;
|
|
int year1;
|
|
int month1;
|
|
int data1;
|
|
int hk=0;//часы для исключения повтора записи данных
|
|
int mk=0;//минуты
|
|
int hb=0;//часы для исключения повтора записи данных
|
|
int mb=0;//минуты
|
|
int hkr=0;//часы для исключения повтора записи данных
|
|
int mkr=0;//минуты
|
|
int timev=0;//для пропуска 20 минут
|
|
//String timev1;//для записи на флэш при сбросе
|
|
bool outdata=0;//флаг обновления состояния выходов
|
|
boolean fdata=0;//флаг обновления данных темп и влажн
|
|
int fobnov=1;//флаг обновления данных темп и влажн
|
|
String timeserv;//время сервера
|
|
String dataserv;//дата
|
|
int v=0;
|
|
int v1=0;
|
|
long EpochTime=0;
|
|
int ind=0;
|
|
|
|
String strdat;//накопленые в памяти данные по темп и влажность передаваемые клиенту
|
|
String tempdat;//
|
|
int ftdata=0;//флаг запроса данных темп и влажн
|
|
int fping=0;// флаг для задержки отр данных на страницу inform
|
|
int wright=0;
|
|
bool flread=0;
|
|
char* strden[] = {"/01","/02","/03","/04","/05","/06","/07","/08","/09","/10","/11","/12","/13","/14","/15","/16","/17","/18","/19","/20","/21","/22","/23","/24","/25","/26","/27","/28","/29","/30","/31"};
|
|
char* strmen[] = {"/JAN","/FEBR","/MARCH","/APRIL","/MAY","/JUNE","/JULY","/AUG","/SEPT","/OCT","/NOV","/DEC"};
|
|
char* stryen[] = {"/2014","/2015","/2016","/2017","/D-2018","/D-2019","/D-2020","/D-2021","/D-2022","/D-2023","/D-2024","/D-2025","/D-2026","/D-2027","/D-2028","/D-2029","/D-2030","/D-2031","/D-2032","D-2033","/D-2034","/D-2035"};
|
|
char* strdaten[] = {"/T1.txt","/T2.txt","/T3.txt","/T4.txt","/T5.txt","/T6.txt","/T7.txt","/T8.txt","/T9.txt","/T10.txt"};
|
|
//************************************************************
|
|
//************************************************************
|
|
hw_timer_t * timer = NULL;
|
|
volatile SemaphoreHandle_t timerSemaphore;
|
|
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
|
|
volatile uint32_t isrCounter = 0;
|
|
volatile uint32_t lastIsrAt = 0;
|
|
char *time_buf;
|
|
//*****************************************************************************
|
|
|
|
// Structure example to receive data
|
|
// Must match the sender structure
|
|
typedef struct struct_message {
|
|
int id;
|
|
float temp;
|
|
float hum;
|
|
unsigned int readingId;
|
|
unsigned int bat;
|
|
} struct_message;
|
|
int volt11;
|
|
struct_message incomingReadings;
|
|
//****************************************Timer Budilnik*****************************************************************************************************************************************************************************************
|
|
int minuta;//счетчик минут для проверки времени сработки будильников
|
|
uint16_t BTimer1 [11] = {2, 390, 450, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440}; // массивы всех таймеров для суточных каналов (1 - 4) 0-й элемент отвечает за состояние канала (1 - вкл/ 0 - выкл/ 2 - авто))
|
|
uint16_t BTimer2 [11] = {2, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440}; // остальное время в минутах (нечетные элементы - таймеры включения, четные - выключения)
|
|
uint16_t BTimer3 [11] = {2, 380, 450, 1080, 1410, 1440, 1440, 1440, 1440, 1440, 1440}; // время 1440 отображается на экране как "--:--", это неактивное значение, для основной логики пустая ячейка означает что таймер не задан
|
|
uint16_t weekTimer1 [7]={0,0,0,0,0,0,0};//недельные установки t1
|
|
uint16_t weekTimer2 [7]={0,0,0,0,0,0,0};//недельные установки t2
|
|
uint16_t weekTimer3 [7]={0,0,0,0,0,0,0};//недельные установки t3
|
|
uint16_t gpioTimer1 [3]={1,0,0};//выходы подкл к таймеру {gpio 4, gpio 26, gpio 27} {1,0,0} подкл 4
|
|
uint16_t gpioTimer2 [3]={1,0,0};//выходы подкл к таймеру {gpio 4, gpio 26, gpio 27} {0,0,0} откл все
|
|
uint16_t gpioTimer3 [3]={0,0,0};//выходы подкл к таймеру {gpio 4, gpio 26, gpio 27}{1,1,1} подкл все
|
|
uint16_t gpio[4]={0,0,0,1};//выходы состояние {gpio 4, gpio 26, gpio 27, timer}{1,1,1,1} timer определяет работу выходов по таймеру=1 или кнопки =0
|
|
bool state1 = 0; //_________________Переменные состояния каналов(вкл/выкл)
|
|
bool state2 = 0;
|
|
bool state3 = 0;
|
|
uint16_t current_time = 0 ; //_______Текущее время в минутах (для основных расчетов)
|
|
//*********************************************************************************************
|
|
const char* PARAM_INPUT_1 = "output";//Gpio
|
|
const char* PARAM_INPUT_2 = "state"; //состояние выхода
|
|
const char* PARAM_INPUT = "value";
|
|
|
|
const int output = 4;
|
|
const int output1 = 26;
|
|
const int output2 = 27;
|
|
String ledout;
|
|
void IRAM_ATTR onTimer();
|
|
//***********************************************************
|
|
void OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len) {
|
|
// Copies the sender mac address to a string
|
|
char macStr[18];
|
|
Serial.print("Packet received from: ");
|
|
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
|
Serial.println(macStr);
|
|
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
|
|
|
|
Serial.printf("Board ID %u: %u bytes\n", incomingReadings.id, len);
|
|
Serial.printf("t value: %4.2f \n", incomingReadings.temp);
|
|
t1 = incomingReadings.temp;
|
|
Serial.printf("h value: %4.2f \n", incomingReadings.hum);
|
|
h1=incomingReadings.hum;
|
|
Serial.printf("readingID value: %d \n", incomingReadings.readingId);
|
|
int tim11 =incomingReadings.readingId;
|
|
hour1=tim11/100;
|
|
min1=tim11%100;
|
|
volt11 =incomingReadings.bat;//заряд батареи
|
|
Serial.printf("bat value: %d \n", incomingReadings.bat);
|
|
|
|
|
|
batz=volt11/100;
|
|
batz+=",";
|
|
batz+=volt11%100;
|
|
|
|
Serial.println(batz);
|
|
//tim3=timeserv;
|
|
//получаем из int incomingReadings= 1530 строку 15:30
|
|
|
|
tim3=incomingReadings.readingId/100;
|
|
tim3+=":";
|
|
if(incomingReadings.readingId%100<10)tim3+="0";
|
|
|
|
tim3+=incomingReadings.readingId%100;
|
|
//JSONстрока формирование
|
|
ntphome();
|
|
flread=1;
|
|
JSstringU();
|
|
savedata();
|
|
flread=1;
|
|
}//OnDataRecv
|
|
|
|
//****************************************************************************
|
|
//****************************************************************************************************************************************************************************************************************************************************
|
|
//подпрогр Действия вебсекета
|
|
void handleWebSocketEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
|
|
switch (type) {
|
|
case WS_EVT_DISCONNECT://[3] Disconnected! откл соединения
|
|
Serial.printf("[%u] Disconnected!\n", client->id());
|
|
idcon--;
|
|
break;
|
|
|
|
case WS_EVT_CONNECT://[4] Connected from 192.168.1.108 подключение
|
|
{
|
|
IPAddress ip = client->remoteIP();//адрес подкл объкта
|
|
Serial.printf("[%u] Connected from %d.%d.%d.%d\n", client->id(), ip[0], ip[1], ip[2], ip[3]);
|
|
idcon++;
|
|
client->text(jsonString);//отправка дата месяц неделя
|
|
client->text(jsonString2);//отправка темп и влажности в комнатах
|
|
String countUpdate2 = "{\"label3\":\"count2\",\"value\":\"" + String(timeserv) + "\"}";//отправка строковой переменной
|
|
String countUpdate = "{\"label3\":\"count\",\"value\":\"" + String(t10) + "\"}";//отправка строковой переменной время раб сервера
|
|
client->text(countUpdate2);//отправка NTP времени timeserv
|
|
client->text(countUpdate);//отправка время раб сервера t10
|
|
if (ftdata==1)//пришел запрос табл данных /inform1 запад
|
|
{ftdata=0;
|
|
nti=1;
|
|
readdata();
|
|
client->text(strdat.c_str());//отправка суточных данных данных из карты памяти в таблицу на стр inform
|
|
}
|
|
if (ftdata==2)//пришел запрос табл данных /inform К1
|
|
{ftdata=0;
|
|
nti=4;
|
|
readdata();
|
|
client->text(strdat.c_str());//отправка суточных данных данных из карты памяти в таблицу на стр inform
|
|
}
|
|
if (ftdata==3)//пришел запрос табл данных /inform k2
|
|
{ftdata=0;
|
|
nti=3;
|
|
readdata();
|
|
client->text(strdat.c_str());//отправка суточных данных данных из карты памяти в таблицу на стр inform
|
|
}
|
|
if (ftdata==5)//пришел запрос табл данных /inform балкон
|
|
{ftdata=0;
|
|
nti=2;
|
|
readdata();
|
|
client->text(strdat.c_str());//отправка суточных данных данных из карты памяти в таблицу на стр inform
|
|
}
|
|
if (ftdata==4)//пришел запрос табл данных /inform корридор
|
|
{ftdata=0;
|
|
nti=5;
|
|
readdata();
|
|
client->text(strdat.c_str());//отправка суточных данных данных из карты памяти в таблицу на стр inform
|
|
}
|
|
if (ftdata==10)//пришел запрос табл данных /inform восток
|
|
{ftdata=0;
|
|
nti=0;
|
|
readdata();
|
|
client->text(strdat.c_str());//отправка суточных данных данных из карты памяти в таблицу на стр inform
|
|
}
|
|
if (ftdata==6)//пришел запрос табл данных кухня
|
|
{ftdata=0;
|
|
// nti=6;
|
|
// readdata();
|
|
// client->text(strdat.c_str());//отправка суточных данных данных из карты памяти в таблицу на стр
|
|
}
|
|
if (ftdata==12)//пришел запрос /setting передача значений таймера
|
|
{ftdata=0;
|
|
client->text(timerweek);//таймер дни недели
|
|
Serial.println(timerweek);
|
|
|
|
client->text(timerdata);//timerout
|
|
Serial.println(timerdata);
|
|
|
|
client->text(timerout);//timerout
|
|
Serial.println(timerout);
|
|
}
|
|
|
|
if (ftdata==8)//пришел запрос управления upravlenie.html
|
|
{ftdata=0;
|
|
JSstringOut();
|
|
client->text(jsonStringout);// {"id":"out","out1":"1011"} отправляем состояние выходов
|
|
//Serial.println(jsonStringout);
|
|
}
|
|
if (ftdata==7)//пришел запрос управления akva.html
|
|
{ftdata=0;
|
|
JSstringAkva();
|
|
client->text(jsonStringakva);//jsonStringakva="{\"id\":\"akva\",\"tempakv1\":\"20,1\",\"light1\":\"80 %\",\"timakv1\":\"12.31\",\"fan1\":\"OFF\",\"tempakv2\":\"20,2\",\"light2\":\"82 %\",\"timakv2\":\"12.32\",\"fan2\":\"OFF\",\"tempakv3\":\"20,3\",\"light3\":\"83 %\",\"timakv3\":\"12.33\",\"fan3\":\"OFF\"}";
|
|
Serial.println(jsonStringakva);
|
|
}
|
|
|
|
if (ftdata==15)//пришел запрос управления akva1.html
|
|
{ftdata=0;
|
|
JSstringAkva();
|
|
client->text(jsonStringakva);//jsonStringakva="{\"id\":\"akva\",\"tempakv1\":\"20,1\",\"light1\":\"80 %\",\"timakv1\":\"12.31\",\"fan1\":\"OFF\",\"tempakv2\":\"20,2\",\"light2\":\"82 %\",\"timakv2\":\"12.32\",\"fan2\":\"OFF\",\"tempakv3\":\"20,3\",\"light3\":\"83 %\",\"timakv3\":\"12.33\",\"fan3\":\"OFF\"}";
|
|
// Serial.println(jsonStringakva);
|
|
readakva();
|
|
client->text(strdat.c_str());//отправка суточных данных данных из карты памяти в таблицу
|
|
}
|
|
if (ftdata==16)//пришел запрос управления akva1.html
|
|
{ftdata=0;
|
|
JSstringAkva();
|
|
client->text(jsonStringakva);//jsonStringakva="{\"id\":\"akva\",\"tempakv1\":\"20,1\",\"light1\":\"80 %\",\"timakv1\":\"12.31\",\"fan1\":\"OFF\",\"tempakv2\":\"20,2\",\"light2\":\"82 %\",\"timakv2\":\"12.32\",\"fan2\":\"OFF\",\"tempakv3\":\"20,3\",\"light3\":\"83 %\",\"timakv3\":\"12.33\",\"fan3\":\"OFF\"}";
|
|
// Serial.println(jsonStringakva);
|
|
readakva();
|
|
client->text(strdat.c_str());//отправка суточных данных данных из карты памяти в таблицу
|
|
}
|
|
if (ftdata==17)//пришел запрос управления akva1.html
|
|
{ftdata=0;
|
|
JSstringAkva();
|
|
client->text(jsonStringakva);//jsonStringakva="{\"id\":\"akva\",\"tempakv1\":\"20,1\",\"light1\":\"80 %\",\"timakv1\":\"12.31\",\"fan1\":\"OFF\",\"tempakv2\":\"20,2\",\"light2\":\"82 %\",\"timakv2\":\"12.32\",\"fan2\":\"OFF\",\"tempakv3\":\"20,3\",\"light3\":\"83 %\",\"timakv3\":\"12.33\",\"fan3\":\"OFF\"}";
|
|
//Serial.println(jsonStringakva);
|
|
readakva();
|
|
client->text(strdat.c_str());//отправка суточных данных данных из карты памяти в таблицу
|
|
}
|
|
if (ftdata==18)//пришел запрос управления akva1.html
|
|
{ftdata=0;
|
|
// JSstringAkva();
|
|
// client->text(jsonStringakva);//jsonStringakva="{\"id\":\"akva\",\"tempakv1\":\"20,1\",\"light1\":\"80 %\",\"timakv1\":\"12.31\",\"fan1\":\"OFF\",\"tempakv2\":\"20,2\",\"light2\":\"82 %\",\"timakv2\":\"12.32\",\"fan2\":\"OFF\",\"tempakv3\":\"20,3\",\"light3\":\"83 %\",\"timakv3\":\"12.33\",\"fan3\":\"OFF\"}";
|
|
//Serial.println(jsonStringakva);
|
|
readakva();
|
|
client->text(strdat.c_str());//отправка суточных данных данных из карты памяти в таблицу
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case WS_EVT_DATA:
|
|
{
|
|
AwsFrameInfo *info = (AwsFrameInfo*)arg;
|
|
if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
|
|
data[len] = '\0';
|
|
String payload = String((char*)data);
|
|
|
|
Serial.printf("[%u] Received: %s\n", client->id(), payload.c_str());
|
|
|
|
if (payload == "toggle") {//если пришло toggle
|
|
|
|
}else{ //{"id":"week","timer1_week":"0111100","timer2_week":"1000011","timer3_week":"0101010"}
|
|
String js = payload.substring(1,11);//"id":"week" вырезаем нужные данные {"ido":"4","out":1}
|
|
// Serial.println(js);
|
|
if((js[1] = 'i')&&(js[6]=='w'))
|
|
{timerweek=payload;
|
|
tweek=1;
|
|
}
|
|
if((js[1] = 'i')&&(js[6]=='t'))// "id":"tout","t1":"100","t2":"010","t3":"001"
|
|
{timerout=payload;
|
|
Serial.println(timerout);
|
|
tweek=1;
|
|
}
|
|
if((js[1] = 't')&&(js[6]=='1'))//{"timer1":["08:00","09:00","10:00","11:00","12:00","13:00","14:00","15:00","16:00","17:00"],"timer2":["09:30","10:30","11:30","12:30","13:30","14:30","15:30","16:30","17:30","18:30"],"timer3":["10:15","11:15","12:15","13:15","14:15","15:15","16:15","17:15","18:15","19:15"]}
|
|
{timerdata=payload;
|
|
//Serial.println(timerdata);
|
|
tdat=1;//флаг разрешения парсинга строки и ее записи на SD
|
|
}
|
|
// Serial.println(js);
|
|
if((js[1] = 'i')&&(js[3]=='o'))//{"ido":"4","out":"1"} переключение выхода
|
|
{ledout=payload;
|
|
//Serial.println(ledout);
|
|
outconvert();// получен данные преобразуем в массив gpio[4]={0,0,0,1}
|
|
JSstringOut();//преобразуем состояние выходов gpio[4]={0,0,0,1} в JSON {"id":"out","out1":"1011"}
|
|
webSocket.textAll(jsonStringout);// выводим всем клиентам w/s
|
|
btime();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void setup() {
|
|
pinMode(2, OUTPUT);
|
|
pinMode(4, OUTPUT);
|
|
digitalWrite(4, LOW);
|
|
pinMode(26, OUTPUT);
|
|
digitalWrite(26, LOW);
|
|
pinMode(27, OUTPUT);
|
|
digitalWrite(27, LOW);
|
|
pinMode(5, OUTPUT);
|
|
digitalWrite(5, LOW);
|
|
pinMode(19, OUTPUT);
|
|
digitalWrite(19, HIGH);
|
|
delay(500);
|
|
digitalWrite(19, LOW);
|
|
|
|
Serial.begin(115200);
|
|
//pinMode(LED_PIN, OUTPUT);
|
|
rtc.begin();
|
|
|
|
// digitalWrite(2, LOW);
|
|
digitalWrite(2, HIGH);
|
|
Serial.println(WiFi.macAddress());
|
|
|
|
sdSPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
|
|
if (!SD.begin(SD_CS, sdSPI))
|
|
{
|
|
// if(!SD.begin()){
|
|
Serial.println("Mounting card mount failed");
|
|
// return;
|
|
}
|
|
|
|
|
|
|
|
uint8_t cardType = SD.cardType();
|
|
if(cardType == CARD_NONE){
|
|
Serial.println("No SD card attached");
|
|
//return;
|
|
}
|
|
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
|
|
Serial.printf("SD Card Size: %lluMB\n", cardSize);
|
|
|
|
|
|
if(!SPIFFS.begin()){
|
|
Serial.println("An Error has occurred while mounting SPIFFS");
|
|
//return;
|
|
}
|
|
|
|
|
|
Nrfsetup();
|
|
//settimer();//таймер отсчета времени настр на 5 сек
|
|
WiFisetup();
|
|
timeClient.begin();
|
|
|
|
timeClient.setTimeOffset(10800);
|
|
|
|
|
|
// ntp();//NTP init
|
|
/*current_time = hour1 * 60 + min1;
|
|
for (int i = 0; i <= 1439; i++) {
|
|
if (current_time > 1439) current_time = 0;
|
|
state1 = main_log(BTimer1, state1);
|
|
state2 = main_log(BTimer2, state2);
|
|
state3 = main_log(BTimer3, state3);
|
|
// state4 = main_log(Timer4, state4);
|
|
current_time++;
|
|
}
|
|
btime();
|
|
*/
|
|
timedate();
|
|
Sdreaddata();
|
|
Sdread();
|
|
mySwitch.enableTransmit(22);
|
|
//mySwitch.send("000000000001010100010011");
|
|
//mySwitch.send("000000000001010100010001");
|
|
esp_now_register_recv_cb(OnDataRecv);
|
|
|
|
|
|
//*******************server******************************************************************
|
|
// server.on("/", HTTP_GET, handleRoot);
|
|
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
request->send(SPIFFS, "/index.html");
|
|
});
|
|
server.on("/index.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
request->send(SPIFFS, "/index.html");
|
|
});
|
|
// Route to load style.css file
|
|
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
request->send(SPIFFS, "/style.css", "text/css");
|
|
});
|
|
server.on("/fon.jpg", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
request->send(SPIFFS, "/fon.jpg");
|
|
});
|
|
//*****************************************************************************************************
|
|
server.on("/upravlenie.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
fobnov=1;
|
|
ftdata=8;
|
|
request->send(SPIFFS, "/upravlenie.html", String(), false, processor);
|
|
});
|
|
|
|
//****************************************************************************************************************
|
|
server.on("/setting.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=12;
|
|
request->send(SPIFFS, "/setting.html");
|
|
});
|
|
server.on("/inform.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=10;
|
|
request->send(SPIFFS, "/inform.html");
|
|
});
|
|
server.on("/informtabl.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=10;
|
|
request->send(SPIFFS, "/informtabl.html");
|
|
});
|
|
|
|
server.on("/inform1.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=1;
|
|
request->send(SPIFFS, "/inform1.html");
|
|
});
|
|
server.on("/informtabl1.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=1;
|
|
request->send(SPIFFS, "/informtabl1.html");
|
|
});
|
|
|
|
server.on("/inform2.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=2;
|
|
request->send(SPIFFS, "/inform2.html");
|
|
});
|
|
server.on("/informtabl2.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=2;
|
|
request->send(SPIFFS, "/informtabl2.html");
|
|
});
|
|
server.on("/inform3.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=3;
|
|
request->send(SPIFFS, "/inform3.html");
|
|
});
|
|
server.on("/informtabl3.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=3;
|
|
request->send(SPIFFS, "/informtabl3.html");
|
|
});
|
|
server.on("/inform4.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=4;
|
|
request->send(SPIFFS, "/inform4.html");
|
|
});
|
|
server.on("/informtabl4.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=4;
|
|
request->send(SPIFFS, "/informtabl4.html");
|
|
});
|
|
server.on("/inform5.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=5;
|
|
request->send(SPIFFS, "/inform5.html");
|
|
});
|
|
server.on("/informtabl5.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=5;
|
|
request->send(SPIFFS, "/informtabl5.html");
|
|
});
|
|
server.on("/inform6.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=6;
|
|
request->send(SPIFFS, "/inform6.html");
|
|
});
|
|
server.on("/informtabl6.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=6;
|
|
request->send(SPIFFS, "/informtabl6.html");
|
|
});
|
|
|
|
server.on("/akva1.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=15;
|
|
request->send(SPIFFS, "/akva1.html");
|
|
});
|
|
|
|
server.on("/akva2.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=16;
|
|
request->send(SPIFFS, "/akva2.html");
|
|
});
|
|
server.on("/akva3.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=17;
|
|
request->send(SPIFFS, "/akva3.html");
|
|
});
|
|
server.on("/akvadat.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=18;
|
|
request->send(SPIFFS, "/akvadat.html");
|
|
});
|
|
server.on("/akvagraf.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=18;
|
|
request->send(SPIFFS, "/akvagraf.html");
|
|
});
|
|
server.on("/timer.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
request->send(SPIFFS, "/timer.html", String(), false, processor);
|
|
});
|
|
server.on("/akva.html", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
ftdata=7;
|
|
request->send(SPIFFS, "/akva.html");
|
|
});
|
|
|
|
server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
request->send(SPIFFS, "/favicon.ico");
|
|
});
|
|
server.on("/favicon-32x32.png", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
request->send(SPIFFS, "/favicon-32x32.png");
|
|
});
|
|
server.on("/favicon-16x16.png", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
request->send(SPIFFS, "/favicon-16x16.png");
|
|
});
|
|
//********************************************************************************************************
|
|
JSstringU();
|
|
JSstringK();
|
|
server.addHandler(&webSocket);
|
|
webSocket.onEvent(handleWebSocketEvent);
|
|
|
|
server.begin();
|
|
esp_task_wdt_init(WDT_TIMEOUT, true); //включить панику, чтобы ESP32 перезапустился
|
|
esp_task_wdt_add(NULL); //добавить текущий поток в WDT watch
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
// Send data to browser, increasing number every second.
|
|
if (millis() - countTimeWas >= 1000) {
|
|
countTimeWas = millis();
|
|
countVal++;//cчетчик до перезапуска сервера
|
|
countVal1++;
|
|
v++;
|
|
v1++;
|
|
if (idcon>0)// если есть подключения
|
|
{ String countUpdate1 = "{\"label3\":\"count1\",\"value\":" + String(countVal1) + "}";//отправка числовой переменной
|
|
webSocket.textAll(countUpdate1);//обновление ws
|
|
if((tdat==1)||(tweek==1))//есть новые данные для установок таймера
|
|
{timerconvert();
|
|
gpio[3]=1;//управление выходами передаем таймеру
|
|
writeFile(SD, "/timerd.txt", timerdata.c_str());//записываем в этот файл значения для таймера
|
|
writeFile(SD, "/week.txt", timerweek.c_str());//записываем в этот файл значения недельного таймера
|
|
writeFile(SD, "/tdout.txt", timerout.c_str());//записываем в этот файл значения выходов к кот подкл таймер
|
|
//timerout= {"id":"tout","t1":"100","t2":"010","t3":"001"}
|
|
}
|
|
}
|
|
|
|
|
|
// Serial.println(countUpdate1);
|
|
|
|
|
|
|
|
if (v1>3600) {//60min-
|
|
delay(0);
|
|
sdsave();// записываем на СД необходимые данные
|
|
delay(0);
|
|
ntp();//считываем время
|
|
v1=0;//обнуляем счетчик =3600с
|
|
delay(0);
|
|
}
|
|
//**************20sek*******************************
|
|
if (v>19){//20sek
|
|
JSstringU();
|
|
JSstringK();
|
|
JSstringOut();
|
|
|
|
|
|
if((ntp_on==0)&&(idcon==0))
|
|
{if((hour1==8)&&(min1==15))ntp();//синхронизация времени с NTP
|
|
|
|
if((hour1==8)&&(min1>18)) ntp_on==1; //если NTP не отвечает прекращаем до следующего дня
|
|
}
|
|
|
|
|
|
|
|
|
|
if((res==1)&&(idcon==0))//idcon=0 клиентов нет
|
|
{
|
|
sdsave();// записываем на СД необходимые данные
|
|
ESP.restart(); //перезагрузка сервака
|
|
}
|
|
|
|
res=0;
|
|
ntphome();//считываем время с esp32
|
|
nrf(); //проверяем не приш ли данные на NRF
|
|
Serial.print ("idcon=");
|
|
Serial.println (idcon);
|
|
v=0;//обнуляем счетчик 4*5=20с
|
|
delay(0);
|
|
vrem();//время работы сайта
|
|
btime();//проверка сработки таймеров
|
|
|
|
|
|
if (idcon>0)// если есть подключения
|
|
{ webSocket.textAll(jsonString);//{"id":"0","temperature":12.456787109375,"humidity":77.456787109375,"tim2":"18:15","ti
|
|
Serial.println(jsonString);
|
|
webSocket.textAll(jsonString2);//{"id":"2","tkom1":"20.0","hkom1":"30.0","batkom1":"4.10","timekom1"
|
|
Serial.println(jsonString2);
|
|
|
|
String countUpdate = "{\"label3\":\"count\",\"value\":\"" + String(t10) + "\"}";//отправка строковой переменной время раб сервера
|
|
webSocket.textAll(countUpdate);
|
|
Serial.println(countUpdate);
|
|
delay(0);
|
|
String countUpdate2 = "{\"label3\":\"count2\",\"value\":\"" + String(timeserv) + "\"}";//отправка строковой переменной врем NTP
|
|
webSocket.textAll(countUpdate2);
|
|
Serial.println(countUpdate2);
|
|
}
|
|
}
|
|
//**************20sek end*******************************
|
|
|
|
if((countVal>3600*2)&&(idcon==0))//прошло более 2 часов и нет подкл клиентов
|
|
{ if(hour1!=3)res=1;//разрешение на перезагрузку сервака
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
esp_task_wdt_reset();//reset WDT сброс вотчдога
|
|
}
|
|
|