#define DEBUG #include "FastLED.h" #include "GyverButton.h" #define VER "6.101" #include "ESP8266WiFi.h" #include "PubSubClient.h" #include #include #include // #include // #include // #include //#include #include "ArduinoJson.h" // #include // 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 = "Sunny6/status"; const char *top_c = "Sunny6/config"; const char *topic = "Sunny6/"; #else const char *top_s = "Sunny6debug/status"; const char *top_c = "Sunny6debug/config"; const char *topic = "Sunny6debug/"; #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); ESP8266WebServer httpServer(80); ESP8266HTTPUpdateServer httpUpdater; 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 (leds, NUM_LEDS).setCorrection(TypicalLEDStrip); FastLED.setBrightness(0); Serial.begin(115200); randomSeed(analogRead(0)); butt1.setDebounce(20); 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); ID = "Sunny_06"; clientId = ID + String(random(1000)); reconnect(); 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(); httpServer.on("/", handleRoot); httpServer.on("/inline", []() { httpServer.send(200, "text/plain", "this works as well"); }); httpServer.send(200, "text/plain", "hello from esp8266!"); httpServer.onNotFound(handleNotFound); MDNS.begin(ID.c_str()); Serial.print("Web server..."); Serial.println(" running."); httpUpdater.setup(&httpServer); httpServer.begin(); Serial.printf("HTTP Update Server running. Open http://%s.local/update\n\n", ID.c_str()); // 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; } #pragma endregion void loop() { static long dot = 0; static long update = 0; static long update2 = 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; httpServer.handleClient(); butt1.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(); reconnect(); if ((millis() - dot) >= 1000) { dot = millis(); } if ((millis () - update) >= 1000 * 60 * 10) { update = millis(); } if ((millis () - update2) >= 1000 * 60 * 120) { ESP.reset(); } 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 reconnect() { if(WiFi.status() != WL_CONNECTED) { WiFi.begin(AP_SSID, AP_PASS); FastLED.setBrightness(10); Serial.print("Attempting WiFi connection "); 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.print(" connected "); Serial.print("ip: "); Serial.println(WiFi.localIP()); } // Serial.print("mqtt state "); // Serial.println(mclient.state()); if(!mclient.connected()) { Serial.print("Attempting MQTT connection... "); while (!mclient.connected()) { Serial.print("."); if (mclient.connect(clientId.c_str(), mqtt_user, mqtt_pass)) { Serial.println("connected"); // mclient.subscribe(newtop("config")); mclient.subscribe(top_c); } } } } void mqtt_callback(char* topic, byte* payload, unsigned int length) { payload[length] = 0; String a = (const char*)payload; String top = (const char*)topic; #ifdef DEBUG Serial.printf("-- MQTT: %s %s --\r\n", topic, payload); #endif 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 { if (parsed["on"] == "on") { enable = true; test = false; } else { enable = false; test = false; } bri = parsed["bri"]; #ifdef DEBUG Serial.printf("%s %d\r\n", String(parsed["on"]), bri); #endif } } } void reboot() { ESP.reset(); } void web() { // char temp[1000]; // snprintf(temp,1000, // "\ // \ // \ // %s\ // \ // \ // \ //

Привет от %s!
Версия %s

\ //

\ // Загрузка прошивки\ //

\ // \ // ",ID.c_str(),ID.c_str(),VER); // httpServer.send(200,"text/html",temp); } void handleRoot() { String temp; temp += F(""); temp += F(""); temp += F(""); temp += ID.c_str(); temp += F(""); temp += F(""); temp += F(""); temp += F(""); temp += F("

Солнышко

"); temp += F("

Версия "); temp += VER; temp += F("
Сборка "); temp += __DATE__; temp += " "; temp += __TIME__; temp += F("

"); temp += F("

"); temp += F("

Загрузка прошивки

"); temp += F(""); httpServer.send(200,"text/html",temp); } void handleNotFound() { // digitalWrite(LEDR, 1); String message = "File Not Found\n\n"; message += "URI: "; message += httpServer.uri(); message += "\nMethod: "; message += (httpServer.method() == HTTP_GET)?"GET":"POST"; message += "\nArguments: "; message += httpServer.args(); message += "\n"; for (uint8_t i=0; i