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.
1045 lines
32 KiB
1045 lines
32 KiB
#define DEBUG |
|
|
|
#include "FastLED.h" |
|
#include "GyverButton.h" |
|
|
|
#define VER "5.81" |
|
|
|
#include "ESP8266WiFi.h" |
|
#include "PubSubClient.h" |
|
#include <GyverNTP.h> |
|
#include <EEPROM.h> |
|
|
|
#include <ESP8266HTTPClient.h> |
|
//#include <WiFiClient.h> |
|
|
|
#include "ArduinoJson.h" |
|
#include <GyverPortal.h> |
|
GyverPortal ui; |
|
|
|
#define AP_SSID "WT24" |
|
#define AP_PASS "repytwjd" |
|
|
|
String ID = ""; |
|
const char *mqtt_server = "192.168.121.72"; // Имя сервера MQTT |
|
const int mqtt_port = 1883; // Порт для подключения к серверу MQTT |
|
const char *mqtt_user = "mqtt"; |
|
const char *mqtt_pass = "mqtt"; |
|
|
|
bool valSwitch = false; |
|
int valNum = 2; |
|
bool valLed = false; |
|
String valStr; |
|
|
|
|
|
// GyverNTP ntp(3); |
|
WiFiClient wclient; |
|
|
|
#ifndef DEBUG |
|
IPAddress ipa(192, 168, 121, 161); |
|
#else |
|
IPAddress ipa(192, 168, 121, 166); |
|
#endif |
|
IPAddress server(192,168,121,72); |
|
IPAddress gateway(192, 168, 121, 2); |
|
IPAddress dns(192, 168, 121, 2); |
|
IPAddress subnet(255, 255, 255, 0); |
|
|
|
#define BTN_PIN D2 |
|
GButton butt1(BTN_PIN, INPUT, HIGH); |
|
StaticJsonDocument<100> parsed; |
|
int value = 0; |
|
volatile bool enable = false; |
|
volatile bool test = false; |
|
byte counter; |
|
|
|
#define LED_PIN D4 |
|
#define NUM_LEDS 129 |
|
#define LED_TYPE WS2812 |
|
#define COLOR_ORDER GRB |
|
CRGB leds[NUM_LEDS]; |
|
|
|
#pragma region Arrays |
|
const byte PROGMEM stage[][129] = { |
|
{105,106,107,108}, |
|
{103,104,105,106,107,108,109,110,65,66,67,68}, |
|
{101,102,103,104,105,106,107,108,109,110,111,112,63,64,65,66,67,68,69,70,36,37,38}, |
|
{16,17,18,34,35,36,37,38,39,40,62,63,64,65,66,67,68,69,70,71,100,101,102,103,104,105,106,107,108,109,110,111,112,113}, |
|
{4,5,6,15,16,17,18,19,34,35,36,37,38,39,40,61,62,63,64,65,66,67,68,69,70,71,72,100,101,102,103,104,105,106,107,108,109,110,111,112,113}, |
|
{0,3,4,5,6,7,13,14,15,16,17,18,19,20,21,32,33,34,35,36,37,38,39,40,41,42,60,61,62,63,64,65,66,67,68,69,70,71,72,73,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114}, |
|
{0,1,2,3,4,5,6,7,8,12,13,14,15,16,17,18,19,20,21,22,31,32,33,34,35,36,37,38,39,40,41,42,43,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115}, |
|
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116}, |
|
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117}, |
|
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118}, |
|
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128} |
|
}; |
|
const byte l_stage[] = {4,12,23,34,41,56,67,78,91,108,129}; |
|
|
|
const byte stager[][2] PROGMEM = {{0,0},{1,8},{9,24},{25,48},{49,83},{84,128}}; |
|
|
|
const byte PROGMEM stagen[][16] = { |
|
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //1 |
|
{1,2,3,4,5,6,7,8,9,11,13,15,17,19,21,23}, //16 |
|
{9,11,13,15,17,19,21,23,25,28,31,34,37,40,43,46}, //16 |
|
{25,28,31,34,37,40,43,46,49,54,58,62,67,71,76,80}, //16 |
|
{49,54,58,62,67,71,76,80,84,90,95,101,107,112,118,123}, //16 |
|
{84,90,95,101,107,112,118,123,123,123,123,123,123,123,123,123} //8 |
|
}; |
|
const byte l_stagen[] = {1,16,16,16,16,8}; |
|
|
|
#pragma endregion |
|
|
|
#define UPDATES_PER_SECOND 100 |
|
#ifndef DEBUG |
|
const char *top_s = "Sunny5/status"; |
|
const char *top_c = "Sunny5/config"; |
|
const char *topic = "Sunny5/"; |
|
#else |
|
const char *top_s = "Sunny5debug/status"; |
|
const char *top_c = "Sunny5debug/config"; |
|
const char *topic = "Sunny5debug/"; |
|
#endif |
|
|
|
byte baza = 0; |
|
|
|
void btn(); |
|
void reconnect(); |
|
void mqtt_callback(char* topic, byte* payload, unsigned int length); |
|
void pub_new_set(); |
|
|
|
PubSubClient mclient(server, 1883, mqtt_callback, wclient); |
|
|
|
volatile byte mode = 0; |
|
volatile byte mode2 = 0; |
|
byte vv2 = 0; |
|
uint16_t light = 0; |
|
uint8_t tmp = 0; |
|
String d = String(__DATE__) + " " + String(__TIME__); |
|
String v = VER; |
|
volatile bool enable3 = false; |
|
|
|
GPtime valTime_on; |
|
GPtime valTime_off; |
|
GPtime valTime; |
|
Datime dt; |
|
Datime ttt; |
|
|
|
String lt = ""; |
|
int bri = 250; |
|
bool iswd = false; |
|
bool _allow = false; |
|
byte h_on = 0; |
|
byte m_on = 0; |
|
byte h_off = 0; |
|
byte m_off = 0; |
|
byte rd = 0; |
|
byte vd = 0; |
|
// byte vd = 0; |
|
String clientId = ""; |
|
bool flag_one = true; |
|
|
|
#pragma region setup |
|
void setup() |
|
{ |
|
delay(500); // power-up safety delay |
|
FastLED.clear(); |
|
FastLED.show(); |
|
FastLED.addLeds <WS2812, LED_PIN, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); |
|
FastLED.setBrightness(0); |
|
Serial.begin(115200); |
|
randomSeed(analogRead(0)); |
|
butt1.setDebounce(20); // настройка антидребезга (по умолчанию 80 мс) |
|
for(int i = 0; i < 5; i++) |
|
FastLED.show(); |
|
|
|
leds[0] = CRGB::Yellow; |
|
FastLED.setBrightness(10); |
|
FastLED.show(); |
|
|
|
Serial.begin(115200); |
|
|
|
Serial.print("\r\n\r\nVersion: "); |
|
Serial.println(v); |
|
Serial.print("Compiled: "); |
|
Serial.println(d); |
|
|
|
WiFi.mode(WIFI_STA); |
|
WiFi.config(ipa, gateway, subnet, dns); |
|
WiFi.begin(AP_SSID, AP_PASS); |
|
FastLED.setBrightness(10); |
|
while (WiFi.status() != WL_CONNECTED) |
|
{ |
|
Serial.print("."); |
|
leds[0] = CRGB::Red; |
|
FastLED.show(); |
|
delay(500); |
|
leds[0] = CRGB::Yellow; |
|
FastLED.show(); |
|
delay(500); |
|
} |
|
Serial.println(); |
|
Serial.println("WiFi connected"); |
|
Serial.print("ip: "); |
|
Serial.println(WiFi.localIP()); |
|
ID = "Sunny_05"; |
|
Serial.print("Web client "); |
|
Serial.print(ID); |
|
Serial.println(" running."); |
|
|
|
clientId = ID + String(random(1000)); |
|
|
|
if (WiFi.status() == WL_CONNECTED) |
|
{ |
|
if (!mclient.connected()) |
|
{ |
|
Serial.print("Connecting to MQTT server... "); |
|
if (mclient.connect(clientId.c_str(), mqtt_user, mqtt_pass)) |
|
{ |
|
Serial.println("Connected."); |
|
mclient.subscribe(top_c); |
|
Serial.print("MQTT client "); |
|
Serial.print(clientId); |
|
Serial.println(" running."); |
|
} |
|
else |
|
{ |
|
Serial.println("Could not connect to MQTT server"); |
|
} |
|
mclient.publish(top_s, "Выключено",true); |
|
valStr = "Выключено"; |
|
} |
|
} |
|
leds[0] = CRGB::Green; |
|
FastLED.setBrightness(10); |
|
FastLED.show(); |
|
delay(500); |
|
leds[0] = CRGB::Black; |
|
FastLED.setBrightness(10); |
|
FastLED.show(); |
|
|
|
NTP.onError([]() |
|
{ |
|
Serial.println(NTP.readError()); |
|
Serial.print("online: "); |
|
Serial.println(NTP.online()); |
|
// if (NTP.online() == 0) |
|
// { |
|
// NTP.end(); |
|
// NTP.setHost("192.168.121.9"); |
|
// NTP.begin(3); |
|
// NTP.updateNow(); |
|
// } |
|
}); |
|
NTP.onSecond([]() |
|
{ |
|
dt = NTP; |
|
valTime.hour = dt.hour; |
|
valTime.minute = dt.minute; |
|
valTime.second = dt.second; |
|
}); |
|
|
|
NTP.begin(3); |
|
NTP.updateNow(); |
|
dt = NTP; |
|
EEPROM.begin(7); |
|
if (EEPROM.read(0) == 255) |
|
{ |
|
EEPROM.write(0, 0); |
|
EEPROM.write(1, 0); |
|
EEPROM.write(2, 0); |
|
EEPROM.write(3, 0); |
|
EEPROM.write(4, 1); |
|
EEPROM.write(5, 1); |
|
EEPROM.write(6, 250); |
|
} |
|
h_on = EEPROM.read(0); |
|
m_on = EEPROM.read(1); |
|
h_off = EEPROM.read(2); |
|
m_off = EEPROM.read(3); |
|
rd = EEPROM.read(4); |
|
vd = EEPROM.read(5); |
|
bri = EEPROM.read(6); |
|
|
|
valTime_on.hour = EEPROM.read(0); |
|
valTime_on.minute = EEPROM.read(1); |
|
valTime_on.second = 0; |
|
valTime_off.hour = EEPROM.read(2); |
|
valTime_off.minute = EEPROM.read(3); |
|
valTime_off.second = 0; |
|
int ii = isworkday(); |
|
if(ii != -1) |
|
{ |
|
iswd = ii; |
|
if(iswd == 0) |
|
Serial.println("рабочий день"); |
|
else |
|
Serial.println("выходной день"); |
|
} |
|
else |
|
iswd = false; |
|
_allow = allow(); |
|
|
|
ui.attachBuild(build); |
|
ui.attach(action); |
|
ui.start(); |
|
ui.enableOTA(); |
|
ui.downloadAuto(true); |
|
|
|
pub_new_set(); |
|
} |
|
|
|
char* concat(const char *s1, const char *s2) |
|
{ |
|
const size_t len1 = strlen(s1); |
|
const size_t len2 = strlen(s2); |
|
char *result = (char *)malloc(len1 + len2 + 1); // +1 for the null-terminator |
|
// in real code you would check for errors in malloc here |
|
memcpy(result, s1, len1); |
|
memcpy(result + len1, s2, len2 + 1); // +1 to copy the null-terminator |
|
return result; |
|
} |
|
|
|
char* newtop(const char *s2) |
|
{ |
|
const size_t len2 = strlen(s2); |
|
const size_t len1 = strlen(topic); |
|
char *result = (char *)malloc(len1 + len2 + 1); // +1 for the null-terminator |
|
// in real code you would check for errors in malloc here |
|
memcpy(result, topic, len1); |
|
memcpy(result + len1, s2, len2 + 1); // +1 to copy the null-terminator |
|
return result; |
|
} |
|
|
|
void pub_new_set() |
|
{ |
|
char s[5] = {0,}; |
|
sprintf(s, "%02d:%02d",valTime_on.hour,valTime_on.minute); |
|
mclient.publish(newtop("T_on"), s,true); |
|
sprintf(s, "%02d:%02d",valTime_off.hour,valTime_off.minute); |
|
mclient.publish(newtop("T_off"), s,true); |
|
sprintf(s, "%d",rd); |
|
mclient.publish(newtop("Workday"), s,true); |
|
sprintf(s, "%d",vd); |
|
mclient.publish(newtop("Holyday"), s,true); |
|
sprintf(s, "%03d",bri); |
|
mclient.publish(newtop("Brightness"), s,true); |
|
} |
|
#pragma endregion |
|
void loop() |
|
{ |
|
static long dot = 0; |
|
static long update = 0; |
|
static long iwd = 0; |
|
static long voshod = 0; |
|
static long testing = 0; |
|
static byte vvv = 0; |
|
static byte klc = 0; |
|
static byte vv1 = 0; |
|
static byte vv2 = 0; |
|
btn(); |
|
if ((millis() - dot) >= 999) |
|
{ |
|
lt = String(light); |
|
dt = NTP; |
|
valTime.hour = dt.hour; |
|
valTime.minute = dt.minute; |
|
|
|
#ifdef DEBUG |
|
// Serial.printf("%02d:%02d:%02d %02d:%02d:%02d %d\r\n", valTime_on.hour,valTime_on.minute,valTime_on.second,dt.hour,dt.minute,dt.second,_allow); |
|
#endif |
|
|
|
if (dt.hour == valTime_on.hour && dt.minute == valTime_on.minute && dt.second == valTime_on.second && _allow) |
|
{ |
|
enable = true; |
|
#ifdef DEBUG |
|
Serial.printf("time ON test = %d ena = %d mode = %d %02d:%02d %02d:%02d %d %d %d %d\r\n",test, enable, mode, valTime_on.hour,valTime_on.minute,valTime_off.hour,valTime_off.minute,rd,vd,bri,_allow); |
|
#endif |
|
} |
|
if (dt.hour == valTime_off.hour && dt.minute == valTime_off.minute && dt.second == valTime_off.second) |
|
{ |
|
enable = false; |
|
#ifdef DEBUG |
|
Serial.printf("time OFF test = %d ena = %d mode = %d %02d:%02d %02d:%02d %d %d %d %d\r\n",test, enable, mode, valTime_on.hour,valTime_on.minute,valTime_off.hour,valTime_off.minute,rd,vd,bri,_allow); |
|
#endif |
|
} |
|
dot = millis(); |
|
} |
|
if ((millis () - update) >= 1000 * 60 * 30) |
|
{ |
|
if(int ii = isworkday() != -1) |
|
iswd = ii; |
|
else |
|
iswd = false; |
|
_allow = allow(); |
|
update = millis(); |
|
} |
|
if((enable) || test) |
|
{ |
|
switch (mode) |
|
{ |
|
case 0: |
|
if(test) |
|
{ |
|
if ((millis () - voshod) >= 40 * 13) |
|
{ |
|
if(flag_one) |
|
{ |
|
mclient.publish(newtop("status"), "Восход",true); |
|
valStr = "Восход"; |
|
flag_one = false; |
|
} |
|
mclient.publish(newtop("status"), "Восход",true); |
|
valStr = "Восход"; |
|
voshod2(vvv); |
|
if(vvv++ == 10) |
|
{ |
|
vvv = 0; |
|
mode = 1; |
|
voshod = 0; |
|
flag_one = true; |
|
} |
|
voshod = millis(); |
|
} |
|
} |
|
else |
|
{ |
|
#ifdef DEBUG |
|
if ((millis () - voshod) >= 50 * 13) |
|
#else |
|
if ((millis () - voshod) >= 1000 * 13) |
|
#endif |
|
{ |
|
if(flag_one) |
|
{ |
|
mclient.publish(newtop("status"), "Восход",true); |
|
valStr = "Восход"; |
|
flag_one = false; |
|
} |
|
voshod2(vvv); |
|
if(vvv++ == 10) |
|
{ |
|
vvv = 0; |
|
mode = 1; |
|
voshod = 0; |
|
flag_one = true; |
|
} |
|
voshod = millis(); |
|
} |
|
} |
|
break; |
|
case 1: |
|
if ((millis() - voshod) >= 100) |
|
{ |
|
if(flag_one) |
|
{ |
|
mclient.publish(newtop("status"), "Кольца",true); |
|
valStr = "Кольца"; |
|
flag_one = false; |
|
} |
|
kolca2(vv1); |
|
if(vv1++ == 26) |
|
{ |
|
vv1 = 0; |
|
mode = 2; |
|
voshod = 0; |
|
flag_one = true; |
|
} |
|
voshod = millis(); |
|
} |
|
break; |
|
case 2: |
|
if ((millis() - voshod) >= 20) |
|
{ |
|
if(flag_one) |
|
{ |
|
mclient.publish(newtop("status"), "Циклон 1",true); |
|
valStr = "Циклон 1"; |
|
flag_one = false; |
|
} |
|
cyclon(vv1); |
|
if(vv1++ == NUM_LEDS - 1) |
|
{ |
|
vv1 = (NUM_LEDS) - 1; |
|
mode = 3; |
|
voshod = 0; |
|
flag_one = true; |
|
} |
|
voshod = millis(); |
|
} |
|
break; |
|
case 3: |
|
if ((millis() - voshod) >= 20) |
|
{ |
|
if(flag_one) |
|
{ |
|
mclient.publish(newtop("status"), "Циклон 2",true); |
|
valStr = "Циклон 2"; |
|
flag_one = false; |
|
} |
|
cyclon(vv1); |
|
if(vv1-- == 0) |
|
{ |
|
vv1 = 0; |
|
mode = 4; |
|
voshod = 0; |
|
flag_one = true; |
|
} |
|
voshod = millis(); |
|
} |
|
break; |
|
case 4: |
|
if ((millis() - voshod) >= 20) |
|
{ |
|
if(flag_one) |
|
{ |
|
mclient.publish(newtop("status"), "Циклон 1",true); |
|
valStr = "Циклон 1"; |
|
flag_one = false; |
|
} |
|
cyclon(vv1); |
|
if(vv1++ == NUM_LEDS - 1) |
|
{ |
|
vv1 = (NUM_LEDS) - 1; |
|
mode = 5; |
|
voshod = 0; |
|
flag_one = true; |
|
} |
|
voshod = millis(); |
|
} |
|
break; |
|
case 5: |
|
if ((millis() - voshod) >= 20) |
|
{ |
|
if(flag_one) |
|
{ |
|
mclient.publish(newtop("status"), "Циклон 2",true); |
|
valStr = "Циклон 2"; |
|
flag_one = false; |
|
} |
|
cyclon(vv1); |
|
if(vv1-- == 0) |
|
{ |
|
vv1 = 0; |
|
mode = 6; |
|
voshod = 0; |
|
flag_one = true; |
|
} |
|
voshod = millis(); |
|
} |
|
break; |
|
case 6: |
|
if ((millis() - voshod) >= 30) |
|
{ |
|
if(flag_one) |
|
{ |
|
mclient.publish(newtop("status"), "Бегунок",true); |
|
valStr = "Бегунок"; |
|
flag_one = false; |
|
} |
|
begunok(vv1); |
|
// if(vvv++ == 11) |
|
if(vv1++ == 120) |
|
{ |
|
vv1 = 0; |
|
mode = 7; |
|
voshod = 0; |
|
flag_one = true; |
|
} |
|
voshod = millis(); |
|
} |
|
break; |
|
case 7: |
|
if ((millis() - voshod) >= 10) |
|
{ |
|
if(flag_one) |
|
{ |
|
mclient.publish(newtop("status"), "Радуга 1",true); |
|
valStr = "Радуга 1"; |
|
flag_one = false; |
|
} |
|
raduga(vv1); |
|
if(vv1++ == 255) |
|
{ |
|
vv1 = 0; |
|
mode = 8; |
|
voshod = 0; |
|
flag_one = true; |
|
} |
|
voshod = millis(); |
|
} |
|
break; |
|
case 8: |
|
if ((millis() - voshod) >= 100) |
|
{ |
|
if(flag_one) |
|
{ |
|
mclient.publish(newtop("status"), "Лучи",true); |
|
valStr = "Лучи"; |
|
flag_one = false; |
|
} |
|
luchi2(vv1); |
|
// if(vvv++ == 11) |
|
if(vv1++ == 30) |
|
{ |
|
vv1 = 0; |
|
mode = 9; |
|
voshod = 0; |
|
flag_one = true; |
|
} |
|
voshod = millis(); |
|
} |
|
break; |
|
case 9: |
|
if ((millis() - voshod) >= 10) |
|
{ |
|
if(flag_one) |
|
{ |
|
mclient.publish(newtop("status"), "Радуга 2",true); |
|
flag_one = false; |
|
valStr = "Радуга 2"; |
|
} |
|
raduga(vv1); |
|
if(vv1++ == 255) |
|
{ |
|
vv1 = 0; |
|
mode = 10; |
|
voshod = 0; |
|
flag_one = true; |
|
} |
|
voshod = millis(); |
|
} |
|
break; |
|
case 10: |
|
if ((millis() - voshod) >= 100) |
|
{ |
|
if(flag_one) |
|
{ |
|
mclient.publish(newtop("status"), "Кольца 3",true); |
|
valStr = "Кольца 3"; |
|
flag_one = false; |
|
} |
|
kolca3(vv1); |
|
if(vv1++ == 26) |
|
{ |
|
vv1 = 0; |
|
mode = 1; |
|
voshod = 0; |
|
flag_one = true; |
|
if(test) |
|
{ |
|
mode = 0; |
|
test = false; |
|
} |
|
} |
|
voshod = millis(); |
|
} |
|
break; |
|
} |
|
} |
|
else |
|
{ |
|
if(leds[105] != CRGB::Black || leds[128] != CRGB::Black ) |
|
{ |
|
#ifdef DEBUG |
|
Serial.printf("test = %d ena = %d ena2 = %d ena3 = %d mode = %d\r\n", test, enable, mode); |
|
#endif |
|
fill_solid(leds, NUM_LEDS, CRGB::Black); |
|
FastLED.show(); |
|
FastLED.show(); |
|
FastLED.show(); |
|
mclient.publish(newtop("status"), "Выключено",true); |
|
valStr = "Выключено"; |
|
vvv = 0; |
|
vv1 = 0; |
|
mode = 0; |
|
} |
|
} |
|
delay(1); |
|
} |
|
#pragma region LEDS function |
|
void fadetoblack() |
|
{ |
|
for(int i = 0; i < NUM_LEDS; i++) |
|
{ |
|
fadeToBlackBy(leds, NUM_LEDS, 10); |
|
FastLED.show(); |
|
FastLED.delay(1000 / UPDATES_PER_SECOND); |
|
} |
|
} |
|
void voshod2(int num) |
|
{ |
|
for(int c = 0; c < l_stage[num]; c++) |
|
{ |
|
byte x = pgm_read_byte(&(stage[num][c])); |
|
leds[x] = HeatColor(num * 13 + 10); |
|
} |
|
FastLED.setBrightness(bri); |
|
FastLED.show(); |
|
FastLED.show(); |
|
if(leds[105] != HeatColor(num * 13 + 10) && leds[106] != HeatColor(num * 13 + 10)) |
|
{ |
|
for(int c = 0; c < l_stage[num]; c++) |
|
{ |
|
byte x = pgm_read_byte(&(stage[num][c])); |
|
leds[x] = HeatColor(num * 13 + 10); |
|
} |
|
} |
|
} |
|
void kolca2(int num) |
|
{ |
|
num = num % 7; |
|
if(num < 6) |
|
{ |
|
fill_solid(leds, NUM_LEDS, HeatColor(142)); |
|
for(int i = pgm_read_byte_near(&(stager[num][0])); i < pgm_read_byte_near(&(stager[num][1])) + 1; i++) |
|
{ |
|
leds[i] = HeatColor(200); |
|
} |
|
} |
|
else |
|
fill_solid(leds, NUM_LEDS, HeatColor(142)); |
|
FastLED.setBrightness(bri); |
|
FastLED.show(); |
|
FastLED.show(); |
|
} |
|
void kolca3(int num) |
|
{ |
|
num = num % 7; |
|
if(num < 6) |
|
{ |
|
fill_solid(leds, NUM_LEDS, HeatColor(142)); |
|
for(int i = pgm_read_byte_near(&(stager[num][0])); i < pgm_read_byte_near(&(stager[num][1])) + 1; i++) |
|
{ |
|
leds[i] = HeatColor(200); |
|
} |
|
} |
|
else |
|
fill_solid(leds, NUM_LEDS, HeatColor(142)); |
|
FastLED.setBrightness(bri); |
|
fadeToBlackBy(leds, NUM_LEDS, 10); |
|
FastLED.show(); |
|
FastLED.show(); |
|
} |
|
void luchi2(int num) |
|
{ |
|
num = num % 6; |
|
fill_solid(leds, NUM_LEDS, HeatColor(142)); |
|
for(int c = 0; c < l_stagen[num]; c++) |
|
{ |
|
byte x = pgm_read_byte_near(&(stagen[num][c])); |
|
leds[x] = HeatColor(200); |
|
} |
|
FastLED.setBrightness(bri); |
|
FastLED.show(); |
|
FastLED.show(); |
|
} |
|
void begunok(int num) |
|
{ |
|
int col = 255; |
|
fill_solid(leds, NUM_LEDS, HeatColor(142)); |
|
leds[num % 45 + 84] = HeatColor(col); |
|
leds[83 - num % 35] = HeatColor(col); |
|
leds[num % 24 + 25] = HeatColor(col); |
|
leds[24 - num % 16] = HeatColor(col); |
|
leds[num % 8] = HeatColor(col); |
|
FastLED.setBrightness(bri); |
|
FastLED.show(); |
|
} |
|
void raduga(int num) |
|
{ |
|
for (int i = 0; i < NUM_LEDS; i++ ) |
|
{ |
|
leds[i] = CHSV(num + i * 2, 255, 255); |
|
} |
|
FastLED.show(); |
|
} |
|
void konfetti(int num) |
|
{ |
|
fill_solid(leds, NUM_LEDS, HeatColor(0)); |
|
for(int ii = 0; ii < num; ii++) |
|
{ |
|
fadeToBlackBy(leds, NUM_LEDS, 2); |
|
for (int i = 0; i < 8; i++) |
|
{ |
|
leds[beatsin16(i + 7, 0, NUM_LEDS - 1)] |= CHSV(baza+=16, 200, 255); |
|
} |
|
FastLED.setBrightness(bri); |
|
FastLED.show(); |
|
delay(20); |
|
} |
|
} |
|
void raduga2(int num) |
|
{ |
|
byte gHue = 0; |
|
byte chanceOfGlitter = 100; |
|
if (num == 0) |
|
fill_solid(leds, NUM_LEDS, HeatColor(0)); |
|
fill_rainbow( leds, NUM_LEDS, gHue, 2); |
|
if(random8() < chanceOfGlitter) |
|
leds[random16(NUM_LEDS)] += CRGB::White; |
|
gHue++; |
|
FastLED.show(); |
|
} |
|
void cyclon3(int num) |
|
{ |
|
leds[num] = 0xAAAAAA; |
|
FastLED.show(); |
|
leds[num] = CRGB::Black; |
|
leds[num] = CHSV(num, 255, 255); |
|
FastLED.show(); |
|
for(int i = 0; i < NUM_LEDS; i++) |
|
leds[i].nscale8(250); |
|
} |
|
void cyclon(int num) |
|
{ |
|
leds[num] = CHSV(num, 255, 255); |
|
FastLED.show(); |
|
for(int i = 0; i < NUM_LEDS; i++) |
|
leds[i].nscale8(250); |
|
} |
|
#pragma endregion |
|
|
|
#pragma region service |
|
void GP_MY_BLOCK() |
|
{ |
|
String s; |
|
s += F("<style>body{background-color: #f9e79f;}</style><p><img src='http://192.168.121.9/sunny042.png'></p>"); |
|
GP.SEND(s); |
|
} |
|
|
|
void build() |
|
{ |
|
GP.BUILD_BEGIN(); |
|
GP.THEME(GP_LIGHT); |
|
GP.UPDATE("sw,led,bri,eff,rst,rd,vd,valTime_off,valTime_on,valTime"); |
|
GP.TITLE("Солнышко"); |
|
GP.PAGE_TITLE("Солнышко"); |
|
GP.ONLINE_CHECK(); |
|
GP.HR(); |
|
GP_MY_BLOCK(); |
|
GP.HR(); |
|
|
|
M_BLOCK( |
|
M_BOX(GP.LABEL("Сборка"); GP.LABEL(d, "d", GP_DEFAULT, -5);); |
|
M_BOX(GP.LABEL("Версия"); GP.LABEL(v, "v", GP_DEFAULT, -5);); |
|
); |
|
|
|
M_BLOCK( |
|
M_BOX(GP.LABEL("Включить");GP.SWITCH("sw", enable); GP.LED_GREEN("led", enable);); |
|
M_BOX(GP.LABEL("Яркость"); GP.SLIDER("bri", bri, 0, 250, 1, 0, GP_GREEN, 0);); |
|
M_BOX(GP.LABEL("Включить "); GP.TIME("valTime_on",valTime_on); ); |
|
M_BOX(GP.LABEL("Выключить"); GP.TIME("valTime_off",valTime_off); ); |
|
M_BOX(GP.LABEL("Рабочие дни");GP.SWITCH("rd", rd);); |
|
M_BOX(GP.LABEL("Выходные дни");GP.SWITCH("vd", vd);); |
|
M_BOX(GP.LABEL("Эффект"); GP.TEXT("eff", valStr);); |
|
M_BOX(GP.LABEL("Время "); GP.TIME("valTime",valTime); ); |
|
); |
|
|
|
M_BLOCK( |
|
M_BOX(GP_CENTER, GP.OTA_FIRMWARE("Обновление");); |
|
M_BOX(GP_CENTER, GP.BUTTON_MINI("rst"," Перезагрузка ");); |
|
); |
|
GP.BUILD_END(); |
|
} |
|
void action() |
|
{ |
|
if (ui.update()) |
|
{ |
|
ui.updateBool("led", enable); |
|
ui.updateBool("sw", enable); |
|
ui.updateString("eff", valStr); |
|
ui.updateTime("valTime", valTime); |
|
ui.updateTime("valTime_off", valTime_off); |
|
} |
|
|
|
if (ui.click()) |
|
{ |
|
if (ui.click("rst")) |
|
{ |
|
Serial.println("Reset..."); |
|
ESP.reset(); |
|
} |
|
if (ui.clickBool("sw", enable)) |
|
{ |
|
Serial.print("Switch: "); |
|
Serial.println(enable); |
|
} |
|
if (ui.clickInt("bri", bri)) |
|
{ |
|
Serial.print("Bri: "); |
|
Serial.println(bri); |
|
} |
|
if (ui.clickTime("valTime_off",valTime_off)) |
|
{ |
|
Serial.printf("on %02d:%02d off %02d:%02d\r\n",valTime_on.hour,valTime_on.minute,valTime_off.hour,valTime_off.minute); |
|
} |
|
if (ui.clickTime("valTime_on",valTime_on)) |
|
{ |
|
Serial.printf("on %02d:%02d off %02d:%02d\r\n",valTime_on.hour,valTime_on.minute,valTime_off.hour,valTime_off.minute); |
|
Datime d_on, d_off; |
|
d_on.hour = valTime_on.hour; |
|
d_on.minute = valTime_on.minute; |
|
d_off.hour = valTime_off.hour; |
|
d_off.minute = valTime_off.minute; |
|
if(d_off < d_on) |
|
{ |
|
d_on.addMinutes(15); |
|
valTime_off.hour = d_on.hour; |
|
valTime_off.minute = d_on.minute; |
|
Serial.printf("on %02d:%02d off %02d:%02d\r\n",valTime_on.hour,valTime_on.minute,valTime_off.hour,valTime_off.minute); |
|
ui.updateTime("valTime_off", valTime_off); |
|
} |
|
} |
|
if (ui.clickBool("rd", rd)) |
|
{ |
|
Serial.print("rd: "); |
|
Serial.println(rd); |
|
} |
|
if (ui.clickBool("vd", vd)) |
|
{ |
|
Serial.print("vd: "); |
|
Serial.println(vd); |
|
} |
|
if (ui.clickInt("bri", bri)) |
|
{ |
|
Serial.print("bri: "); |
|
Serial.println(bri); |
|
} |
|
EEPROM.write(0, valTime_on.hour); |
|
EEPROM.write(1, valTime_on.minute); |
|
EEPROM.write(2, valTime_off.hour); |
|
EEPROM.write(3, valTime_off.minute); |
|
EEPROM.write(4, rd); |
|
EEPROM.write(5, vd); |
|
EEPROM.write(6, bri); |
|
EEPROM.commit(); |
|
if(mclient.connected()) |
|
Serial.println("MQTT Connected"); |
|
else |
|
Serial.println("MQTT NOT Connected"); |
|
|
|
pub_new_set(); |
|
} |
|
} |
|
void btn() |
|
{ |
|
ui.tick(); |
|
butt1.tick(); |
|
NTP.tick(); |
|
if (butt1.isPress()) |
|
{ |
|
Serial.println("press 0"); |
|
if(enable) |
|
{ |
|
Serial.println("press 1"); |
|
enable = false; |
|
test = false; |
|
#ifdef DEBUG |
|
Serial.printf("test = %d ena = %d mode = %d\r\n", test, enable, mode); |
|
#endif |
|
} |
|
else |
|
{ |
|
Serial.println("press 2"); |
|
test = true; |
|
#ifdef DEBUG |
|
Serial.printf("test = %d ena = %d mode = %d\r\n", test, enable, mode); |
|
#endif |
|
} |
|
} |
|
mclient.loop(); |
|
if(!mclient.connected()) |
|
reconnect(); |
|
} |
|
void reconnect() |
|
{ |
|
mclient.disconnect(); |
|
while (!mclient.connected()) |
|
{ |
|
Serial.print("Attempting MQTT connection..."); |
|
if (mclient.connect(clientId.c_str(), mqtt_user, mqtt_pass)) |
|
{ |
|
Serial.println("connected"); |
|
mclient.subscribe(newtop("config")); |
|
} |
|
} |
|
} |
|
|
|
void mqtt_callback(char* topic, byte* payload, unsigned int length) |
|
{ |
|
payload[length] = 0; |
|
String a = (const char*)payload; |
|
String top = (const char*)topic; |
|
a.toLowerCase(); |
|
a.replace("\r",""); |
|
a.replace("\n",""); |
|
if(top == String(top_c)) |
|
{ |
|
DeserializationError error = deserializeJson(parsed, a); |
|
if (error) |
|
{ |
|
Serial.print(F("deserializeJson() failed: ")); |
|
Serial.println(error.f_str()); |
|
return; |
|
} |
|
else |
|
{ |
|
Serial.println(a); |
|
valTime_on.decode(parsed["t_on"]); |
|
valTime_off.decode(parsed["t_off"]); |
|
bri = parsed["bri"]; |
|
rd = parsed["rd"]; |
|
vd = parsed["vd"]; |
|
EEPROM.write(0, valTime_on.hour); |
|
EEPROM.write(1, valTime_on.minute); |
|
EEPROM.write(2, valTime_off.hour); |
|
EEPROM.write(3, valTime_off.minute); |
|
EEPROM.write(4, rd); |
|
EEPROM.write(5, vd); |
|
EEPROM.write(6, bri); |
|
EEPROM.commit(); |
|
_allow = allow(); |
|
#ifdef DEBUG |
|
Serial.printf("%02d:%02d %02d:%02d %d %d %d %d\r\n", valTime_on.hour,valTime_on.minute,valTime_off.hour,valTime_off.minute,rd,vd,bri,_allow); |
|
#endif |
|
pub_new_set(); |
|
} |
|
} |
|
} |
|
bool allow() |
|
{ |
|
return (!iswd && rd) || (iswd && vd); |
|
} |
|
int isworkday() |
|
{ |
|
if (WiFi.status() == WL_CONNECTED) |
|
{ |
|
HTTPClient http; |
|
char buf[8]; |
|
Datime dt = NTP; |
|
sprintf(buf, "%04d%02d%02d", dt.year, dt.month, dt.day); |
|
String q = "http://isdayoff.ru/" + String(buf); |
|
http.begin(wclient, q.c_str()); |
|
int httpCode = http.GET(); |
|
if (httpCode > 0) |
|
{ |
|
String payload = http.getString(); |
|
http.end(); |
|
return payload.toInt(); |
|
} |
|
else |
|
{ |
|
http.end(); |
|
return -1; |
|
} |
|
} |
|
else return -1; |
|
// return 1; |
|
} |
|
|
|
void reboot() |
|
{ |
|
ESP.reset(); |
|
} |
|
|
|
#pragma endregion
|
|
|