#include <sqlite3.h>
#include <vfs.h>
#include <FS.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266FtpServer.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#define GMT 3 // смещение (москва 3)
#define NTP_ADDRESS "europe.pool.ntp.org" // сервер времени
#define NTP_INTERVAL 60 * 1000 // обновление (1 минута)
const byte relay = 4;
const char *ssid = "MYWIFI"; // Для хранения SSID
const char *password = "MYPASSWORD"; // Для хранения пароля сети
const char *ssidAP = "MyESP";
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, NTP_ADDRESS, GMT * 3600, NTP_INTERVAL);
ESP8266WebServer HTTP(80); // Определяем объект и порт сервера для работы с HTTP
FtpServer ftpSrv;
sqlite3 *db;
byte days, hs, ms, ss, my, dm;
int yy;
void setup() {
Serial.begin(9600);
pinMode(relay,OUTPUT);
WiFi.mode(WIFI_STA);
byte tries = 50;
WiFi.begin(ssid, password);
while (--tries && WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(1000);
}
if (WiFi.status() != WL_CONNECTED)
{
Serial.println("");
Serial.println("WiFi up AP");
WiFi.softAP(ssidAP); // Создаём точку доступа
}
else {
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
system_update_cpu_freq(SYS_CPU_160MHZ);
SPIFFS.begin();
HTTP.begin();
ftpSrv.begin("relay","relay");
Serial.print("\nMy IP to connect via Web-Browser or FTP: ");
Serial.println(WiFi.softAPIP());
Serial.println("\n");
timeClient.begin();
// Обработка HTTP-запросов
HTTP.on("/relay_switch", [](){
HTTP.send(200, "text/plain", relay_switch());
});
HTTP.on("/relay_status", [](){
HTTP.send(200, "text/plain", relay_status());
});
HTTP.onNotFound([](){
if(!handleFileRead(HTTP.uri()))
HTTP.send(404, "text/plain", "Not Found");
});
// SPIFFS.remove("/db.db");
sqlite3_initialize();
}
void loop() {
timeClient.update();
hs = timeClient.getHours();
ms = timeClient.getMinutes();
ss = timeClient.getSeconds();
getDTString();
// Serial.println(String(hs) + ":" + String(ms) + ":" + String(ss) + " " + String(dm) + "/" + String(my) + "/" + String(yy));
if (Serial.available() > 0) {
String str = Serial.readString();
if (str != "")
{
char query[str.length() + 1];
strcpy(query, str.c_str());
str = "";
db_exec(db, query);
}
}
delay(10);
HTTP.handleClient();
ftpSrv.handleFTP();
}
void db_exec(sqlite3 *db, const char *sql) {
const char *dbf = "/weather.sql3";
char *ErrMsg = 0;
const char* data = 0;
Serial.println(sql);
File db_file_obj;
vfs_set_spiffs_file_obj(&db_file_obj);
if (sqlite3_open(dbf, &db)) {
Serial.print(F("Can't open database: "));
Serial.println(sqlite3_errmsg(db));
return;
}
else {Serial.println("DB opened");}
Serial.println(sql);
long start = millis();
int rc = sqlite3_exec(db, sql, callback, (void*)data, &ErrMsg);
if (rc != SQLITE_OK) {
Serial.print(F("SQL error: "));
Serial.println(ErrMsg);
sqlite3_free(ErrMsg);
} else {
Serial.print(F("Done. Time taken: "));
Serial.print(millis()-start);
Serial.println(F(" ms"));
Serial.println();
}
Serial.println(rc);
sqlite3_close(db);
}
static int callback(void *data, int argc, char **argv, char **azColName) {
for (int i = 0; i < argc; i++){
// Serial.printf("%s = %s\n", azColName[i], argv[i]);
if (i > 0)
Serial.print(" | ");
Serial.print(argv[i]);
}
Serial.println();
return 0;
}
String relay_switch() {
byte state;
if (digitalRead(relay))
state = 0;
else
state = 1;
digitalWrite(relay, state);
Serial.println(String(hs) + ":" + String(ms) + ":" + String(ss) + " " + String(dm) + "/" + String(my - 1) + "/" + String(yy));
// String str = "INSERT INTO pokazaniya (cday, cmonth, cyear, chour, tin, tout, vlag, davl) VALUES (" + String(dm) + ", " + String(my) + ", " + String(yy) + ", " + String(hs) + ", 29.4, -4.5, 15, 745)";
// String str = "INSERT INTO pokazaniya VALUES (" + String(dm) + ", " + String(my) + ", " + String(yy) + ", " + String(hs) + ", 29.4, -4.5, 15, 745)";
String str = "SELECT * FROM pokazaniya WHERE cday = 21";
char query[str.length() + 1];
db_exec(db, str.c_str());
return String(state);
}
String relay_status() {
byte state;
if (digitalRead(relay))
state = 1;
else
state = 0;
return String(state);
}
bool handleFileRead(String path){
if(path.endsWith("/")) path += "index.html";
String contentType = getContentType(path);
if(SPIFFS.exists(path)){
File file = SPIFFS.open(path, "r");
size_t sent = HTTP.streamFile(file, contentType);
file.close();
return true;
}
return false;
}
String getContentType(String filename){
if (filename.endsWith(".html")) return "text/html";
else if (filename.endsWith(".css")) return "text/css";
else if (filename.endsWith(".js")) return "application/javascript";
else if (filename.endsWith(".png")) return "image/png";
else if (filename.endsWith(".jpg")) return "image/jpeg";
else if (filename.endsWith(".gif")) return "image/gif";
else if (filename.endsWith(".ico")) return "image/x-icon";
return "text/plain";
}
void getDTString() {
unsigned long rawTime = (timeClient.getEpochTime()) / 86400L; // in days
unsigned long days = 0, yr = 1970;
uint8_t month;
while((days += (LEAP_YEAR(yr) ? 366 : 365)) <= rawTime)
yr++;
rawTime -= days - (LEAP_YEAR(yr) ? 366 : 365); // now it is days in this year, starting at 0
days=0;
for (month=0; month<12; month++) {
uint8_t monthLength;
if (month==1) { // february
monthLength = LEAP_YEAR(yr) ? 29 : 28;
} else {
//monthLength = monthDays[month];
}
if (rawTime < monthLength) break;
rawTime -= monthLength;
}
yy = yr;
my = month+1;
dm = rawTime+1;
// DayOfWeek = weekDays[timeClient.getDay()];
// MonthOfYear = monthNames[my-1];
// String monthStr = ++month < 10 ? "0" + String(month) : String(month); // jan is month 1
// String dayStr = ++rawTime < 10 ? "0" + String(rawTime) : String(rawTime); // day of month
// return String(yr) + "-" + monthStr + "-" + dayStr + "T" + timeClient.getFormattedTime(ss ? ss : 0) + "Z";
}
int openDb(const char *filename, sqlite3 **db) {
int rc = sqlite3_open(filename, db);
if (rc) {
Serial.printf("Can't open database: %s\n", sqlite3_errmsg(*db));
return rc;
} else {
Serial.printf("Opened database successfully\n");
}
return rc;
}