├── .gitignore ├── Event.ino ├── FS.ino ├── LICENSE ├── MQTTDDNS.ino ├── Main.ino ├── NTP.ino ├── README.md ├── Relay.ino ├── SSDP.ino ├── Scenary.ino ├── Timers.ino ├── Upgrade.ino ├── WIFI.ino ├── WS2811.ino ├── Web.ino ├── build ├── 2016 │ ├── build.0x00000_flash_size_1Mb.256Kb_2016.12.08.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2016.12.11.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2016.12.14.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2016.12.15.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2016.12.16.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2016.12.19.bin │ ├── spiffs.0xBB000_flash_size_1Mb.256Kb_2016.12.14.bin │ ├── spiffs.0xBB000_flash_size_1Mb.257Kb_2016.12.16.bin │ └── spiffs.0xBB000_flash_size_1Mb.257Kb_2016.12.19.bin ├── 2017 old │ ├── README.md │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.01.09.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.02.02.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.02.04.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.02.06.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.02.08.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.02.09.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.02.18.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.02.20.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.02.21.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.02.23.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.02.24.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.02.25.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.03.03.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.03.09.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.03.11.bin │ ├── build.0x00000_flash_size_1Mb.256Kb_2017.03.30.bin │ ├── spiffs.0xBB000_flash_size_1Mb.257Kb_2017.01.09.bin │ ├── spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.02.bin │ ├── spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.04.bin │ ├── spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.06.bin │ ├── spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.09.bin │ ├── spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.18.bin │ ├── spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.20.bin │ ├── spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.23.bin │ ├── spiffs.0xBB000_flash_size_1Mb.257Kb_2017.03.03.bin │ ├── spiffs.0xBB000_flash_size_1Mb.257Kb_2017.03.11.bin │ └── spiffs.0xBB000_flash_size_1Mb.257Kb_2017.03.30.bin ├── README.md ├── build.0x00000_flash_size_1Mb.256Kb_2017.06.07.bin ├── build.0x00000_flash_size_1Mb.256Kb_2017.06.08.bin ├── build.0x00000_flash_size_1Mb.256Kb_2017.06.12.bin ├── build.0x00000_flash_size_1Mb.256Kb_2017.06.17.bin ├── build.0x00000_flash_size_1Mb.256Kb_2017.06.21.bin ├── build.0x00000_flash_size_1Mb.256Kb_2017.07.21.bin ├── build.0x00000_flash_size_1Mb.256Kb_2017.07.24.bin ├── build.0x00000_flash_size_1Mb.256Kb_2017.09.11.bin ├── build.0x00000_flash_size_1Mb.256Kb_2017.10.11.bin ├── spiffs.0xBB000_flash_size_1Mb.256Kb_2017.06.07.bin ├── spiffs.0xBB000_flash_size_1Mb.256Kb_2017.06.08.bin ├── spiffs.0xBB000_flash_size_1Mb.256Kb_2017.06.12.bin ├── spiffs.0xBB000_flash_size_1Mb.256Kb_2017.06.17.bin ├── spiffs.0xBB000_flash_size_1Mb.256Kb_2017.06.21.bin ├── spiffs.0xBB000_flash_size_1Mb.256Kb_2017.07.21.bin ├── spiffs.0xBB000_flash_size_1Mb.256Kb_2017.07.24.bin ├── spiffs.0xBB000_flash_size_1Mb.256Kb_2017.09.11.bin └── spiffs.0xBB000_flash_size_1Mb.256Kb_2017.10.11.bin ├── data ├── block-analog.htm.gz ├── block-humidity.htm.gz ├── block-jalousie.htm.gz ├── block-leakag.htm.gz ├── block-relay.htm.gz ├── block-rgb.htm.gz ├── block-temperature.htm.gz ├── chart.json ├── config.save.json ├── config.widgets.json ├── config.widgets1.json ├── configs.json ├── configs │ ├── jalousie.txt │ ├── leakag.txt │ ├── manually.txt │ ├── rgb-shim.txt │ ├── rgb.txt │ ├── smart-room.txt │ └── sonoff-rf.txt ├── css │ └── build.css.gz ├── donate.htm.gz ├── edit.htm.gz ├── favicon.ico ├── first-connect.json ├── help.htm.gz ├── img │ ├── swatches.png │ └── swatches1.png ├── index.htm.gz ├── index.json ├── index2.htm.gz ├── index3.htm.gz ├── index4.htm.gz ├── jalousie.json ├── js │ ├── build.chart.js.gz │ └── function.js.gz ├── lang │ ├── lang.en.json.gz │ ├── lang.lv.json.gz │ ├── lang.ru.json.gz │ └── lang.ua.json.gz ├── page.htm.gz ├── relay.json ├── rgb.json ├── scenary.json ├── scenary.save.txt ├── setup.json ├── starting.json ├── timer.json ├── timer.save.json ├── trigger.jalousie.json ├── trigger.relay.json └── trigger.rgb.json ├── dev_data ├── block-analog.htm ├── block-humidity.htm ├── block-jalousie.htm ├── block-leakag.htm ├── block-relay.htm ├── block-rgb.htm ├── block-temperature.htm ├── css │ ├── bootstrap.min.css │ ├── chartist.min.css │ └── style.css ├── donate.htm ├── edit.htm ├── help.htm ├── index.htm ├── index2.htm ├── index3.htm ├── index4.htm ├── js │ ├── chart.js │ ├── chartist.min.js │ ├── function.js │ └── siema.min.js ├── lang │ ├── lang.en.json │ ├── lang.lv.json │ ├── lang.ru.json │ └── lang.ua.json └── page.htm ├── index.html ├── jalousie.ino ├── manifest.json ├── pre-commit.sh ├── rgb.ino └── tutorial ├── breadboard.gif ├── esp8266_12_wiring.png ├── esp8266_esp01_horizontal-01.png ├── esp8266_esp12e_horizontal-01.png ├── esp8266_wiring.png ├── jalousie.png ├── nodemcu-flasher.png ├── question.png ├── schematic.gif ├── screen1.png ├── screen2.png ├── screen3.png ├── screen4.png ├── smart-home-icon.gif └── sonoff.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | /rgb.cpp.generic.bin 2 | /rgb.ino.generic.bin 3 | -------------------------------------------------------------------------------- /Event.ino: -------------------------------------------------------------------------------- 1 | // ------------------- Инициализация Динамика 2 | void initBuzer() { 3 | int pin = readArgsInt(); 4 | sendOptions("pinBuzer", pin); 5 | pinMode(pin, OUTPUT); 6 | sendStatus("stateBuzer", readArgsInt()); 7 | analogWrite(pin, getStatusInt("stateBuzer")); 8 | analogWriteFreq(0); 9 | } 10 | 11 | void buzerBeep() { 12 | analogWrite(jsonReadtoInt(configLive, "pinBuzer"), readArgsInt()); 13 | analogWriteFreq(readArgsInt()); 14 | } 15 | 16 | 17 | // ----------------- Аналоговый вход A0 18 | void initA0() { 19 | HTTP.on("/analog.json", HTTP_GET, []() { 20 | HTTP.send(200, "application/json", graf(analogRead(A0), 10, 3000, "low:0")); 21 | }); 22 | modulesReg("analog"); 23 | } 24 | // ----------------- Кнопка GPIO 0 25 | void initTach() { 26 | // Кнопка будет работать по прерыванию 27 | uint8_t TACH_PIN = 0; 28 | attachInterrupt(TACH_PIN, Tach_0, RISING); //прерывание сработает, когда состояние вывода изменится с низкого уровня на высокий 29 | configOptions = jsonWrite(configOptions, "TachCommand", readArgsString()); 30 | } 31 | // Выполняется при нажатии на кнопку 32 | void Tach_0() { 33 | static unsigned long millis_prev; 34 | // Устроняем дребезг контакта 35 | if (millis() - 500 > millis_prev) { 36 | command = jsonRead(configOptions, "TachCommand"); 37 | } 38 | millis_prev = millis(); 39 | } 40 | 41 | // ----------------- Движение 42 | void initMotion() { 43 | int pin = readArgsInt(); 44 | pinMode(pin, INPUT); 45 | attachInterrupt(pin, motionOn, RISING); //прерывание сработает, когда состояние вывода изменится с низкого уровня на высокий 46 | String cmd = readArgsString(); 47 | configOptions = jsonWrite(configOptions, "Command", cmd); 48 | modulesReg("movement"); 49 | } 50 | 51 | void motionOn() { 52 | motion.attach(120, motionOff); 53 | command = jsonRead(configOptions, "Command") + "on"; 54 | 55 | } 56 | void motionOff() { 57 | motion.detach(); 58 | command = jsonRead(configOptions, "Command") + "off"; 59 | 60 | } 61 | 62 | // ----------------- DHT 63 | void initDHT() { 64 | dht.setup(readArgsInt()); 65 | //delay(dht.getMinimumSamplingPeriod()); 66 | delay (1000); 67 | 68 | String temp = ""; 69 | temp += dht.getTemperature(); 70 | if (temp != "nan") { 71 | HTTP.on("/temperature.json", HTTP_GET, []() { 72 | float temp = dht.getTemperature(); 73 | if (temp == 'NaN') { 74 | temp = 0; 75 | } 76 | HTTP.send(200, "application/json", graf(temp, 10, 3000, "low:0")); 77 | }); 78 | modulesReg("temperature"); 79 | HTTP.on("/humidity.json", HTTP_GET, []() { 80 | float temp = dht.getHumidity();; 81 | if (temp == 'NaN') { 82 | temp = 0; 83 | } 84 | HTTP.send(200, "application/json", graf(temp, 10, 3000, "low:0")); 85 | }); 86 | modulesReg("humidity"); 87 | } 88 | } 89 | 90 | // ---------- initD18B20 91 | void initD18B20() { 92 | pinMode(d18b20PIN, INPUT_PULLUP); 93 | d18b20.begin(); 94 | d18b20.requestTemperatures(); 95 | float ok = d18b20.getTempCByIndex(0); 96 | d18b20.setResolution(12); 97 | if (ok != -127) { 98 | HTTP.on("/temperature.json", HTTP_GET, []() { 99 | d18b20.requestTemperatures(); 100 | float temp = d18b20.getTempCByIndex(0); 101 | if (temp == -127) { 102 | temp = 0; 103 | } 104 | HTTP.send(200, "application/json", graf(temp, 10, 3000)); 105 | }); 106 | modulesReg("temperature"); 107 | } 108 | } 109 | // ----------------------Приемник на 433мГ 110 | void rfReceived() { 111 | byte pin = readArgsInt(); 112 | if (pin == 1 || pin == 3) Serial.end(); 113 | mySwitch.enableReceive(pin); 114 | // задача опрашивать RC код 115 | ts.add(3, 5, [&](void*) { 116 | RCRCreceiv(); 117 | }, nullptr, true); 118 | sendStatus("Received", 0); 119 | modulesReg("rfReceived"); 120 | } 121 | 122 | void RCRCreceiv() { 123 | if (mySwitch.available()) { 124 | int value = mySwitch.getReceivedValue(); 125 | if (value == 0) { 126 | configJson = jsonWrite(configJson, "Received", 0); 127 | } else { 128 | int codeRC = mySwitch.getReceivedValue(); 129 | flag = sendStatus("Received", codeRC); 130 | } 131 | mySwitch.resetAvailable(); 132 | } 133 | } 134 | 135 | 136 | -------------------------------------------------------------------------------- /FS.ino: -------------------------------------------------------------------------------- 1 | // Инициализация FFS 2 | void FS_init(void) { 3 | SPIFFS.begin(); 4 | { 5 | Dir dir = SPIFFS.openDir("/"); 6 | while (dir.next()) { 7 | String fileName = dir.fileName(); 8 | size_t fileSize = dir.fileSize(); 9 | } 10 | // Создаем список файлов каталога /lang 11 | Lang = FileList("/lang"); 12 | } 13 | //HTTP страницы для работы с FFS 14 | //list directory 15 | HTTP.on("/list", HTTP_GET, handleFileList); 16 | //загрузка редактора editor 17 | HTTP.on("/edit", HTTP_GET, []() { 18 | if (!handleFileRead("/edit.htm")) HTTP.send(404, "text/plain", "FileNotFound"); 19 | }); 20 | //Создание файла 21 | HTTP.on("/edit", HTTP_PUT, handleFileCreate); 22 | //Удаление файла 23 | HTTP.on("/edit", HTTP_DELETE, handleFileDelete); 24 | //first callback is called after the request has ended with all parsed arguments 25 | //second callback handles file uploads at that location 26 | HTTP.on("/edit", HTTP_POST, []() { 27 | HTTP.send(200, "text/plain", ""); 28 | }, handleFileUpload); 29 | //called when the url is not defined here 30 | //use it to load content from SPIFFS 31 | HTTP.onNotFound([]() { 32 | if (!handleFileRead(HTTP.uri())) 33 | HTTP.send(404, "text/plain", "FileNotFound"); 34 | }); 35 | HTTP.on("/skins", HTTP_GET, []() { 36 | String set=HTTP.arg("set"); 37 | //configJson = jsonWrite(configJson, "setIndex", set); 38 | configSetup = jsonWrite(configSetup, "setIndex", set); 39 | saveConfigSetup(); 40 | HTTP.send(307, "Temporary Redirect\r\nLocation: /\r\nConnection: Close\r\n", ""); 41 | }); 42 | 43 | } 44 | 45 | // Здесь функции для работы с файловой системой 46 | String getContentType(String filename) { 47 | if (HTTP.hasArg("download")) return "application/octet-stream"; 48 | else if (filename.endsWith(".htm")) return "text/html"; 49 | else if (filename.endsWith(".html")) return "text/html"; 50 | else if (filename.endsWith(".json")) return "application/json"; 51 | else if (filename.endsWith(".css")) return "text/css"; 52 | else if (filename.endsWith(".js")) return "application/javascript"; 53 | else if (filename.endsWith(".png")) return "image/png"; 54 | else if (filename.endsWith(".gif")) return "image/gif"; 55 | else if (filename.endsWith(".jpg")) return "image/jpeg"; 56 | else if (filename.endsWith(".ico")) return "image/x-icon"; 57 | else if (filename.endsWith(".xml")) return "text/xml"; 58 | else if (filename.endsWith(".pdf")) return "application/x-pdf"; 59 | else if (filename.endsWith(".zip")) return "application/x-zip"; 60 | else if (filename.endsWith(".gz")) return "application/x-gzip"; 61 | return "text/plain"; 62 | } 63 | 64 | bool handleFileRead(String path) { 65 | String setIndex = jsonRead(configSetup, "setIndex"); 66 | if (setIndex == "") setIndex = "index.htm"; 67 | if (path.endsWith("/")) path += setIndex; 68 | String contentType = getContentType(path); 69 | String pathWithGz = path + ".gz"; 70 | if (SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) { 71 | if (SPIFFS.exists(pathWithGz)) 72 | path += ".gz"; 73 | File file = SPIFFS.open(path, "r"); 74 | size_t sent = HTTP.streamFile(file, contentType); 75 | file.close(); 76 | return true; 77 | } 78 | return false; 79 | } 80 | 81 | void handleFileUpload() { 82 | if (HTTP.uri() != "/edit") return; 83 | HTTPUpload& upload = HTTP.upload(); 84 | if (upload.status == UPLOAD_FILE_START) { 85 | String filename = upload.filename; 86 | if (!filename.startsWith("/")) filename = "/" + filename; 87 | fsUploadFile = SPIFFS.open(filename, "w"); 88 | filename = String(); 89 | } else if (upload.status == UPLOAD_FILE_WRITE) { 90 | //DBG_OUTPUT_PORT.print("handleFileUpload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize); 91 | if (fsUploadFile) 92 | fsUploadFile.write(upload.buf, upload.currentSize); 93 | } else if (upload.status == UPLOAD_FILE_END) { 94 | if (fsUploadFile) 95 | fsUploadFile.close(); 96 | } 97 | } 98 | 99 | void handleFileDelete() { 100 | if (HTTP.args() == 0) return HTTP.send(500, "text/plain", "BAD ARGS"); 101 | String path = HTTP.arg(0); 102 | if (path == "/") 103 | return HTTP.send(500, "text/plain", "BAD PATH"); 104 | if (!SPIFFS.exists(path)) 105 | return HTTP.send(404, "text/plain", "FileNotFound"); 106 | SPIFFS.remove(path); 107 | HTTP.send(200, "text/plain", ""); 108 | path = String(); 109 | } 110 | 111 | void handleFileCreate() { 112 | if (HTTP.args() == 0) 113 | return HTTP.send(500, "text/plain", "BAD ARGS"); 114 | String path = HTTP.arg(0); 115 | if (path == "/") 116 | return HTTP.send(500, "text/plain", "BAD PATH"); 117 | if (SPIFFS.exists(path)) 118 | return HTTP.send(500, "text/plain", "FILE EXISTS"); 119 | File file = SPIFFS.open(path, "w"); 120 | if (file) 121 | file.close(); 122 | else 123 | return HTTP.send(500, "text/plain", "CREATE FAILED"); 124 | HTTP.send(200, "text/plain", ""); 125 | path = String(); 126 | 127 | } 128 | 129 | void handleFileList() { 130 | if (!HTTP.hasArg("dir")) { 131 | HTTP.send(500, "text/plain", "BAD ARGS"); 132 | return; 133 | } 134 | String path = HTTP.arg("dir"); 135 | HTTP.send(200, "application/json", FileList(path)); 136 | } 137 | 138 | // Создаем список файлов каталога 139 | String FileList(String path) { 140 | Dir dir = SPIFFS.openDir(path); 141 | path = String(); 142 | String output = "["; 143 | while (dir.next()) { 144 | File entry = dir.openFile("r"); 145 | if (output != "[") output += ','; 146 | bool isDir = false; 147 | output += "{\"type\":\""; 148 | output += (isDir) ? "dir" : "file"; 149 | output += "\",\"name\":\""; 150 | output += String(entry.name()).substring(1); 151 | output += "\"}"; 152 | entry.close(); 153 | } 154 | output += "]"; 155 | return output; 156 | } 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Renats Kevrels (https://github.com/renat2985) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MQTTDDNS.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Для использования вкладки требуется добавить в заголовке скетча следуюший код 3 | #include 4 | WiFiClient wclient; 5 | PubSubClient client(wclient); 6 | */ 7 | 8 | void callback(const MQTT::Publish& pub) 9 | { 10 | Serial.print(pub.topic()); // выводим в сериал порт название топика 11 | Serial.print(" => "); 12 | Serial.print(pub.payload_string()); // выводим в сериал порт значение полученных данных 13 | Serial.println(); 14 | String payload = pub.payload_string(); 15 | Serial.println(payload); 16 | 17 | if ( pub.payload_string() == "HELLO" ) { // handshaking 18 | 19 | loadnWidgets(); 20 | } 21 | 22 | if (String(pub.topic()) == prefix + "/" + chipID + "/RELE_1_not/control") // проверяем из нужного ли нам топика пришли данные 23 | //if (String(pub.topic()) == prefix + "/"+chipID + "/RELE_1_not/status") // проверяем из нужного ли нам топика пришли данные 24 | { 25 | int stled = payload.toInt(); // преобразуем полученные данные в тип integer 26 | if (stled == 1) command = "relayon"; 27 | if (stled == 0) command = "relayoff"; 28 | 29 | 30 | } 31 | 32 | } 33 | 34 | void initMQTT() { 35 | HTTP.on("/mqtt", handle_Set_MQTT); 36 | modulesReg("mqtt"); 37 | MQTT_Pablush(); 38 | } 39 | 40 | void MQTT_Pablush() { 41 | String mqtt_server = jsonRead(configSetup, "mqttServer"); 42 | if ((mqtt_server != "")) { 43 | client.set_server(mqtt_server, jsonReadtoInt(configSetup, "mqttPort")); 44 | // подключаемся к MQTT серверу 45 | if (WiFi.status() == WL_CONNECTED) { 46 | if (!client.connected()) { 47 | if (client.connect(MQTT::Connect(chipID) 48 | .set_auth(jsonRead(configSetup, "mqttUser"), jsonRead(configSetup, "mqttPass")))) { 49 | client.set_callback(callback); 50 | client.subscribe(prefix); // Для приема получения HELLOW и подтверждения связи 51 | client.subscribe(prefix + "/+/+/control"); // Подписываемся на топики control 52 | //client.subscribe("/" + chipID + "/RELE_1"); // подписываемся по топик с данными для светодиода 53 | loadnWidgets(); 54 | } else { 55 | } 56 | } 57 | } 58 | } 59 | } 60 | 61 | void handleMQTT() { 62 | if (client.connected()) client.loop(); 63 | else { 64 | MQTT_Pablush(); 65 | //Serial.println("MQTT"); 66 | } 67 | } 68 | 69 | //Установка параметров http://192.168.0.101/mqtt?server=m13.cloudmqtt.com&port=15535&user=cxluynva&pass=4cje5WEkzqvR 70 | void handle_Set_MQTT() { // 71 | configSetup = jsonWrite(configSetup, "mqttServer", HTTP.arg("server")); 72 | configSetup = jsonWrite(configSetup, "mqttPort", HTTP.arg("port").toInt()); 73 | configSetup = jsonWrite(configSetup, "mqttUser", HTTP.arg("user")); 74 | configSetup = jsonWrite(configSetup, "mqttPass", HTTP.arg("pass")); 75 | saveConfigSetup (); 76 | client.disconnect(); 77 | MQTT_Pablush(); 78 | HTTP.send(200, "text/plain", "OK"); // отправляем ответ о выполнении 79 | } 80 | 81 | 82 | 83 | // Читаем и отправляем виджеты на сервер 84 | bool loadnWidgets() { 85 | 86 | DynamicJsonBuffer jsonBuffer; 87 | JsonObject& Widgets = jsonBuffer.parseObject(readFile("config.widgets.json", 4096)); 88 | JsonArray& WidgetsArray = Widgets["nWidgets"].asArray(); 89 | int j = WidgetsArray.size(); 90 | if (j != 0) { 91 | for (int i = 0; i <= j - 1; i++) { 92 | Widgets["nWidgets"][i]["topic"] = prefix + "/" + chipID + Widgets["nWidgets"][i]["topic"].as(); 93 | //Widgets["nWidgets"][i]["descr"] = jsonRead(configSetup, "SSDP"); 94 | String thing_config = Widgets["nWidgets"][i].as(); 95 | //Serial.println(thing_config); 96 | client.publish(MQTT::Publish(prefix + "/" + chipID + "/config", thing_config).set_qos(1)); 97 | } 98 | } 99 | return true; 100 | } 101 | 102 | 103 | // --------------------- Включаем DDNS 104 | void initDDNS() { 105 | HTTPWAN = ESP8266WebServer (jsonReadtoInt(configSetup, "ddnsPort")); 106 | HTTP.on("/ddns", handle_ddns); // Установка параметров ddns 107 | HTTPWAN.begin(); 108 | // задача синхронизайия с сервером ddns каждые 10 минут 109 | ts.add(4, 600000, [&](void*) { 110 | ip_wan(); 111 | }, nullptr, true); 112 | modulesReg("ddns"); 113 | } 114 | 115 | // ------------------------------Установка параметров ddns 116 | void handle_ddns() { 117 | configSetup = jsonWrite(configSetup, "ddns", HTTP.arg("ddns")); 118 | configSetup = jsonWrite(configSetup, "ddnsName", HTTP.arg("ddnsName")); 119 | configSetup = jsonWrite(configSetup, "ddnsPort", HTTP.arg("ddnsPort")); 120 | ip_wan(); 121 | saveConfigSetup (); 122 | HTTP.send(200, "text/plain", "OK"); 123 | } 124 | 125 | // --------------------------------Запрос для синхронизации внешнего ip адреса с ddns 126 | int ip_wan() { 127 | String ddns = jsonRead(configSetup, "ddns"); 128 | if (ddns != "") { 129 | getURL(ddns); 130 | } 131 | } 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /NTP.ino: -------------------------------------------------------------------------------- 1 | #include //Содержится в пакете 2 | void initNTP() { 3 | HTTP.on("/Time", handle_Time); // Синхронизировать время устройства по запросу вида /Time 4 | HTTP.on("/timeZone", handle_time_zone); // Установка времянной зоны 5 | timeSynch(jsonReadtoInt(configSetup, "timeZone")); 6 | modulesReg("ntp"); 7 | } 8 | 9 | void timeSynch(int zone) { 10 | if (WiFi.status() == WL_CONNECTED) { 11 | // Инициализация UDP соединения с NTP сервером 12 | configTime(zone * 3600, 0, "pool.ntp.org", "ru.pool.ntp.org"); 13 | int i = 0; 14 | while (!time(nullptr) && i < 10) { 15 | i++; 16 | delay(100); 17 | } 18 | String timeNow = GetTime(); 19 | configJson = jsonWrite(configJson, "time", timeNow); 20 | configSetup = jsonWrite(configSetup, "time", timeNow); 21 | } 22 | } 23 | 24 | // ---------- Синхронизация времени 25 | void handle_Time() { 26 | timeSynch(jsonReadtoInt(configSetup, "timeZone")); 27 | String out = "{}"; 28 | out = jsonWrite(out, "title", "{{LangTime1}} "+GetTime()+""); 29 | HTTP.send(200, "text/plain", out); // отправляем ответ о выполнении 30 | } 31 | 32 | // ---------- Установка параметров времянной зоны по запросу вида http://192.168.0.101/timeZone?timezone=3 33 | void handle_time_zone() { 34 | int timezone = HTTP.arg("timeZone").toInt(); // Получаем значение timezone из запроса конвертируем в int сохраняем в глобальной переменной 35 | configOptions = jsonWrite(configOptions, "timeZone", timezone); 36 | configSetup = jsonWrite(configSetup, "timeZone", timezone); 37 | timeSynch(timezone); 38 | saveConfigSetup (); 39 | HTTP.send(200, "text/plain", "OK"); 40 | } 41 | 42 | // Получение текущего времени 43 | String GetTime() { 44 | time_t now = time(nullptr); // получаем время с помощью библиотеки time.h 45 | String Time = ""; // Строка для результатов времени 46 | Time += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017 47 | int i = Time.indexOf(":"); //Ишем позицию первого символа : 48 | Time = Time.substring(i - 2, i + 6); // Выделяем из строки 2 символа перед символом : и 6 символов после 49 | return Time; // Возврашаем полученное время 50 | } 51 | 52 | 53 | // Получение даты 54 | String GetDate() { 55 | time_t now = time(nullptr); // получаем время с помощью библиотеки time.h 56 | String Data = ""; // Строка для результатов времени 57 | Data += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017 58 | Data.replace("\n", ""); 59 | int i = Data.lastIndexOf(" "); //Ишем позицию последнего символа пробел 60 | String Time = Data.substring(i - 8, i+1); // Выделяем время и пробел 61 | Data.replace(Time, ""); // Удаляем из строки 8 символов времени и пробел 62 | return Data; // Возврашаем полученную дату 63 | } 64 | // Получение дня недели 65 | String GetWeekday() { 66 | String Data = GetDate(); 67 | int i = Data.indexOf(" "); //Ишем позицию первого символа пробел 68 | String weekday = Data.substring(i - 3, i); // Выделяем время и пробел 69 | return weekday; 70 | } 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # **Офлайн умный дом** на базе ESP8266 и светодиодов WS2811/WS2812/NeoPixel 2 | 3 |

4 | 5 | 6 | 7 | 8 |

9 | 10 | 11 | 12 | ## Описание 13 | 14 | Этот проект предназначен для создания автономной системы умного дома с использованием микроконтроллера ESP8266 и светодиодов WS2811/WS2812/NeoPixel. Он предоставляет функциональность управления освещением и другими устройствами без необходимости постоянного подключения к интернету. 15 | 16 | ## Особенности 17 | 18 | - **NTP**: Синхронизация времени через протокол NTP. 19 | - **DDNS**: Поддержка динамического DNS для удаленного доступа. 20 | - **Таймеры**: Настройка автоматических действий по расписанию. 21 | - **Датчики**: Поддержка DHT11, DHT22, AM2302, RHT03, DS18B20 и аналоговых датчиков. 22 | - **Реле**: Управление до 4 реле. 23 | - **Жалюзи**: Контроль жалюзи через интерфейс. 24 | - **Светодиоды**: Управление светодиодами WS2811/WS2812/NeoPixel. 25 | - **RF и IR**: Прием и передача сигналов радиочастотного и инфракрасного диапазонов. 26 | 27 | ## Установка 28 | 29 | ### 🚀 Веб установка (рекомендуется) 30 | 31 | Откройте этот сайт и следуйте инструкциям 32 | 33 | ### [https://renat2985.github.io/rgb/](https://renat2985.github.io/rgb/) 34 | 35 | ### Или используйте NodeMCU Flasher 36 | 37 | 1. **Загрузка прошивки**: Скачайте файл прошивки [Build.Spiffs.flash.1Mb.256Kb.2018.12.03.zip](https://github.com/renat2985/rgb/releases/download/3.0/Build.Spiffs.flash.1Mb.256Kb.2018.12.03.zip) 38 | 39 | 2. **Инструмент прошивки**: Скачайте [NodeMCU Flasher](https://github.com/nodemcu/nodemcu-flasher) для Windows ([Win32](https://github.com/nodemcu/nodemcu-flasher/blob/master/Win32/Release/ESP8266Flasher.exe) или [Win64](https://github.com/nodemcu/nodemcu-flasher/blob/master/Win64/Release/ESP8266Flasher.exe)). 40 | 3. **Настройка**: Настройте параметры прошивки: 41 | ``` 42 | - Модуль: Generic ESP8266 Module 43 | - Размер флеша: 1 МБ 44 | - Режим флеша: DIO 45 | - Частота флеша: 40 МГц 46 | - Скорость загрузки: 921600 47 | ``` 48 | 49 | 50 | 51 | ## Примеры использования 52 | 53 | 54 | Пример работы системы можно посмотреть в [этом видео](https://github.com/renat2985/rgb), здесь мы сделали большое количество видео по обучению. 55 | Так же советуем почитать [wiki](https://github.com/renat2985/rgb/wiki), там вы тоже найдете много полезного. 56 | 57 | [![IMAGE ALT TEXT HERE](https://img.youtube.com/vi/rNLlpkg2BGI/0.jpg)](https://www.youtube.com/playlist?list=PL6NJTNxbvy-IPTDQk8XjTV41oRrFafrRi) 58 | 59 | ## Мобильное приложение 60 | 61 | Для удобного управления системой доступно мобильное приложение: 62 | 63 | - **Репозиторий**: [iot-room-finder](https://github.com/tutaf/iot-room-finder) 64 | - **Скачать**: [Google Play](https://play.google.com/store/apps/details?id=com.tutaf.iotroomfinder) 65 | 66 | Приложение отправляет UPnP-пакет в локальную сеть, и первое устройство, которое ответит, откроется в вашем браузере, что избавляет от необходимости запоминать IP-адреса устройств. 67 | 68 | ## Благодарности 69 | 70 | Особая благодарность Андрею за разработку мобильного приложения. 71 | 72 | 73 | 74 | ## Другие наши проекты 75 | 76 | - Jalousie: [https://github.com/tretyakovsa/jaluzi](https://github.com/tretyakovsa/jaluzi) 77 | 78 | - Sonoff: [https://github.com/tretyakovsa/Sonoff_WiFi_switch](https://github.com/tretyakovsa/Sonoff_WiFi_switch) 79 | 80 | - Themes you can download here: [https://bootswatch.com/3/](https://bootswatch.com/3/) 81 | 82 | 83 | ## :battery: Donation 84 | 85 | If you like this project, you can buy me a cup of coffee :coffee: 86 | 87 | 88 | 89 | - PayPal [https://www.paypal.me/RKevrels](https://www.paypal.me/RKevrels/5) 90 | -------------------------------------------------------------------------------- /Relay.ino: -------------------------------------------------------------------------------- 1 | // ------------------- Инициализация Реле 2 | void initRelay() { 3 | int pin = readArgsInt(); 4 | sendOptions("relay1Pin", pin); 5 | pinMode(pin, OUTPUT); 6 | sendStatus("stateRelay", readArgsInt()); 7 | digitalWrite(pin, getStatusInt("stateRelay")); 8 | 9 | sCmd.addCommand("relayon", relayOn); 10 | sCmd.addCommand("relayoff", relayOff); 11 | sCmd.addCommand("relaynot", relayNot); 12 | commandsReg("relayon", "relay"); 13 | commandsReg("relayoff", "relay"); 14 | commandsReg("relaynot", "relay"); 15 | 16 | HTTP.on("/relay", relay); // реакция на запрос 17 | HTTP.on("/relayon", relayon); // реакция на запрос 18 | HTTP.on("/relayoff", relayoff); // реакция на запрос 19 | HTTP.on("/sonoff", relay); // реакция на запрос 20 | 21 | HTTPWAN.on("/relay", relayddns); // реакция на запрос 22 | HTTPWAN.on("/relayon", relayonddns); // реакция на запрос 23 | HTTPWAN.on("/relayoff", relayoffddns); // реакция на запрос 24 | HTTPWAN.on("/sonoff", relayddns); // реакция на запрос 25 | modulesReg("relay"); 26 | } 27 | void relayddns() { 28 | sCmd.readStr("relaynot"); 29 | HTTPWAN.send(200, "application/json", relayStatus(configJson, "stateRelay")); 30 | } 31 | void relayonddns() { 32 | sCmd.readStr("relayon"); 33 | HTTPWAN.send(200, "application/json", relayStatus(configJson, "stateRelay")); 34 | } 35 | void relayoffddns() { 36 | sCmd.readStr("relayoff"); 37 | HTTPWAN.send(200, "application/json", relayStatus(configJson, "stateRelay")); 38 | } 39 | void relay() { 40 | sCmd.readStr("relaynot"); 41 | HTTP.send(200, "application/json", relayStatus(configJson, "stateRelay")); 42 | } 43 | void relayon() { 44 | sCmd.readStr("relayon"); 45 | HTTP.send(200, "application/json", relayStatus(configJson, "stateRelay")); 46 | } 47 | void relayoff() { 48 | sCmd.readStr("relayoff"); 49 | HTTP.send(200, "application/json", relayStatus(configJson, "stateRelayRelay")); 50 | } 51 | 52 | // читает данные из раздела state строки json и возвращает строку для смены класса кнопки 53 | String relayStatus(String json, String state) { 54 | String out = "{}"; 55 | if (jsonReadtoInt(json, state)) { 56 | out = jsonWrite(out, "title", "{{LangOff}}"); 57 | out = jsonWrite(out, "class", "btn btn-block btn-lg btn-info"); 58 | } 59 | else { 60 | out = jsonWrite(out, "title", "{{LangOn}}"); 61 | out = jsonWrite(out, "class", "btn btn-block btn-lg btn-primary"); 62 | 63 | } 64 | return out; 65 | } 66 | void relayOn() { 67 | if (!getStatusInt("stateRelay")) flag = sendStatus("stateRelay", 1); 68 | digitalWrite(getOptionsInt("relay1Pin"), getStatusInt("stateRelay")); 69 | toggleRelay(getStatusInt("stateRelay")); 70 | topicPub("/RELE_1_not/status", String(getStatusInt("stateRelay")), 1 ); 71 | } 72 | 73 | void relayOff() { 74 | if (getStatusInt("stateRelay")) flag = sendStatus("stateRelay", 0); 75 | digitalWrite(getOptionsInt("relay1Pin"), getStatusInt("stateRelay")); 76 | toggleRelay(getStatusInt("stateRelay")); 77 | topicPub("/RELE_1_not/status", String(getStatusInt("stateRelay")), 1 ); 78 | } 79 | 80 | void relayNot() { 81 | flag = sendStatus("stateRelay", !getStatusInt("stateRelay")); 82 | digitalWrite(getOptionsInt("relay1Pin"), getStatusInt("stateRelay")); 83 | toggleRelay(getStatusInt("stateRelay")); 84 | topicPub("/RELE_1_not/status", String(getStatusInt("stateRelay")), 1 ); 85 | } 86 | void topicPub(String topic, String data, boolean retain ) { 87 | client.publish(MQTT::Publish(prefix + "/" + chipID + topic, "{\"status\":" + data + "}").set_retain(1)); 88 | } 89 | 90 | // -------------- Для управления реле по UART 91 | // https://www.banggood.com/ru/ESP8266-5V-WiFi-Relay-Module-Internet-Of-Things-Smart-Home-Phone-APP-Remote-Control-Switch-p-1126605.html?rmmds=category 92 | 93 | void toggleRelay(bool relayState) { 94 | if (relayState) { 95 | const byte miBufferON[] = {0xA0, 0x01, 0x01, 0xA2}; 96 | Serial.write(miBufferON, sizeof(miBufferON)); 97 | } 98 | else { 99 | //To disable the Relay send it by serial port: 100 | const byte miBufferOFF[] = {0xA0, 0x01, 0x00, 0xA1}; 101 | Serial.write(miBufferOFF, sizeof(miBufferOFF)); 102 | } 103 | } 104 | 105 | 106 | -------------------------------------------------------------------------------- /SSDP.ino: -------------------------------------------------------------------------------- 1 | void initSSDP() { 2 | // Включаем определение имени для Windows 3 | // Модуль будет доступен по запросу вида 4 | String temp = jsonRead(configSetup, "SSDP"); 5 | if (temp == "") { 6 | temp = "Sonoff"; 7 | configSetup = jsonWrite(configSetup, "SSDP", temp); 8 | saveConfigSetup (); 9 | } 10 | ssdpList = jsonWrite(ssdpList, jsonRead(configSetup, "SSDP"), WiFi.localIP().toString()); 11 | //LLMNR.begin(temp.c_str()); 12 | //NBNS.begin(temp.c_str()); 13 | unsigned int localPort = 1901; 14 | udp.begin(localPort); 15 | // задача проверять смену ip каждые 30 секунд 16 | ts.add(1, 30000, [&](void*) { 17 | ipChanges(); 18 | }, nullptr, true); 19 | // задача проверять наличие устройств в сети каждые две минуты. 20 | ts.add(2, 120000, [&](void*) { 21 | requestSSDP(); 22 | }, nullptr, true); 23 | // SSDP дескриптор 24 | HTTP.on("/description.xml", HTTP_GET, []() { 25 | SSDP.schema(HTTP.client()); 26 | }); 27 | SSDP.setDeviceType("upnp:rootdevice"); 28 | SSDP.setSchemaURL("description.xml"); 29 | SSDP.setHTTPPort(80); 30 | SSDP.setName(jsonRead(configSetup, "SSDP")); 31 | SSDP.setSerialNumber(chipID); 32 | SSDP.setURL("/"); 33 | SSDP.setModelName(jsonRead(configSetup, "configs")); 34 | SSDP.setModelNumber(chipID + "/" + jsonRead(configSetup, "SSDP")); 35 | SSDP.setModelURL("https://github.com/tretyakovsa/Sonoff_WiFi_switch"); 36 | SSDP.setManufacturer("Tretyakov Sergey, Kevrels Renats"); 37 | SSDP.setManufacturerURL("http://www.esp8266-arduinoide.ru"); 38 | SSDP.begin(); 39 | 40 | // Установить имя устройства 41 | HTTP.on("/device", handle_device); // Установить имя устройства 42 | HTTP.on("/ip.list.json", HTTP_GET, []() { 43 | HTTP.send(200, "application/json", addressList); 44 | }); 45 | HTTP.on("/ssdp.list.json", HTTP_GET, []() { 46 | HTTP.send(200, "application/json", ssdpList); 47 | }); 48 | } 49 | 50 | // ------------- Установить имя устройства 51 | void handle_device() { 52 | // /device?ssdp=Sonoff-Rele&space={{space}} 53 | String ssdpName = HTTP.arg("ssdp"); 54 | configSetup = jsonWrite(configSetup, "SSDP", ssdpName); 55 | configOptions = jsonWrite(configOptions, "SSDP", ssdpName); 56 | modules = jsonWrite(modules, "SSDP", ssdpName); 57 | SSDP.setName(ssdpName); 58 | SSDP.setModelNumber(chipID + "/" + jsonRead(configSetup, "SSDP")); 59 | String space = HTTP.arg("space"); 60 | configSetup = jsonWrite(configSetup, "space", space); 61 | configOptions = jsonWrite(configOptions, "space", space); 62 | modules = jsonWrite(modules, "space", space); 63 | HTTP.send(200, "text/plain", "Ok"); 64 | saveConfigSetup(); 65 | } 66 | 67 | // ------------- SSDP запрос 68 | void requestSSDP () { 69 | if (WiFi.status() == WL_CONNECTED) { 70 | //addressList = "{\"ssdpList\":[]}"; 71 | //ssdpLists(chipID, WiFi.localIP().toString(), jsonRead(configSetup, "SSDP")); 72 | ssdpList = jsonWrite(ssdpList, jsonRead(configSetup, "SSDP"), WiFi.localIP().toString()); 73 | IPAddress ssdpAdress(239, 255, 255, 250); 74 | unsigned int ssdpPort = 1900; 75 | char ReplyBuffer[] = "M-SEARCH * HTTP/1.1\r\nHost:239.255.255.250:1900\r\nST:upnp:rootdevice\r\nMan:\"ssdp:discover\"\r\nMX:3\r\n\r\n"; 76 | udp.beginPacket(ssdpAdress, ssdpPort); 77 | udp.write(ReplyBuffer); 78 | udp.endPacket(); 79 | } 80 | } 81 | // ------------- Чтение ответа от устройств SSDP слушаем порт все время 82 | void handleUDP() { 83 | String input_string = ""; 84 | String chipIDremote = ""; 85 | String ssdpName = ""; 86 | char packetBuffer[512]; 87 | int packetSize = udp.parsePacket(); 88 | if (packetSize) { 89 | int len = udp.read(packetBuffer, 512); 90 | if (len > 0) packetBuffer[len] = 0; 91 | input_string += packetBuffer; 92 | int i = input_string.indexOf("Arduino"); 93 | if (i > 0) { 94 | 95 | chipIDremote = deleteBeforeDelimiter(input_string, "Arduino"); 96 | chipIDremote = selectToMarker(chipIDremote, "\n"); 97 | //1.0 UPNP/1.1 smart-room/4039-1458400/IoT-Room 2 (\n) 98 | ssdpName = selectToMarkerLast(chipIDremote, "/"); 99 | ssdpName = selectToMarker(ssdpName, "\r"); 100 | chipIDremote = selectToMarkerLast(chipIDremote, "/"); 101 | chipIDremote = selectToMarker(chipIDremote, "\r"); 102 | // строку input_string сохраняю для расширения 103 | ssdpList = jsonWrite(ssdpList, chipIDremote, udp.remoteIP().toString()); 104 | 105 | } 106 | } 107 | } 108 | void ssdpLists(String chipIDremote, String remoteIP, String ssdpName ) { 109 | DynamicJsonBuffer jsonBuffer; 110 | JsonObject& list = jsonBuffer.parseObject(addressList); 111 | JsonArray& arrays = list["ssdpList"].asArray(); 112 | JsonObject& record = arrays.createNestedObject(); 113 | //record["id"] = chipIDremote; 114 | record["ip"] = remoteIP; 115 | record["ssdp"] = ssdpName; 116 | addressList = ""; 117 | list.printTo(addressList); 118 | } 119 | 120 | // Каждые 30 секунд проверяем не изиенился ли адрес ip 121 | void ipChanges() { 122 | String ip = WiFi.localIP().toString(); 123 | if (jsonRead(configSetup, "ip") != ip) { 124 | configJson = jsonWrite(configJson, "ip", ip); 125 | configSetup = jsonWrite(configSetup, "ip", ip); 126 | requestSSDP(); 127 | 128 | } 129 | } 130 | 131 | // {"ssdpList":[{"id":"14317906-1458400","ip":"192.168.0.102"},{"id":"16321347-1327328","ip":"192.168.0.108"}]} 132 | 133 | void deviceList() { 134 | HTTP.send(200, "text/plain", "[" + modules + "]"); 135 | } 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /Scenary.ino: -------------------------------------------------------------------------------- 1 | void initScenary() { 2 | loadScenary(); 3 | sCmd.addCommand("if", ifCommand); 4 | sCmd.addCommand("id", idNot); 5 | sCmd.addCommand("then", thenCommand); 6 | HTTP.on("/setscenary", HTTP_GET, []() { 7 | loadScenary(); 8 | HTTP.send(200, "text/plain", "Ok"); 9 | }); 10 | } 11 | 12 | void loadScenary(){ 13 | Scenary = readFile("scenary.save.txt", 4096); 14 | Scenary.replace("\r\n", "\n"); 15 | Scenary.replace("\n\n", "\n"); 16 | Scenary += "\n"; 17 | } 18 | 19 | // Ничего не делать если комманда id 20 | void idNot() {} 21 | 22 | void handleScenary() { 23 | if (flag) { 24 | goCommands(Scenary); 25 | //Serial.println(goCommands(Scenary)); 26 | flag = false; 27 | } 28 | } 29 | 30 | // Разбор команды if 31 | void ifCommand() { 32 | thenOk = false; 33 | String Name = readArgsString(); 34 | String Condition = readArgsString(); 35 | String Volume = readArgsString(); 36 | if (Condition == "=") { 37 | if (Volume == getStatus(Name)) thenOk = true; 38 | } 39 | if (Condition == "<") { 40 | if (Volume > getStatus(Name)) thenOk = true; 41 | } 42 | if (Condition == ">") { 43 | if (Volume < getStatus(Name)) thenOk = true; 44 | } 45 | if (Condition == "<=") { 46 | if (Volume >= getStatus(Name)) thenOk = true; 47 | } 48 | if (Condition == ">=") { 49 | if (Volume <= getStatus(Name)) thenOk = true; 50 | } 51 | if (Condition == "!=") { 52 | if (Volume != getStatus(Name)) thenOk = true; 53 | } 54 | } 55 | // Выполнение then 56 | void thenCommand() { 57 | if (thenOk) { 58 | String ssdp = jsonRead(configSetup, "SSDP"); 59 | String test = readArgsString(); 60 | String comm = readArgsString(); 61 | // Если это локальное устройство 62 | if (ssdp == test ) { 63 | sCmd.readStr(comm); 64 | } 65 | else { 66 | //http://192.168.0.91/cmd?command=relay1 67 | String urls = "http://"; 68 | String ip = jsonRead(ssdpList, test); 69 | urls += ip; 70 | urls += "/cmd?command=" + comm; 71 | if (ip != "") { 72 | //Serial.println(urls); 73 | getURL(urls); 74 | } 75 | 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Timers.ino: -------------------------------------------------------------------------------- 1 | void initTimers() { 2 | HTTP.on("/timerSave", handle_timer_Save); 3 | HTTP.on("/timersDel", handle_timer_Del); 4 | HTTP.on("/timer.modules.json", handle_timer_Mod); 5 | 6 | // задача проверять таймеры каждую секунду. 7 | ts.add(0, 1000, [&](void*) { 8 | runTimers(); 9 | }, nullptr, true); 10 | loadTimer(); 11 | modulesReg("timers"); 12 | } 13 | 14 | void handle_timer_Mod(){ 15 | String responsA = "{\"content\":["; 16 | String responsB ="{}"; 17 | String responsC ="{}"; 18 | 19 | responsC = jsonWrite(responsC, "rgb", "RGB"); 20 | responsC = jsonWrite(responsC, "relay", "Relay"); 21 | responsC = jsonWrite(responsC, "jalousie", "Jalousie"); 22 | 23 | responsB = jsonWrite(responsB, "type", "select"); 24 | responsB = jsonWrite(responsB, "name", "module"); 25 | responsB = jsonWrite(responsB, "response", "[[trigger]]"); 26 | responsB = jsonWrite(responsB, "action", "/trigger.[[module]].json"); 27 | 28 | responsB = selectToMarker (responsB, "}"); 29 | 30 | responsA +=responsB; 31 | responsA += ",\"title\":"; 32 | responsA +=responsC; 33 | responsA += "}]}"; 34 | HTTP.send(200, "application/json", responsA); 35 | } 36 | 37 | 38 | void handle_timer_Save() { 39 | DynamicJsonBuffer jsonBuffer; 40 | JsonObject& Timers = jsonBuffer.parseObject(jsonTimer); 41 | JsonArray& arrays = Timers["timer"].asArray(); 42 | JsonObject& record = arrays.createNestedObject(); 43 | record["id"] = HTTP.arg("id"); 44 | record["trigger"] = HTTP.arg("trigger"); 45 | record["module"] = HTTP.arg("module"); 46 | record["day"] = HTTP.arg("day"); 47 | record["time"] = HTTP.arg("time"); 48 | record["work"] = HTTP.arg("work"); 49 | jsonTimer = ""; 50 | Timers.printTo(jsonTimer); 51 | writeFile("timer.save.json", jsonTimer ); 52 | 53 | loadTimer(); 54 | HTTP.send(200, "text/plain", responsTimer()); 55 | } 56 | 57 | String responsTimer() { 58 | String responsA = "{\"state\": \"timer.save.json\",\"title\":"; 59 | String responsB = "{}"; 60 | responsB = jsonWrite(responsB, "module", ""); 61 | responsB = jsonWrite(responsB, "trigger", "{{LangOn.}}/{{LangOff.}}"); 62 | responsB = jsonWrite(responsB, "day", "{{LangDay}}"); 63 | responsB = jsonWrite(responsB, "time", "{{LangTime4}}"); 64 | responsB = jsonWrite(responsB, "work", "{{LangWorkTime}}"); 65 | responsB = jsonWrite(responsB, "id", "{{LangDel}}"); 66 | return responsA += responsB += "}"; 67 | } 68 | 69 | 70 | void handle_timer_Del() { 71 | DynamicJsonBuffer jsonBuffer; 72 | JsonObject& Timers = jsonBuffer.parseObject(jsonTimer); 73 | JsonArray& nestedArray = Timers["timer"].asArray(); 74 | int y; 75 | for (int i = 0; i <= nestedArray.size() - 1; i++) { 76 | if (Timers["timer"][i]["id"] == HTTP.arg("id").toInt()) y = i; 77 | 78 | } 79 | nestedArray.removeAt(y); 80 | jsonTimer = ""; 81 | Timers.printTo(jsonTimer); 82 | writeFile("timer.save.json", jsonTimer ); 83 | loadTimer(); 84 | HTTP.send(200, "text/plain", responsTimer()); 85 | } 86 | 87 | 88 | bool loadTimer() { 89 | Timerset = ""; 90 | jsonTimer = readFile("timer.save.json", 4096); 91 | String Weekday = GetWeekday(); 92 | configJson = jsonWrite(configJson, "weekday", Weekday); 93 | DynamicJsonBuffer jsonBuffer; 94 | JsonObject& Timers = jsonBuffer.parseObject(jsonTimer); 95 | JsonArray& nestedArray = Timers["timer"].asArray(); 96 | int j = nestedArray.size(); 97 | if (j != 0) { 98 | for (int i = 0; i <= j - 1; i++) { 99 | if ((Weekday == Timers["timer"][i]["day"].as()) || (Timers["timer"][i]["day"].as() == "All")) { 100 | 101 | Timerset += Timers["timer"][i]["time"].as() + ","; 102 | Timerset += Timers["timer"][i]["module"].as() + ","; 103 | Timerset += Timers["timer"][i]["trigger"].as() + ","; 104 | Timerset += Timers["timer"][i]["work"].as() + ","; 105 | Timerset += Timers["timer"][i]["id"].as(); 106 | Timerset += "\r\n"; 107 | } 108 | } 109 | } 110 | //runTimers(); 111 | return true; 112 | } 113 | void runTimers() { 114 | // Список текущих таймеров во временную переменную 115 | String timers = Timerset; 116 | String now = GetTime(); 117 | String Weekday = GetWeekday(); 118 | if (jsonRead(configJson, "weekday") != Weekday) { 119 | configJson = jsonWrite(configJson, "weekday", Weekday); 120 | loadTimer(); 121 | } 122 | configSetup = jsonWrite(configSetup, "time", now); 123 | configJson = jsonWrite(configJson, "time", now); 124 | int i; 125 | // Будем повторять проверку для каждого установленного таймера 126 | do { 127 | // проверяем есть ли таймеры 128 | i = timers.indexOf("\r\n"); 129 | if (i != -1) { 130 | // получаем строку текщего таймера 131 | String timer = timers.substring(0, i); 132 | if (timer.substring(0, 8) == now) { 133 | // Отрезаем время из строки 12:44:15,relay,not,work,id 134 | timer = deleteBeforeDelimiter(timer, ","); 135 | // Выделяем модуль 136 | String module = selectToMarker (timer, ","); 137 | // отрезаем модуль 138 | timer = deleteBeforeDelimiter(timer, ","); 139 | // Выделяем команду 140 | String com = selectToMarker (timer, ","); 141 | // отрезаем команду 142 | timer = deleteBeforeDelimiter(timer, ","); 143 | // Выделяем интервал таймера 144 | String interval = selectToMarker (timer, ","); 145 | // отрезаем интервал 146 | timer = deleteBeforeDelimiter(timer, ","); 147 | // выделяем id таймера 148 | String id = selectToMarker (timer, "\r\n"); 149 | // выполняем необходимое действие 150 | 151 | command = module + com + " " + interval + " " + id; 152 | 153 | } 154 | timers = timers.substring(timers.indexOf("\r\n") + 2); 155 | } 156 | } while (i != -1); 157 | } 158 | 159 | -------------------------------------------------------------------------------- /Upgrade.ino: -------------------------------------------------------------------------------- 1 | void initUpgrade() { 2 | // Добавляем функцию Update для перезаписи прошивки по Wi-Fi при 1М(256K SPIFFS) и выше 3 | httpUpdater.setup(&HTTP); 4 | HTTP.on("/upgrade", webUpgrade); // запустить обнавление 5 | modulesReg("upgrade"); 6 | } 7 | // ----------------------- Обновление с сайта 8 | void webUpgrade() { 9 | String refresh = "Update module..."; 10 | HTTP.send(200, "text/html", refresh); 11 | String spiffsData = HTTP.arg("spiffs"); 12 | if (spiffsData != "") { 13 | SPIFFS.format(); 14 | spiffsData = spiffsData.substring(spiffsData.lastIndexOf("/") + 1); // выделяем имя файла 15 | ESPhttpUpdate.rebootOnUpdate(false); 16 | t_httpUpdate_return ret = ESPhttpUpdate.updateSpiffs(HTTP.arg("spiffs")); 17 | switch(ret) { 18 | case HTTP_UPDATE_FAILED: 19 | configSetup = jsonWrite(configSetup, "spiffsData", "HTTP_UPDATE_FAILED"); 20 | statistics(); 21 | break; 22 | case HTTP_UPDATE_NO_UPDATES: 23 | configSetup = jsonWrite(configSetup, "spiffsData", "HTTP_UPDATE_NO_UPDATES"); 24 | statistics(); 25 | break; 26 | case HTTP_UPDATE_OK: 27 | configSetup = jsonWrite(configSetup, "spiffsData", "HTTP_UPDATE_OK"); 28 | statistics(); 29 | break; 30 | } 31 | writeFile("timer.save.json", jsonTimer); 32 | configSetup = jsonWrite(configSetup, "spiffsData", spiffsData); 33 | saveConfigSetup (); 34 | } 35 | String buildData = HTTP.arg("build"); 36 | if (buildData != "") { 37 | buildData = buildData.substring(buildData.lastIndexOf("/") + 1); // выделяем имя файла 38 | configSetup = jsonWrite(configSetup, "buildData", buildData); 39 | saveConfigSetup (); 40 | ESPhttpUpdate.rebootOnUpdate(true); 41 | t_httpUpdate_return jet = ESPhttpUpdate.update(HTTP.arg("build")); 42 | } 43 | } 44 | 45 | void savePrevious(){ 46 | moveSetup ("lang"); 47 | moveSetup ("setIndex"); 48 | moveSetup ("SSDP"); 49 | moveSetup ("space"); 50 | moveSetup ("ssid"); 51 | moveSetup ("ssidPass"); 52 | moveSetupInt ("wifiConnect"); 53 | moveSetupInt ("wifiBlink"); 54 | moveSetup ("checkboxIP"); 55 | moveSetup ("ip"); 56 | moveSetup ("subnet"); 57 | moveSetup ("getway"); 58 | moveSetup ("dns"); 59 | moveSetupInt ("timeZone"); 60 | moveSetup ("ssidAP"); 61 | moveSetup ("ssidApPass"); 62 | moveSetup ("configs"); 63 | moveSetup ("ddns"); 64 | moveSetup ("ddnsName"); 65 | moveSetupInt ("ddnsPort"); 66 | moveSetup ("mqttServer"); 67 | moveSetupInt ("mqttPort"); 68 | moveSetup ("mqttUser"); 69 | moveSetup ("mqttPass"); 70 | } 71 | 72 | void moveSetup (String Name){ 73 | configSetup = jsonWrite(previousSetup, Name, jsonRead(previousSetup, Name)); 74 | } 75 | 76 | void moveSetupInt (String Name){ 77 | configSetup = jsonWrite(previousSetup, Name, jsonReadtoInt(previousSetup, Name)); 78 | } 79 | -------------------------------------------------------------------------------- /WIFI.ino: -------------------------------------------------------------------------------- 1 | //Подключение к сети в режиме станции при неудачной попытки включим режим точки доступа 2 | /* 1. Проверяем есть ли точка доступа установленная во flash 3 | Если да: 4 | проверяем режим DHCP или Manual IP 5 | Если Manual IP устанавливаем парамерты 6 | Иначе делаем попытку подключения к точке доступа 7 | Точка доступа не доступна Вклчаем режим AP 8 | */ 9 | // ---------------- Инициализация WiFi 10 | void initWIFI() { 11 | HTTP.on("/wifi.scan.json", handle_wifi_scan); // сканирование сети на доступные точки доступа 12 | HTTP.on("/ssid", handle_ssid); // Установить имя и пароль роутера 13 | HTTP.on("/wifi", handle_wifi); // Установить имя и пароль для точки доступа 14 | HTTP.on("/ssidap", handle_ssidap); // Установить имя и пароль для точки доступа 15 | HTTP.on("/restart", handle_restart); // Перезагрузка модуля 16 | HTTP.on("/restartWiFi", RestartWiFi); // Перизапустить wifi попытаться узнать будущий ip адрес перезагрузить устройство 17 | startWIFI(); 18 | } 19 | 20 | void handle_wifi(){ 21 | configSetup = jsonWrite(configSetup, "wifiConnect", HTTP.arg("connect")); 22 | configSetup = jsonWrite(configSetup, "wifiBlink", HTTP.arg("blink")); 23 | HTTP.send(200, "text/plain", "Ok"); 24 | saveConfigSetup(); 25 | } 26 | 27 | // --------------Установить имя и пароль для роутера 28 | void handle_ssid() { 29 | configSetup = jsonWrite(configSetup, "ssid", HTTP.arg("ssid")); 30 | configSetup = jsonWrite(configSetup, "subnet", HTTP.arg("subnet")); 31 | configSetup = jsonWrite(configSetup, "getway", HTTP.arg("getway")); 32 | configSetup = jsonWrite(configSetup, "dns", HTTP.arg("dns")); 33 | configSetup = jsonWrite(configSetup, "ip", HTTP.arg("ip")); 34 | configSetup = jsonWrite(configSetup, "checkboxIP", HTTP.arg("checkboxIP")); 35 | String ssidName = HTTP.arg("ssid"); 36 | String ssidPass = HTTP.arg("ssidPass"); 37 | configSetup = jsonWrite(configSetup, "ssid", ssidName); 38 | configSetup = jsonWrite(configSetup, "ssidPass", ssidPass); 39 | HTTP.send(200, "text/plain", "Ok"); 40 | saveConfigSetup(); 41 | } 42 | 43 | // --------------- Установить имя и пароль для AP 44 | void handle_ssidap() { 45 | configSetup = jsonWrite(configSetup, "ssidAP", HTTP.arg("ssidAP")); 46 | configSetup = jsonWrite(configSetup, "ssidApPass", HTTP.arg("ssidApPass")); 47 | HTTP.send(200, "text/plain", "Ok"); 48 | saveConfigSetup(); 49 | } 50 | 51 | // -------------- Перезагрузка модуля 52 | void handle_restart() { 53 | String restart = HTTP.arg("device"); 54 | if (restart == "ok") { // Если значение равно Ок 55 | HTTP.send(200, "text/plain", "Reset OK"); // Oтправляем ответ Reset OK 56 | ESP.restart(); // перезагружаем модуль 57 | } else { // иначе 58 | HTTP.send(200, "text/plain", "No Reset"); // Oтправляем ответ No Reset 59 | } 60 | } 61 | 62 | //-------------- Перизапустить wifi попытаться узнать будущий ip адрес перезагрузить устройство 63 | bool RestartWiFi() { 64 | //Перезапуск Wi-Fi при первой настройке 65 | Serial.println("WiFi reconnect"); 66 | WiFi.mode(WIFI_AP_STA); 67 | // Не отключаясь от точки доступа подключаемся к роутеру для получения будущего IP 68 | WiFi.begin(jsonRead(configSetup, "ssid").c_str(),jsonRead(configSetup, "ssidPass").c_str()); 69 | 70 | wifiConnect(jsonReadtoInt(configSetup, "wifiConnect"), jsonReadtoInt(configSetup, "wifiBlink")); 71 | 72 | // {"title":"

{{LangConnect2}} http://192.168.1.30

"} 73 | // {"title":"Любой текст и html","class":"класс", "style":"Стиль","state":"Данные для вставки в state input_а"} 74 | String state = "\{\"title\":\"

\{\{LangConnect2\}\} http://" + WiFi.localIP().toString() + "

\"\}"; 75 | HTTP.send(200, "application/json", state); 76 | delay(1000); 77 | // Отключаем точку доступа и переподключаемся к роутеру 78 | ESP.restart(); 79 | } 80 | 81 | //-------------Подключение к роутеру конфигурация в строке json 82 | //{"ip":"192.168.0.190","getway":"192.168.0.1","subnet":"255.255.255.0","dns":"","checkboxIP":0} 83 | boolean startSTA(String configWiFi) { 84 | //WiFi.persistent (false); 85 | if (jsonRead(configWiFi, "checkboxIP") == "1") { 86 | IPAddress staticIP; 87 | IPAddress staticGateway; 88 | IPAddress staticSubnet; 89 | String volume = ""; 90 | boolean check = true; 91 | volume = jsonRead(configWiFi, "ip"); 92 | if (volume != "") { 93 | staticIP.fromString(volume); 94 | check = false; 95 | } 96 | volume = jsonRead(configWiFi, "getway"); 97 | if (volume != "") { 98 | staticGateway.fromString(volume); 99 | check = false; 100 | } 101 | volume = jsonRead(configWiFi, "subnet"); 102 | if (volume != "") { 103 | staticSubnet.fromString(volume); 104 | check = false; 105 | } 106 | if (!check) { 107 | } 108 | } 109 | WiFi.mode(WIFI_OFF); 110 | WiFi.mode(WIFI_STA); 111 | WiFi.hostname ( "sonoff-" + chipID ); 112 | WiFi.begin(); 113 | //WiFi.begin(jsonRead(configJson, "ssid").c_str(),jsonRead(configJson, "ssidPass").c_str()); 114 | if ( wifiConnect(jsonReadtoInt(configSetup, "wifiConnect"), jsonReadtoInt(configSetup, "wifiBlink"))) { 115 | WiFi.setAutoConnect(true); 116 | WiFi.setAutoReconnect(true); 117 | configSetup = jsonWrite(configSetup, "ip", WiFi.localIP().toString()); 118 | configSetup = jsonWrite(configSetup, "getway", WiFi.gatewayIP().toString()); 119 | configSetup = jsonWrite(configSetup, "subnet", WiFi.subnetMask().toString()); 120 | statistics(); 121 | return true; 122 | } 123 | return false; 124 | } 125 | // --------------Проверять на подключение к роутеру tries раз. Отображать подключение на ноге pin 126 | boolean wifiConnect(byte tries, byte pin) { 127 | if (tries == 0) tries = 11; 128 | if ((pin > 5 && pin < 12) || pin > 16) pin = 0 ; 129 | if (pin != 0) pinMode(pin, OUTPUT); 130 | while (--tries && WiFi.status() != WL_CONNECTED) 131 | { 132 | //Мигаем сетодиодом при попытке подключится к роутеру 133 | if (pin != 0) digitalWrite(pin, HIGH); 134 | delay(500); 135 | if (pin != 0) digitalWrite(pin, LOW); 136 | delay(500); 137 | } 138 | if (WiFi.status() == WL_CONNECTED)return true; 139 | return false; 140 | } 141 | 142 | //-------------Включение режима AP конфигурация в строке json 143 | //{"ssidAP":"Sonoff","ssidApPass":""} 144 | boolean startAP(String configWiFi) { 145 | IPAddress apIP(192, 168, 4, 1); 146 | IPAddress staticGateway(192, 168, 4, 1); 147 | IPAddress staticSubnet(255, 255, 255, 0); 148 | WiFi.softAPConfig(apIP, staticGateway, staticSubnet); 149 | WiFi.softAP(jsonRead(configWiFi, "ssidAP").c_str(), jsonRead(configWiFi, "ssidApPass").c_str()); 150 | WiFi.mode(WIFI_AP); 151 | dnsServer.start(53, "*", apIP); 152 | //Зажигаем светодиод если находимся в режиме AP 153 | int pin = jsonReadtoInt(configWiFi, "blink"); 154 | if ((pin > 5 && pin < 12) || pin > 16) pin = 0 ; 155 | if (pin != 0) { 156 | pinMode(pin, OUTPUT); 157 | digitalWrite(pin, HIGH); 158 | } 159 | return true; 160 | } 161 | 162 | // ---------------- сканирование сети на доступные точки доступа 163 | void handle_wifi_scan() { 164 | int n = WiFi.scanNetworks(); 165 | DynamicJsonBuffer jsonBuffer; 166 | JsonObject& json = jsonBuffer.createObject(); 167 | JsonArray& networks = json.createNestedArray("networks"); 168 | for (int i = 0; i < n; i++) { 169 | JsonObject& data = networks.createNestedObject(); 170 | data["ssid"] = WiFi.SSID(i); 171 | data["pass"] = (WiFi.encryptionType(i) == ENC_TYPE_NONE) ? "" : "*"; 172 | data["dbm"] = WiFi.RSSI(i); 173 | } 174 | String root; 175 | json.printTo(root); 176 | HTTP.send(200, "application/json", root); 177 | } 178 | 179 | 180 | // ----------------- Запускаем WiFi 181 | void startWIFI() { 182 | if (startSTA(configSetup)) { 183 | } 184 | else { 185 | startAP(configSetup); 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /WS2811.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Модуль использует библиотеки 3 | #include //https://github.com/adafruit/Adafruit_NeoPixel 4 | #include //https://github.com/MTJoker/WS2812FX 5 | Объект должен быть определен в начале скетча 6 | WS2812FX ws2812fx = WS2812FX(); 7 | В Loop обработчик 8 | ws2812fx.service(); 9 | */ 10 | 11 | void initRGB() { 12 | sendStatus("colorRGB", "ff6600"); 13 | sendStatus("speedRGB", 100); 14 | sendStatus("brightnessRGB", 255); 15 | sendStatus("modeRGB", 0); 16 | sendStatus("timeRGB", 0); 17 | sendStatus("timeBUZ", 0); 18 | // Настраивается по запросу /set? 19 | HTTP.on("/set", handle_RGB); 20 | HTTP.on("/rgb", LedRGB); 21 | HTTPWAN.on("/set", handle_RGB); 22 | HTTPWAN.on("/rgb", LedRGB); 23 | 24 | // Реагирует на комманду rgbnot 25 | sCmd.addCommand("rgbnot", rgbNot); 26 | sCmd.addCommand("rgbon", rgbOn); 27 | sCmd.addCommand("rgboff", rgbOff); 28 | commandsReg("rgbon","rgb"); 29 | commandsReg("rgboff","rgb"); 30 | commandsReg("rgbnot","rgb"); 31 | byte pin = readArgsInt(); 32 | if (pin == 1 || pin == 3) Serial.end(); 33 | ws2812fx.setPin(pin); 34 | ws2812fx.updateLength(readArgsInt()); 35 | ws2812fx.init(); 36 | ws2812fx.setMode(getStatusInt("modeRGB")); // Режим 37 | // Начальный цвет 38 | uint32_t tmp = strtol(("0x" + jsonRead(configJson, "colorRGB")).c_str(), NULL, 0); 39 | if (tmp >= 0x000000 && tmp <= 0xFFFFFF) { 40 | ws2812fx.setColor(tmp); 41 | } 42 | ws2812fx.setSpeed(getStatusInt("speedRGB")); // Скорость 43 | ws2812fx.setBrightness(getStatusInt("brightnessRGB")); //Яркость 44 | //регистрируем модуль 45 | int state = readArgsInt(); 46 | sendStatus("stateRGB", state); 47 | if (state) {command = "rgbon";} 48 | modulesReg("rgb"); 49 | } 50 | 51 | //void handle_RGB() {} 52 | 53 | // ----------------Задать режимы ленты 54 | void handle_RGB() { 55 | //Получаем цвет 56 | String colorRGB = HTTP.arg("c"); 57 | if (colorRGB != "") { 58 | flag = sendStatus("colorRGB", colorRGB); 59 | uint32_t tmp = strtol(("0x" + colorRGB).c_str(), NULL, 0); 60 | if (tmp >= 0x000000 && tmp <= 0xFFFFFF) { 61 | ws2812fx.setColor(tmp); 62 | } 63 | } 64 | //Получаем скорость 65 | String speedRGB = HTTP.arg("s"); 66 | if (speedRGB != "") { 67 | flag = sendStatus("speedRGB", speedRGB.toInt()); 68 | ws2812fx.setSpeed(speedRGB.toInt()); 69 | } 70 | //Получаем яркость 71 | String brightnessRGB = HTTP.arg("b"); 72 | if (brightnessRGB != "") { 73 | flag = sendStatus("brightnessRGB", brightnessRGB.toInt()); 74 | ws2812fx.setBrightness(brightnessRGB.toInt()); 75 | 76 | } 77 | //Получаем режим 78 | String modeRGB = HTTP.arg("m"); 79 | if (modeRGB != "") { 80 | flag = sendStatus("modeRGB", modeRGB.toInt()); 81 | ws2812fx.setMode(modeRGB.toInt() % ws2812fx.getModeCount()); 82 | } 83 | //Получаем время таймера 84 | String timeRGB = HTTP.arg("time"); 85 | if (timeRGB != "") { 86 | flag = sendStatus("timeRGB", timeRGB.toInt()); 87 | } 88 | //Получаем время сигнала 89 | String timeBUZ = HTTP.arg("s"); 90 | if (timeBUZ != "") { 91 | flag = sendStatus("timeBUZ", timeBUZ.toInt()); 92 | } 93 | command = "rgbon"; 94 | String state = "{}"; 95 | state = jsonWrite(state, "title", "{{LangOff}}"); 96 | state = jsonWrite(state, "class", "btn btn-block btn-lg btn-info"); 97 | HTTP.send(200, "text/plain", state); 98 | } 99 | 100 | void rgbNot() { 101 | flag = sendStatus("stateRGB", !getStatusInt("stateRGB")); 102 | if (!getStatusInt("stateRGB")){ 103 | ws2812fx.stop(); 104 | } 105 | else{ 106 | ws2812fx.stop(); 107 | ws2812fx.start(); 108 | } 109 | topicPub("/RGB_not/status", String(getStatusInt("stateRGB")), 1 ); 110 | } 111 | 112 | void rgbOn() { 113 | 114 | if (!getStatusInt("stateRGB")) { 115 | configJson = jsonWrite(configJson, "stateRGB", 1); 116 | flag = sendStatus("stateRGB", 1); 117 | ws2812fx.start(); 118 | } 119 | 120 | } 121 | 122 | void rgbOff() { 123 | 124 | if (getStatusInt("stateRGB")) { 125 | configJson = jsonWrite(configJson, "stateRGB", 1); 126 | flag = sendStatus("stateRGB", 0); 127 | ws2812fx.stop(); 128 | } 129 | 130 | } 131 | 132 | void LedRGB() { 133 | command = "rgbnot"; 134 | String state = "{}"; 135 | if (getStatusInt("stateRGB")) { 136 | state = jsonWrite(state, "title", "{{LangOn}}"); 137 | state = jsonWrite(state, "class", "btn btn-block btn-lg btn-primary"); 138 | } 139 | else { 140 | state = jsonWrite(state, "title", "{{LangOff}}"); 141 | state = jsonWrite(state, "class", "btn btn-block btn-lg btn-info"); 142 | } 143 | HTTP.send(200, "text/plain", state); 144 | } 145 | -------------------------------------------------------------------------------- /Web.ino: -------------------------------------------------------------------------------- 1 | // ---------------------Инициализация Web сервера и сервисных функций 2 | void initHTTP(void) { 3 | // Кэшировать файлы для быстрой работы 4 | HTTP.serveStatic("/css/", SPIFFS, "/css/", "max-age=31536000"); // кеширование на 1 год 5 | HTTP.serveStatic("/js/", SPIFFS, "/js/", "max-age=31536000"); // кеширование на 1 год 6 | HTTP.serveStatic("/img/", SPIFFS, "/img/", "max-age=31536000"); // кеширование на 1 год 7 | //HTTP.serveStatic("/lang/", SPIFFS, "/lang/", "max-age=31536000"); // кеширование на 1 год 8 | 9 | // --------------------Выдаем данные configOptions 10 | HTTP.on("/config.options.json", HTTP_GET, []() { 11 | HTTP.send(200, "application/json", configOptions); 12 | }); 13 | 14 | // --------------------Выдаем данные configJson 15 | HTTP.on("/config.live.json", HTTP_GET, []() { 16 | HTTP.send(200, "application/json", configJson); 17 | }); 18 | 19 | // -------------------Выдаем данные configSetup 20 | HTTP.on("/config.setup.json", HTTP_GET, []() { 21 | HTTP.send(200, "application/json", configSetup); 22 | }); 23 | // -------------------Выдаем данные regCommands 24 | HTTP.on("/command.json", HTTP_GET, []() { 25 | HTTP.send(200, "application/json", regCommands); 26 | }); 27 | 28 | // --------------------Узнать какие модули есть в устройстве 29 | HTTP.on("/modules.json", HTTP_GET, []() { 30 | HTTP.send(200, "application/json", modules); 31 | }); 32 | 33 | // -------------------Установка конфигурации 34 | HTTP.on("/configs", HTTP_GET, []() { 35 | String set = HTTP.arg("set"); 36 | configSetup = jsonWrite(configSetup, "configs", set); 37 | saveConfigSetup(); 38 | String reqvest = "{\"action\": \"page.htm?configs&" + set + "\"}"; 39 | HTTP.send(200, "text/plain", reqvest); 40 | }); 41 | 42 | // ------------------Выполнение команды из запроса 43 | HTTP.on("/cmd", HTTP_GET, []() { 44 | command = HTTP.arg("command"); 45 | HTTP.send(200, "text/plain", command); 46 | }); 47 | 48 | HTTP.on("/lang", HTTP_GET, []() { 49 | configSetup = jsonWrite(configSetup, "lang", HTTP.arg("set")); 50 | configOptions = jsonWrite(configOptions, "lang", HTTP.arg("set")); 51 | saveConfigSetup(); 52 | HTTP.send(200, "text/plain", "OK"); 53 | }); 54 | 55 | //Запускаем HTTP сервер 56 | HTTP.begin(); 57 | } 58 | -------------------------------------------------------------------------------- /build/2016/build.0x00000_flash_size_1Mb.256Kb_2016.12.08.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2016/build.0x00000_flash_size_1Mb.256Kb_2016.12.08.bin -------------------------------------------------------------------------------- /build/2016/build.0x00000_flash_size_1Mb.256Kb_2016.12.11.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2016/build.0x00000_flash_size_1Mb.256Kb_2016.12.11.bin -------------------------------------------------------------------------------- /build/2016/build.0x00000_flash_size_1Mb.256Kb_2016.12.14.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2016/build.0x00000_flash_size_1Mb.256Kb_2016.12.14.bin -------------------------------------------------------------------------------- /build/2016/build.0x00000_flash_size_1Mb.256Kb_2016.12.15.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2016/build.0x00000_flash_size_1Mb.256Kb_2016.12.15.bin -------------------------------------------------------------------------------- /build/2016/build.0x00000_flash_size_1Mb.256Kb_2016.12.16.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2016/build.0x00000_flash_size_1Mb.256Kb_2016.12.16.bin -------------------------------------------------------------------------------- /build/2016/build.0x00000_flash_size_1Mb.256Kb_2016.12.19.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2016/build.0x00000_flash_size_1Mb.256Kb_2016.12.19.bin -------------------------------------------------------------------------------- /build/2016/spiffs.0xBB000_flash_size_1Mb.256Kb_2016.12.14.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2016/spiffs.0xBB000_flash_size_1Mb.256Kb_2016.12.14.bin -------------------------------------------------------------------------------- /build/2016/spiffs.0xBB000_flash_size_1Mb.257Kb_2016.12.16.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2016/spiffs.0xBB000_flash_size_1Mb.257Kb_2016.12.16.bin -------------------------------------------------------------------------------- /build/2016/spiffs.0xBB000_flash_size_1Mb.257Kb_2016.12.19.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2016/spiffs.0xBB000_flash_size_1Mb.257Kb_2016.12.19.bin -------------------------------------------------------------------------------- /build/2017 old/README.md: -------------------------------------------------------------------------------- 1 | #Specification .bin files 2 | - Module: Generic ESP8266 Module 3 | - Flash Size: 1M(256K SPIFFS) 4 | - CPU Frequency: 80Mhz 5 | - Flash Mode: dio 6 | - Flash Frequency: 40Mhz 7 | - Upload Speed: 115200 8 | 9 | 10 | ##NodeMCU Flasher 11 | [https://github.com/nodemcu/nodemcu-flasher](https://github.com/nodemcu/nodemcu-flasher) 12 | 13 | Download Release: [Win32](https://github.com/nodemcu/nodemcu-flasher/blob/master/Win32/Release/ESP8266Flasher.exe) or 14 | [Win64](https://github.com/nodemcu/nodemcu-flasher/blob/master/Win64/Release/ESP8266Flasher.exe). 15 | 16 | ###Usage 17 | 18 | ![alt](https://raw.githubusercontent.com/tretyakovsa/Sonoff_WiFi_switch/master/tutorial/nodemcu-flasher.png) 19 | 20 | 21 | ![alt](https://raw.githubusercontent.com/tretyakovsa/Sonoff_WiFi_switch/master/tutorial/esp8266_wiring.png) 22 | 23 | 24 | ##Web Upgrade (Youtube) 25 | [![IMAGE ALT TEXT HERE](https://img.youtube.com/vi/t0jJxRcIoSU/0.jpg)](https://www.youtube.com/watch?v=t0jJxRcIoSU&list=PL6NJTNxbvy-IPTDQk8XjTV41oRrFafrRi) 26 | -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.01.09.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.01.09.bin -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.02.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.02.bin -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.04.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.04.bin -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.06.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.06.bin -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.08.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.08.bin -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.09.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.09.bin -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.18.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.18.bin -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.20.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.20.bin -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.21.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.21.bin -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.23.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.23.bin -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.24.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.24.bin -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.25.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.02.25.bin -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.03.03.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.03.03.bin -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.03.09.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.03.09.bin -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.03.11.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.03.11.bin -------------------------------------------------------------------------------- /build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.03.30.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/build.0x00000_flash_size_1Mb.256Kb_2017.03.30.bin -------------------------------------------------------------------------------- /build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.01.09.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.01.09.bin -------------------------------------------------------------------------------- /build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.02.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.02.bin -------------------------------------------------------------------------------- /build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.04.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.04.bin -------------------------------------------------------------------------------- /build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.06.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.06.bin -------------------------------------------------------------------------------- /build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.09.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.09.bin -------------------------------------------------------------------------------- /build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.18.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.18.bin -------------------------------------------------------------------------------- /build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.20.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.20.bin -------------------------------------------------------------------------------- /build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.23.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.02.23.bin -------------------------------------------------------------------------------- /build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.03.03.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.03.03.bin -------------------------------------------------------------------------------- /build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.03.11.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.03.11.bin -------------------------------------------------------------------------------- /build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.03.30.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/2017 old/spiffs.0xBB000_flash_size_1Mb.257Kb_2017.03.30.bin -------------------------------------------------------------------------------- /build/README.md: -------------------------------------------------------------------------------- 1 | # Specification .bin files 2 | 3 | - Module: Generic ESP8266 Module 4 | - Flash Size: 1M(256K SPIFFS) 5 | - CPU Frequency: 80Mhz 6 | - Flash Mode: dio 7 | - Flash Frequency: 40Mhz 8 | - Upload Speed: 115200 9 | 10 | 11 | ## NodeMCU Flasher 12 | 13 | [https://github.com/nodemcu/nodemcu-flasher](https://github.com/nodemcu/nodemcu-flasher) 14 | 15 | Download Release: [Win32](https://github.com/nodemcu/nodemcu-flasher/blob/master/Win32/Release/ESP8266Flasher.exe) or 16 | [Win64](https://github.com/nodemcu/nodemcu-flasher/blob/master/Win64/Release/ESP8266Flasher.exe). 17 | 18 | ### Usage 19 | 20 | ![alt](https://raw.githubusercontent.com/tretyakovsa/Sonoff_WiFi_switch/master/tutorial/nodemcu-flasher.png) 21 | 22 | 23 | ![alt](https://raw.githubusercontent.com/tretyakovsa/Sonoff_WiFi_switch/master/tutorial/esp8266_wiring.png) 24 | -------------------------------------------------------------------------------- /build/build.0x00000_flash_size_1Mb.256Kb_2017.06.07.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/build.0x00000_flash_size_1Mb.256Kb_2017.06.07.bin -------------------------------------------------------------------------------- /build/build.0x00000_flash_size_1Mb.256Kb_2017.06.08.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/build.0x00000_flash_size_1Mb.256Kb_2017.06.08.bin -------------------------------------------------------------------------------- /build/build.0x00000_flash_size_1Mb.256Kb_2017.06.12.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/build.0x00000_flash_size_1Mb.256Kb_2017.06.12.bin -------------------------------------------------------------------------------- /build/build.0x00000_flash_size_1Mb.256Kb_2017.06.17.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/build.0x00000_flash_size_1Mb.256Kb_2017.06.17.bin -------------------------------------------------------------------------------- /build/build.0x00000_flash_size_1Mb.256Kb_2017.06.21.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/build.0x00000_flash_size_1Mb.256Kb_2017.06.21.bin -------------------------------------------------------------------------------- /build/build.0x00000_flash_size_1Mb.256Kb_2017.07.21.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/build.0x00000_flash_size_1Mb.256Kb_2017.07.21.bin -------------------------------------------------------------------------------- /build/build.0x00000_flash_size_1Mb.256Kb_2017.07.24.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/build.0x00000_flash_size_1Mb.256Kb_2017.07.24.bin -------------------------------------------------------------------------------- /build/build.0x00000_flash_size_1Mb.256Kb_2017.09.11.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/build.0x00000_flash_size_1Mb.256Kb_2017.09.11.bin -------------------------------------------------------------------------------- /build/build.0x00000_flash_size_1Mb.256Kb_2017.10.11.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/build.0x00000_flash_size_1Mb.256Kb_2017.10.11.bin -------------------------------------------------------------------------------- /build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.06.07.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.06.07.bin -------------------------------------------------------------------------------- /build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.06.08.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.06.08.bin -------------------------------------------------------------------------------- /build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.06.12.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.06.12.bin -------------------------------------------------------------------------------- /build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.06.17.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.06.17.bin -------------------------------------------------------------------------------- /build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.06.21.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.06.21.bin -------------------------------------------------------------------------------- /build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.07.21.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.07.21.bin -------------------------------------------------------------------------------- /build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.07.24.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.07.24.bin -------------------------------------------------------------------------------- /build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.09.11.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.09.11.bin -------------------------------------------------------------------------------- /build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.10.11.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.10.11.bin -------------------------------------------------------------------------------- /data/block-analog.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/block-analog.htm.gz -------------------------------------------------------------------------------- /data/block-humidity.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/block-humidity.htm.gz -------------------------------------------------------------------------------- /data/block-jalousie.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/block-jalousie.htm.gz -------------------------------------------------------------------------------- /data/block-leakag.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/block-leakag.htm.gz -------------------------------------------------------------------------------- /data/block-relay.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/block-relay.htm.gz -------------------------------------------------------------------------------- /data/block-rgb.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/block-rgb.htm.gz -------------------------------------------------------------------------------- /data/block-temperature.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/block-temperature.htm.gz -------------------------------------------------------------------------------- /data/chart.json: -------------------------------------------------------------------------------- 1 | { 2 | "configs":[ 3 | "/config.live.json", 4 | "/config.options.json", 5 | "/lang/lang.{{lang}}.json", 6 | "/modules.json" 7 | ], 8 | "title":"{{LangChart}}", 9 | "class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6", 10 | "content":[ 11 | { 12 | "type":"h5", 13 | "title":"{{SSDP}}", 14 | "class":"alert-default" 15 | }, 16 | { 17 | "type":"select", 18 | "state":"{{lang}}", 19 | "name":"languages", 20 | "action":"/lang?set=[[languages]]", 21 | "response":"page.htm?{{urlArray0}}", 22 | "style":"margin-top:-47px;float:right;width:70px", 23 | "title":{"ru":"RU","en":"EN","lv":"LV","ua":"UA"} 24 | }, 25 | 26 | 27 | { 28 | "type":"link", 29 | "title":"{{LangDevices}}", 30 | "action":"/", 31 | "class":"btn btn-block btn-danger" 32 | }, 33 | { 34 | "type":"link", 35 | "title":"{{LangOptions1}} RGB", 36 | "module":"rgb", 37 | "action":"/page.htm?rgb", 38 | "class":"btn btn-block btn-default" 39 | }, 40 | { 41 | "type":"link", 42 | "title":"{{LangOptions1}} Relay", 43 | "module":"relay", 44 | "action":"/page.htm?relay", 45 | "class":"btn btn-block btn-default" 46 | }, 47 | { 48 | "type":"link", 49 | "title":"{{LangOptions1}} Jalousie", 50 | "module":"jalousie", 51 | "action":"/page.htm?jalousie", 52 | "class":"btn btn-block btn-default" 53 | }, 54 | { 55 | "type":"link", 56 | "title":" {{LangSetting3}}", 57 | "action":"/page.htm?setup", 58 | "class":"btn btn-block btn-default" 59 | }, 60 | 61 | { 62 | "type":"hr" 63 | }, 64 | 65 | { 66 | "type":"chart", 67 | "title":"{{LangChart}}", 68 | "state":"{{urlArray1}}.json", 69 | "style":"height:400px;margin-left:-20px" 70 | }, 71 | 72 | 73 | { 74 | "type":"link", 75 | "title":" {{LangSetting3}}", 76 | "action":"/page.htm?setup", 77 | "class":"btn btn-block btn-default" 78 | } 79 | 80 | ] 81 | } 82 | -------------------------------------------------------------------------------- /data/config.save.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "ru", 3 | "setIndex": "", 4 | "SSDP": "Sonoff", 5 | "space": "home", 6 | "ssid": "home", 7 | "ssidPass": "i12345678", 8 | "wifiConnect": 30, 9 | "wifiBlink": 13, 10 | "checkboxIP": "0", 11 | "ip": "", 12 | "subnet": "", 13 | "getway": "", 14 | "dns": "", 15 | "timeZone": 8, 16 | "ssidAP": "Sonoff-Start", 17 | "ssidApPass": "", 18 | "configs": "sonoff-rf", 19 | "ddns": "", 20 | "ddnsName": "", 21 | "ddnsPort": 8080, 22 | "mqttServer": "", 23 | "mqttPort": 15535, 24 | "mqttUser": "", 25 | "mqttPass": "", 26 | "time": "00:00:00" 27 | } 28 | -------------------------------------------------------------------------------- /data/config.widgets.json: -------------------------------------------------------------------------------- 1 | { 2 | "nWidgets": [ 3 | { 4 | "id": 0, 5 | "page": "buttons", 6 | "descr": "Toggle", 7 | "widget": "toggle", 8 | "color": "green", 9 | "topic": "/RELE_1_not" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /data/config.widgets1.json: -------------------------------------------------------------------------------- 1 | { 2 | "nWidgets": [ 3 | { 4 | "id": 0, 5 | "page": "buttons", 6 | "descr": "Toggle", 7 | "widget": "toggle", 8 | "color": "green", 9 | "topic": "/RELE_1_not" 10 | }, 11 | { 12 | "id": "1", 13 | "page": "grafics", 14 | "descr": "Steel 1", 15 | "widget": "steel", 16 | "topic": "/steel1", 17 | "widgetConfig": { 18 | "width": "auto", 19 | "height": 100, 20 | "type": "Linear", 21 | "titleString": "Thermometer 2", 22 | "unitString": "temp C", 23 | "threshold": 40 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /data/configs.json: -------------------------------------------------------------------------------- 1 | { 2 | "configs": [ 3 | "/config.setup.json", 4 | "/lang/lang.{{lang}}.json", 5 | "/modules.json" 6 | ], 7 | "title": "Configs", 8 | "class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6", 9 | "content": [ 10 | { 11 | "type": "h5", 12 | "title": "{{SSDP}}", 13 | "class":"alert-default" 14 | }, 15 | { 16 | "type": "select", 17 | "state": "{{lang}}", 18 | "name":"languages", 19 | "action": "/lang?set=[[languages]]", 20 | "response":"page.htm?{{urlArray0}}", 21 | "style": "margin-top:-47px;float:right;width:70px", 22 | "title": {"ru":"RU","en":"EN","lv":"LV","ua":"UA"} 23 | }, 24 | 25 | 26 | { 27 | "type": "link", 28 | "title": "{{LangDevices}}", 29 | "action": "/", 30 | "class": "btn btn-block btn-danger" 31 | }, 32 | { 33 | "type": "link", 34 | "title": "{{LangOptions1}} RGB", 35 | "module": "rgb", 36 | "action": "/page.htm?rgb", 37 | "class": "btn btn-block btn-default" 38 | }, 39 | { 40 | "type": "link", 41 | "title": "{{LangOptions1}} Relay", 42 | "module": "relay", 43 | "action": "/page.htm?relay", 44 | "class": "btn btn-block btn-default" 45 | }, 46 | { 47 | "type": "link", 48 | "title": "{{LangOptions1}} Jalousie", 49 | "module": "jalousie", 50 | "action": "/page.htm?jalousie", 51 | "class": "btn btn-block btn-default" 52 | }, 53 | { 54 | "type": "link", 55 | "title": " {{LangSetting3}}", 56 | "action": "/page.htm?setup", 57 | "class": "btn btn-block btn-default" 58 | }, 59 | 60 | { 61 | "type": "hr" 62 | }, 63 | 64 | 65 | { 66 | "type": "h2", 67 | "title": "{{LangType}} {{configs}}" 68 | }, 69 | { 70 | "type": "configs", 71 | "state": "{{urlArray1}}.txt" 72 | }, 73 | 74 | { 75 | "type": "hr" 76 | }, 77 | { 78 | "type": "link", 79 | "title": " {{LangSetting3}}", 80 | "action": "/page.htm?setup", 81 | "class": "btn btn-block btn-default" 82 | }, 83 | { 84 | "type": "link", 85 | "title": "{{LangReset1}}", 86 | "action": "javascript:if(confirm(renameBlock(jsonResponse,'{{LangReset3}}'))){send_request(this,'/restart?device=ok');}", 87 | "class": "btn btn-block btn-warning" 88 | } 89 | 90 | ] 91 | } 92 | -------------------------------------------------------------------------------- /data/configs/jalousie.txt: -------------------------------------------------------------------------------- 1 | // Включаем время из сети 2 | NTP 3 | // Доступ по DDNS 4 | DDNS 5 | // Для управления IoT Manager 6 | MQTT 7 | // Если требуются таймеры 8 | TIMERS 9 | // Датчики температуры и влажности DHT11, DHT22, AM2302, RHT03 10 | DHT 14 11 | // Пока только один датчик и пин менять нельзя 12 | D18B20 14 13 | // Аналоговый вход 14 | A0 15 | // Кнопка на GPIO0, доступно: rgbnot relaynot jalousienot 16 | Tach jalousienot 17 | // Первая ячейка - PIN, вторая - состояние реле при включение ESP 18 | # RELAY 12 0 19 | // WS2811/WS2812/NeoPixel LEDs. Первая ячейка - пин led ленты, вторая - количество лед, терья - состояние LED при включение ESP 20 | # RGB 2 15 0 21 | // Первая ячейка - счетчик оборотов, вторая и третья - управление мотором 22 | JALOUSIE 4 12 13 23 | // В стадии разработки, пока не работает 24 | # RGBSHIM 2 4 5 25 | // Сенсор движения, доступно: relay rgb jalousie 26 | # MOTION 4 jalousie 27 | // Беспроводной приемник mHz частот 28 | # RF-RECEIVED 3 433 29 | // Беспроводной передатчик mHz частот, скоро. 30 | # RF-TRANSMITTER 1 433 -------------------------------------------------------------------------------- /data/configs/leakag.txt: -------------------------------------------------------------------------------- 1 | // Включаем время из сети 2 | NTP 3 | // Доступ по DDNS 4 | DDNS 5 | // Для управления IoT Manager 6 | MQTT 7 | // Если требуются таймеры 8 | TIMERS 9 | // Датчики температуры и влажности DHT11, DHT22, AM2302, RHT03 10 | DHT 14 11 | // Пока только один датчик и пин менять нельзя 12 | D18B20 14 13 | // Аналоговый вход 14 | A0 15 | // Кнопка на GPIO0, доступно: rgbnot relaynot jalousienot 16 | Tach relaynot 17 | // Первая ячейка - PIN, вторая - состояние реле при включение ESP 18 | RELAY 12 0 19 | // WS2811/WS2812/NeoPixel LEDs. Первая ячейка - пин led ленты, вторая - количество лед, терья - состояние LED при включение ESP 20 | # RGB 2 15 0 21 | // Первая ячейка - счетчик оборотов, вторая и третья - управление мотором 22 | # JALOUSIE 4 12 13 23 | // В стадии разработки, пока не работает 24 | # RGBSHIM 2 4 5 25 | // Сенсор движения, доступно: relay rgb jalousie 26 | # MOTION 4 rgb 27 | // Беспроводной приемник mHz частот 28 | # RF-RECEIVED 3 433 29 | // Беспроводной передатчик mHz частот, скоро. 30 | # RF-TRANSMITTER 1 433 -------------------------------------------------------------------------------- /data/configs/manually.txt: -------------------------------------------------------------------------------- 1 | // Включаем время из сети 2 | NTP 3 | // Доступ по DDNS 4 | DDNS 5 | // Для управления IoT Manager 6 | MQTT 7 | // Если требуются таймеры 8 | TIMERS 9 | // Датчики температуры и влажности DHT11, DHT22, AM2302, RHT03 10 | DHT 14 11 | // Пока только один датчик и пин менять нельзя 12 | D18B20 14 13 | // Аналоговый вход 14 | A0 15 | // Кнопка на GPIO0, доступно: rgbnot relaynot jalousienot 16 | Tach relaynot 17 | // Первая ячейка - PIN, вторая - состояние реле при включение ESP 18 | RELAY 12 0 19 | // WS2811/WS2812/NeoPixel LEDs. Первая ячейка - пин led ленты, вторая - количество лед, терья - состояние LED при включение ESP 20 | RGB 2 15 0 21 | // Первая ячейка - счетчик оборотов, вторая и третья - управление мотором 22 | # JALOUSIE 4 12 13 23 | // В стадии разработки, пока не работает 24 | # RGBSHIM 2 4 5 25 | // Сенсор движения, доступно: relay rgb jalousie 26 | # MOTION 4 rgb 27 | // Беспроводной приемник mHz частот 28 | # RF-RECEIVED 3 433 29 | // Беспроводной передатчик mHz частот, скоро. 30 | # RF-TRANSMITTER 1 433 -------------------------------------------------------------------------------- /data/configs/rgb-shim.txt: -------------------------------------------------------------------------------- 1 | // Включаем время из сети 2 | NTP 3 | // Доступ по DDNS 4 | DDNS 5 | // Для управления IoT Manager 6 | MQTT 7 | // Если требуются таймеры 8 | TIMERS 9 | // Датчики температуры и влажности DHT11, DHT22, AM2302, RHT03 10 | DHT 14 11 | // Пока только один датчик и пин менять нельзя 12 | D18B20 14 13 | // Аналоговый вход 14 | A0 15 | // Кнопка на GPIO0, доступно: rgbnot relaynot jalousienot 16 | Tach rgbnot 17 | // Первая ячейка - PIN, вторая - состояние реле при включение ESP 18 | # RELAY 12 0 19 | // WS2811/WS2812/NeoPixel LEDs. Первая ячейка - пин led ленты, вторая - количество лед, терья - состояние LED при включение ESP 20 | # RGB 2 15 0 21 | // Первая ячейка - счетчик оборотов, вторая и третья - управление мотором 22 | # JALOUSIE 4 12 13 23 | // В стадии разработки, пока не работает 24 | RGBSHIM 2 4 5 25 | // Сенсор движения, доступно: relay rgb jalousie 26 | # MOTION 4 rgb 27 | // Беспроводной приемник mHz частот 28 | # RF-RECEIVED 3 433 29 | // Беспроводной передатчик mHz частот, скоро. 30 | # RF-TRANSMITTER 1 433 -------------------------------------------------------------------------------- /data/configs/rgb.txt: -------------------------------------------------------------------------------- 1 | // Включаем время из сети 2 | NTP 3 | // Доступ по DDNS 4 | DDNS 5 | // Для управления IoT Manager 6 | MQTT 7 | // Если требуются таймеры 8 | TIMERS 9 | // Датчики температуры и влажности DHT11, DHT22, AM2302, RHT03 10 | DHT 14 11 | // Пока только один датчик и пин менять нельзя 12 | D18B20 14 13 | // Аналоговый вход 14 | A0 15 | // Кнопка на GPIO0, доступно: rgbnot relaynot jalousienot 16 | Tach rgbnot 17 | // Первая ячейка - PIN, вторая - состояние реле при включение ESP 18 | # RELAY 12 0 19 | // WS2811/WS2812/NeoPixel LEDs. Первая ячейка - пин led ленты, вторая - количество лед, терья - состояние LED при включение ESP 20 | RGB 2 15 0 21 | // Первая ячейка - счетчик оборотов, вторая и третья - управление мотором 22 | # JALOUSIE 4 12 13 23 | // В стадии разработки, пока не работает 24 | # RGBSHIM 2 4 5 25 | // Сенсор движения, доступно: relay rgb jalousie 26 | # MOTION 4 rgb 27 | // Беспроводной приемник mHz частот 28 | # RF-RECEIVED 3 433 29 | // Беспроводной передатчик mHz частот, скоро. 30 | # RF-TRANSMITTER 1 433 -------------------------------------------------------------------------------- /data/configs/smart-room.txt: -------------------------------------------------------------------------------- 1 | // Включаем время из сети 2 | NTP 3 | // Доступ по DDNS 4 | DDNS 5 | // Для управления IoT Manager 6 | MQTT 7 | // Если требуются таймеры 8 | TIMERS 9 | // Датчики температуры и влажности DHT11, DHT22, AM2302, RHT03 10 | DHT 14 11 | // Пока только один датчик и пин менять нельзя 12 | D18B20 14 13 | // Аналоговый вход 14 | A0 15 | // Кнопка на GPIO0, доступно: rgbnot relaynot jalousienot 16 | Tach relaynot 17 | // Первая ячейка - PIN, вторая - состояние реле при включение ESP 18 | RELAY 12 1 19 | // Первая ячейка - счетчик оборотов, вторая и третья - управление мотором 20 | # JALOUSIE 4 12 13 21 | // WS2811/WS2812/NeoPixel LEDs. Первая ячейка - пин led ленты, вторая - количество лед, терья - состояние LED при включение ESP 22 | # RGB 2 15 0 23 | // В стадии разработки, пока не работает 24 | # RGBSHIM 2 4 5 25 | // Сенсор движения, доступно: relay rgb jalousie 26 | # MOTION 2 relay 27 | // Беспроводной приемник mHz частот 28 | RF-RECEIVED 3 433 29 | // Беспроводной передатчик mHz частот, скоро. 30 | # RF-TRANSMITTER 1 433 -------------------------------------------------------------------------------- /data/configs/sonoff-rf.txt: -------------------------------------------------------------------------------- 1 | // Включаем время из сети 2 | NTP 3 | // Доступ по DDNS 4 | DDNS 5 | // Для управления IoT Manager 6 | MQTT 7 | // Если требуются таймеры 8 | TIMERS 9 | // Датчики температуры и влажности DHT11, DHT22, AM2302, RHT03 10 | DHT 14 11 | // Пока только один датчик и пин менять нельзя 12 | D18B20 14 13 | // Кнопка на GPIO0, доступно: rgbnot relaynot jalousienot 14 | Tach relaynot 15 | // Первая ячейка - PIN, вторая - состояние реле при включение ESP 16 | RELAY 12 0 17 | // WS2811/WS2812/NeoPixel LEDs. Первая ячейка - пин led ленты, вторая - количество лед, терья - состояние LED при включение ESP 18 | # RGB 14 15 0 19 | // Первая ячейка - счетчик оборотов, вторая и третья - управление мотором 20 | # JALOUSIE 14 1 3 21 | // В стадии разработки, пока не работает 22 | # RGBSHIM 14 1 3 23 | // Сенсор движения, доступно: relay rgb jalousie 24 | # MOTION 14 relay 25 | // Беспроводной приемник mHz частот 26 | # RF-RECEIVED 14 433 27 | // Беспроводной передатчик mHz частот, скоро. 28 | # RF-TRANSMITTER 1 433 -------------------------------------------------------------------------------- /data/css/build.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/css/build.css.gz -------------------------------------------------------------------------------- /data/donate.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/donate.htm.gz -------------------------------------------------------------------------------- /data/edit.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/edit.htm.gz -------------------------------------------------------------------------------- /data/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/favicon.ico -------------------------------------------------------------------------------- /data/first-connect.json: -------------------------------------------------------------------------------- 1 | { 2 | "configs":[ 3 | "/config.live.json", 4 | "/config.setup.json", 5 | "/lang/lang.{{lang}}.json", 6 | "/modules.json" 7 | ], 8 | "title":"", 9 | "class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6", 10 | "content":[ 11 | { 12 | "type":"h5", 13 | "title":"{{SSDP}}", 14 | "class":"alert-warning" 15 | }, 16 | { 17 | "type":"select", 18 | "state":"{{lang}}", 19 | "name":"languages", 20 | "action":"/lang?set=[[languages]]", 21 | "response":"page.htm?{{urlArray0}}", 22 | "style":"margin-top:-47px;float:right;width:70px", 23 | "title":{"ru":"RU","en":"EN","lv":"LV","ua":"UA"} 24 | }, 25 | 26 | 27 | { 28 | "type":"link", 29 | "title":" {{LangSetting3}}", 30 | "action":"page.htm?setup", 31 | "class":"btn btn-block btn-default" 32 | }, 33 | 34 | 35 | { 36 | "type":"hr" 37 | }, 38 | 39 | { 40 | "type":"h2", 41 | "title":"{{LangType}}" 42 | }, 43 | 44 | { 45 | "type":"select", 46 | "name":"build", 47 | "class":"btn btn-block btn-info btn-lg", 48 | "style":"height:auto;", 49 | "state":"{{configs}}", 50 | "action":"/configs?set=[[build]]", 51 | "title":{ 52 | "sonoff-rf":"Sonoff-rf / Sonoff / Wi-Fi Smart socket", 53 | "rgb":"RGB (WS2811-12/NeoPixel)", 54 | "jalousie":"Jalousie", 55 | "leakag":"Leakag", 56 | "smart-room":"Smart-Room", 57 | "manually":"Manually" 58 | } 59 | }, 60 | 61 | 62 | { 63 | "type":"hr" 64 | }, 65 | 66 | 67 | { 68 | "type":"h2", 69 | "title":"{{LangDevice}}" 70 | }, 71 | { 72 | "type":"input", 73 | "title":"{{LangDevice}}", 74 | "name":"ssdp", 75 | "state":"{{SSDP}}", 76 | "style":"width:50%;display:inline", 77 | "pattern":"[0-9a-zA-Zа-яА-Я.\\- ]{1,20}" 78 | }, 79 | { 80 | "type":"input", 81 | "title":"{{LangSpace}}", 82 | "name":"space", 83 | "state":"{{space}}", 84 | "style":"width:50%;display:inline", 85 | "pattern":"[0-9a-zA-Zа-яА-Я.\\- ]{1,20}" 86 | }, 87 | { 88 | "type":"button", 89 | "title":"{{LangSave}}", 90 | "module":"", 91 | "action":"device?ssdp=[[ssdp]]&space=[[space]]", 92 | "class":"btn btn-block btn-success" 93 | }, 94 | 95 | 96 | { 97 | "type":"hr" 98 | }, 99 | 100 | 101 | { 102 | "type":"text", 103 | "name":"ip-adress", 104 | "title":"

{{LangConnect1}}

", 105 | "class":"col-sm-offset-2 col-sm-8 pop-up hidden" 106 | }, 107 | 108 | 109 | { 110 | "type":"text", 111 | "title":"{{LangWiFi3}}", 112 | "class":"alert alert-dismissible alert-danger" 113 | }, 114 | 115 | 116 | { 117 | "type":"h2", 118 | "title":"{{LangWiFi2}}" 119 | }, 120 | 121 | 122 | { 123 | "type":"wifi", 124 | "title":"{{LangWiFi1}}", 125 | "name":"ssid", 126 | "state":"{{ssid}}", 127 | "pattern":".{1,20}" 128 | }, 129 | { 130 | "type":"password", 131 | "title":"{{LangDevice}}", 132 | "name":"ssidPass", 133 | "state":"{{ssidPass}}", 134 | "pattern":".{8,20}" 135 | }, 136 | { 137 | "type":"button", 138 | "module":"", 139 | "name":"savsff", 140 | "title":"{{LangSave}}", 141 | "class":"btn btn-block btn-success", 142 | "action":"ssid?ssid=[[ssid]]&ssidPass=[[ssidPass]]&checkboxIP=0" 143 | }, 144 | 145 | 146 | { 147 | "type":"hr" 148 | }, 149 | 150 | 151 | { 152 | "type":"link", 153 | "title":"{{LangReset1}}", 154 | "name":"titi", 155 | "action":"javascript:toggle('ip-adress');send_request_post(this,'restartWiFi','{{ip-adress}}');", 156 | "class":"btn btn-block btn-warning" 157 | } 158 | ]} 159 | -------------------------------------------------------------------------------- /data/help.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/help.htm.gz -------------------------------------------------------------------------------- /data/img/swatches.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/img/swatches.png -------------------------------------------------------------------------------- /data/img/swatches1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/img/swatches1.png -------------------------------------------------------------------------------- /data/index.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/index.htm.gz -------------------------------------------------------------------------------- /data/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "configs":[ 3 | "/config.live.json", 4 | "/config.options.json", 5 | "/lang/lang.{{lang}}.json", 6 | "/modules.json" 7 | ], 8 | "title":"{{LangOptions1}}", 9 | "class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6", 10 | "content":[ 11 | { 12 | "type":"h5", 13 | "title":"{{SSDP}}", 14 | "class":"alert-info" 15 | }, 16 | { 17 | "type":"select", 18 | "state":"{{lang}}", 19 | "name":"languages", 20 | "action":"/lang?set=[[languages]]", 21 | "response":"page.htm?{{urlArray0}}", 22 | "style":"margin-top:-47px;float:right;width:70px", 23 | "title":{"ru":"RU","en":"EN","lv":"LV","ua":"UA"} 24 | }, 25 | 26 | 27 | { 28 | "type":"link", 29 | "title":"{{LangDevices}}", 30 | "action":"/", 31 | "class":"btn btn-block btn-danger" 32 | }, 33 | { 34 | "type":"link", 35 | "title":" {{LangSetting3}}", 36 | "action":"/page.htm?setup", 37 | "class":"btn btn-block btn-default" 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /data/index2.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/index2.htm.gz -------------------------------------------------------------------------------- /data/index3.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/index3.htm.gz -------------------------------------------------------------------------------- /data/index4.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/index4.htm.gz -------------------------------------------------------------------------------- /data/jalousie.json: -------------------------------------------------------------------------------- 1 | { 2 | "configs":[ 3 | "/config.live.json", 4 | "/config.options.json", 5 | "/lang/lang.{{lang}}.json", 6 | "/modules.json" 7 | ], 8 | "title":"{{LangOptions1}}", 9 | "class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6", 10 | "content":[ 11 | { 12 | "type":"h5", 13 | "title":"{{SSDP}}", 14 | "class":"alert-success" 15 | }, 16 | { 17 | "type":"select", 18 | "state":"{{lang}}", 19 | "name":"languages", 20 | "action":"/lang?set=[[languages]]", 21 | "response":"page.htm?{{urlArray0}}", 22 | "style":"margin-top:-47px;float:right;width:70px", 23 | "title":{"ru":"RU","en":"EN","lv":"LV","ua":"UA"} 24 | }, 25 | 26 | 27 | { 28 | "type":"link", 29 | "title":"{{LangDevices}}", 30 | "action":"/", 31 | "class":"btn btn-block btn-danger" 32 | }, 33 | { 34 | "type":"link", 35 | "title":"{{LangOptions1}} RGB", 36 | "module":"rgb", 37 | "action":"/page.htm?rgb", 38 | "class":"btn btn-block btn-default" 39 | }, 40 | { 41 | "type":"link", 42 | "title":"{{LangOptions1}} Relay", 43 | "module":"relay", 44 | "action":"/page.htm?relay", 45 | "class":"btn btn-block btn-default" 46 | }, 47 | { 48 | "type":"link", 49 | "title":" {{LangSetting3}}", 50 | "action":"/page.htm?setup", 51 | "class":"btn btn-block btn-default" 52 | }, 53 | 54 | 55 | { 56 | "type":"hr" 57 | }, 58 | 59 | 60 | { 61 | "type":"text", 62 | "module":"ddns", 63 | "title":"{{LangIfttt1}}", 64 | "class":"alert alert-info" 65 | }, 66 | 67 | 68 | { 69 | "type":"button", 70 | "title":"('{{stateJalousie}}'==0?'{{LangOpen}}':'{{LangClose}}')", 71 | "name":"motor", 72 | "module":"jalousie", 73 | "response":"[[motor]]", 74 | "action":"jalousienot", 75 | "class":"btn btn-block btn-lg btn-primary" 76 | }, 77 | 78 | 79 | { 80 | "type":"hr" 81 | }, 82 | 83 | { 84 | "type":"h2", 85 | "title":"{{LangTurn}}" 86 | }, 87 | { 88 | "type":"input", 89 | "title":"{{turn}}", 90 | "module":"jalousie", 91 | "name":"turn", 92 | "state":"{{turn}}", 93 | "pattern":"[0-9]{1,3}" 94 | }, 95 | { 96 | "type":"button", 97 | "module":"jalousie", 98 | "title":"{{LangSave}}", 99 | "class":"btn btn-block btn-success", 100 | "action":"jalousieturn [[turn]]" 101 | }, 102 | 103 | 104 | { 105 | "type":"hr", 106 | "module":"timers" 107 | }, 108 | 109 | 110 | { 111 | "type":"h2", 112 | "module":"timers", 113 | "title":"{{LangTimer}}" 114 | }, 115 | 116 | 117 | { 118 | "type":"table", 119 | "module":"timers", 120 | "state":"timer.save.json", 121 | "title":{ 122 | "module":"", 123 | "trigger":"{{LangOn.}}/{{LangOff.}}", 124 | "day":"{{LangDay}}", 125 | "time":"{{LangTime4}}", 126 | "work":"{{LangWorkTime}}" 127 | }, 128 | "class":"table alert alert-dismissible alert-warning", 129 | "style":"width:100%;" 130 | }, 131 | { 132 | "type":"link", 133 | "module":"timers", 134 | "title":"{{LangTimer}}", 135 | "action":"page.htm?timer", 136 | "class":"btn btn-block btn-default" 137 | }, 138 | 139 | 140 | { 141 | "type":"hr" 142 | }, 143 | 144 | 145 | { 146 | "type":"chart", 147 | "title":"{{LangAnalog}}", 148 | "state":"analog.json", 149 | "module":"analog", 150 | "action":"/page.htm?chart&analog", 151 | "style":"height:200px;margin-left:-20px" 152 | }, 153 | { 154 | "type":"chart", 155 | "title":"{{LangTemperature}}", 156 | "state":"temperature.json", 157 | "module":"temperature", 158 | "action":"/page.htm?chart&temperature", 159 | "style":"height:200px;margin-left:-20px" 160 | }, 161 | { 162 | "type":"chart", 163 | "title":"{{LangHumidity}}", 164 | "state":"humidity.json", 165 | "module":"humidity", 166 | "action":"/page.htm?chart&humidity", 167 | "style":"height:200px;margin-left:-20px" 168 | }, 169 | 170 | 171 | { 172 | "type":"h2", 173 | "module":"movement", 174 | "title":"{{LangPir1}}" 175 | }, 176 | { 177 | "type":"text", 178 | "module":"movement", 179 | "title":"{{LangPir2}}", 180 | "class":"alert alert-info", 181 | "style":"width:60%;float:left;" 182 | }, 183 | 184 | { 185 | "type":"input", 186 | "module":"movement", 187 | "title":"", 188 | "name":"pir-time", 189 | "state":"{{pirTime}}", 190 | "style":"width:35%;float:right;", 191 | "pattern":"[0-9]*[.,]?[0-9]+" 192 | }, 193 | { 194 | "type":"button", 195 | "module":"movement", 196 | "title":"{{LangOff.}}", 197 | "action":"/pir?t=0", 198 | "class":"btn btn-block btn-default", 199 | "style":"width:15%;float:right;margin-top:5px;" 200 | }, 201 | { 202 | "type":"button", 203 | "module":"movement", 204 | "title":"{{LangSave}}", 205 | "action":"/pir?t=[[pir-time]]", 206 | "class":"btn btn-block btn-success", 207 | "style":"width:20%;float:right;" 208 | }, 209 | 210 | 211 | { 212 | "type":"hr", 213 | "module":"movement", 214 | "style":"clear:both;" 215 | }, 216 | 217 | 218 | { 219 | "type":"link", 220 | "title":" {{LangSetting3}}", 221 | "action":"/page.htm?setup", 222 | "class":"btn btn-block btn-default" 223 | } 224 | 225 | ] 226 | } 227 | -------------------------------------------------------------------------------- /data/js/build.chart.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/js/build.chart.js.gz -------------------------------------------------------------------------------- /data/js/function.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/js/function.js.gz -------------------------------------------------------------------------------- /data/lang/lang.en.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/lang/lang.en.json.gz -------------------------------------------------------------------------------- /data/lang/lang.lv.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/lang/lang.lv.json.gz -------------------------------------------------------------------------------- /data/lang/lang.ru.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/lang/lang.ru.json.gz -------------------------------------------------------------------------------- /data/lang/lang.ua.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/lang/lang.ua.json.gz -------------------------------------------------------------------------------- /data/page.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/page.htm.gz -------------------------------------------------------------------------------- /data/relay.json: -------------------------------------------------------------------------------- 1 | { 2 | "configs":[ 3 | "/config.live.json", 4 | "/config.options.json", 5 | "/lang/lang.{{lang}}.json", 6 | "/modules.json" 7 | ], 8 | "title":"{{LangOptions1}}", 9 | "class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6", 10 | "content":[ 11 | { 12 | "type":"h5", 13 | "title":"{{SSDP}}", 14 | "class":"alert-danger" 15 | }, 16 | { 17 | "type":"select", 18 | "state":"{{lang}}", 19 | "name":"languages", 20 | "action":"/lang?set=[[languages]]", 21 | "response":"page.htm?{{urlArray0}}", 22 | "style":"margin-top:-47px;float:right;width:70px", 23 | "title":{"ru":"RU","en":"EN","lv":"LV","ua":"UA"} 24 | }, 25 | 26 | 27 | { 28 | "type":"link", 29 | "title":"{{LangDevices}}", 30 | "action":"/", 31 | "class":"btn btn-block btn-danger" 32 | }, 33 | { 34 | "type":"link", 35 | "title":"{{LangOptions1}} RGB", 36 | "module":"rgb", 37 | "action":"/page.htm?rgb", 38 | "class":"btn btn-block btn-default" 39 | }, 40 | { 41 | "type":"link", 42 | "title":"{{LangOptions1}} Jalousie", 43 | "module":"jalousie", 44 | "action":"/page.htm?jalousie", 45 | "class":"btn btn-block btn-default" 46 | }, 47 | { 48 | "type":"link", 49 | "title":" {{LangSetting3}}", 50 | "action":"/page.htm?setup", 51 | "class":"btn btn-block btn-default" 52 | }, 53 | 54 | 55 | { 56 | "type":"hr" 57 | }, 58 | 59 | 60 | { 61 | "type":"text", 62 | "module":"ddns", 63 | "title":"{{LangIfttt1}}", 64 | "class":"alert alert-info" 65 | }, 66 | 67 | 68 | { 69 | "type":"button", 70 | "title":"({{stateRelay}}==0?'{{LangOn}}':'{{LangOff}}')", 71 | "name":"relay0", 72 | "response":"[[relay0]]", 73 | "action":"relay", 74 | "class":"btn btn-block btn-lg btn-primary" 75 | }, 76 | 77 | { 78 | "type":"button", 79 | "title":"({{stateRelay}}==0?'{{LangOn}}':'{{LangOff}}')", 80 | "name":"relay1", 81 | "module":"relay1", 82 | "response":"[[relay1]]", 83 | "action":"relay1", 84 | "class":"btn btn-block btn-lg btn-primary" 85 | }, 86 | 87 | { 88 | "type":"button", 89 | "title":"({{stateRelay}}==0?'{{LangOn}}':'{{LangOff}}')", 90 | "name":"relay2", 91 | "module":"relay2", 92 | "response":"[[relay2]]", 93 | "action":"relay2", 94 | "class":"btn btn-block btn-lg btn-primary" 95 | }, 96 | 97 | { 98 | "type":"button", 99 | "title":"({{stateRelay}}==0?'{{LangOn}}':'{{LangOff}}')", 100 | "name":"relay3", 101 | "module":"relay3", 102 | "response":"[[relay3]]", 103 | "action":"relay3", 104 | "class":"btn btn-block btn-lg btn-primary" 105 | }, 106 | 107 | { 108 | "type":"hr", 109 | "module":"timers" 110 | }, 111 | 112 | 113 | { 114 | "type":"h2", 115 | "module":"timers", 116 | "title":"{{LangTimer}}" 117 | }, 118 | 119 | 120 | { 121 | "type":"table", 122 | "module":"timers", 123 | "state":"timer.save.json", 124 | "title":{ 125 | "module":"", 126 | "trigger":"{{LangOn.}}/{{LangOff.}}", 127 | "day":"{{LangDay}}", 128 | "time":"{{LangTime4}}", 129 | "work":"{{LangWorkTime}}" 130 | }, 131 | "class":"table alert alert-dismissible alert-warning", 132 | "style":"width:100%;" 133 | }, 134 | { 135 | "type":"link", 136 | "module":"timers", 137 | "title":"{{LangTimer}}", 138 | "action":"page.htm?timer", 139 | "class":"btn btn-block btn-default" 140 | }, 141 | 142 | 143 | { 144 | "type":"hr" 145 | }, 146 | 147 | 148 | { 149 | "type":"chart", 150 | "title":"{{LangAnalog}}", 151 | "state":"analog.json", 152 | "module":"analog", 153 | "action":"/page.htm?chart&analog", 154 | "style":"height:200px;margin-left:-20px" 155 | }, 156 | { 157 | "type":"chart", 158 | "title":"{{LangTemperature}}", 159 | "state":"temperature.json", 160 | "module":"temperature", 161 | "action":"/page.htm?chart&temperature", 162 | "style":"height:200px;margin-left:-20px" 163 | }, 164 | { 165 | "type":"chart", 166 | "title":"{{LangHumidity}}", 167 | "state":"humidity.json", 168 | "module":"humidity", 169 | "action":"/page.htm?chart&humidity", 170 | "style":"height:200px;margin-left:-20px" 171 | }, 172 | 173 | 174 | { 175 | "type":"h2", 176 | "module":"movement", 177 | "title":"{{LangPir1}}" 178 | }, 179 | { 180 | "type":"text", 181 | "module":"movement", 182 | "title":"{{LangPir2}} {{LangSoon}}", 183 | "class":"alert alert-info", 184 | "style":"width:60%;float:left;" 185 | }, 186 | 187 | { 188 | "type":"input", 189 | "module":"movement", 190 | "title":"", 191 | "name":"pir-time", 192 | "state":"{{pirTime}}", 193 | "style":"width:35%;float:right;", 194 | "pattern":"[0-9]*[.,]?[0-9]+" 195 | }, 196 | { 197 | "type":"button", 198 | "module":"movement", 199 | "title":"{{LangOff.}}", 200 | "action":"/pir?t=0", 201 | "class":"btn btn-block btn-default", 202 | "style":"width:15%;float:right;margin-top:5px;" 203 | }, 204 | { 205 | "type":"button", 206 | "module":"movement", 207 | "title":"{{LangSave}}", 208 | "action":"/pir?t=[[pir-time]]", 209 | "class":"btn btn-block btn-success", 210 | "style":"width:20%;float:right;" 211 | }, 212 | 213 | 214 | { 215 | "type":"hr", 216 | "module":"movement", 217 | "style":"clear:both;" 218 | }, 219 | 220 | 221 | { 222 | "type":"link", 223 | "title":" {{LangSetting3}}", 224 | "action":"/page.htm?setup", 225 | "class":"btn btn-block btn-default" 226 | } 227 | 228 | ] 229 | } 230 | -------------------------------------------------------------------------------- /data/rgb.json: -------------------------------------------------------------------------------- 1 | { 2 | "configs":[ 3 | "/config.live.json", 4 | "/config.options.json", 5 | "/lang/lang.{{lang}}.json", 6 | "/modules.json" 7 | ], 8 | "title":"{{LangOptions1}}", 9 | "class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6", 10 | "content":[ 11 | { 12 | "type":"h5", 13 | "title":"{{SSDP}}", 14 | "class":"alert-info" 15 | }, 16 | { 17 | "type":"select", 18 | "state":"{{lang}}", 19 | "name":"languages", 20 | "action":"/lang?set=[[languages]]", 21 | "response":"page.htm?{{urlArray0}}", 22 | "style":"margin-top:-47px;float:right;width:70px", 23 | "title":{"ru":"RU","en":"EN","lv":"LV","ua":"UA"} 24 | }, 25 | 26 | 27 | { 28 | "type":"link", 29 | "title":"{{LangDevices}}", 30 | "action":"/", 31 | "class":"btn btn-block btn-danger" 32 | }, 33 | { 34 | "type":"link", 35 | "title":"{{LangOptions1}} Relay", 36 | "module":"relay", 37 | "action":"/page.htm?relay", 38 | "class":"btn btn-block btn-default" 39 | }, 40 | { 41 | "type":"link", 42 | "title":"{{LangOptions1}} Jalousie", 43 | "module":"jalousie", 44 | "action":"/page.htm?jalousie", 45 | "class":"btn btn-block btn-default" 46 | }, 47 | { 48 | "type":"link", 49 | "title":" {{LangSetting3}}", 50 | "action":"/page.htm?setup", 51 | "class":"btn btn-block btn-default" 52 | }, 53 | 54 | 55 | { 56 | "type":"hr" 57 | }, 58 | 59 | 60 | { 61 | "type":"text", 62 | "module":"ddns", 63 | "title":"{{LangIfttt1}}", 64 | "class":"alert alert-info" 65 | }, 66 | 67 | { 68 | "type":"rgb", 69 | "title":"/img/swatches.png", 70 | "name":"color", 71 | "state":"{{colorRGB}}", 72 | "response":"[[rgb]]", 73 | "action":"set?c=[[color]]&time=[[time]]&sound=[[sound]]&s=[[speed]]&b=[[brightness]]", 74 | "style":"cursor:pointer;width:100%" 75 | }, 76 | 77 | { 78 | "type":"select", 79 | "state":"{{modeRGB}}", 80 | "name":"dynamic", 81 | "response":"[[rgb]]", 82 | "action":"set?m=[[dynamic]]&time=[[time]]&sound=[[sound]]&s=[[speed]]&b=[[brightness]]", 83 | "title":{ 84 | "0":"Static", 85 | "1":"Blink", 86 | "2":"Breath", 87 | "3":"Color Wipe", 88 | "4":"Color Wipe Random", 89 | "5":"Random Color", 90 | "6":"Single Dynamic", 91 | "7":"Multi Dynamic", 92 | "8":"Rainbow", 93 | "9":"Rainbow Cycle", 94 | "10":"Scan", 95 | "11":"Dual Scan", 96 | "12":"Fade", 97 | "13":"Theater Chase", 98 | "14":"Theater Chase Rainbow", 99 | "15":"Running Lights", 100 | "16":"Twinkle", 101 | "17":"Twinkle Random", 102 | "18":"Twinkle Fade", 103 | "19":"Twinkle Fade Random", 104 | "20":"Sparkle", 105 | "21":"Flash Sparkle", 106 | "22":"Hyper Sparkle", 107 | "23":"Strobe", 108 | "24":"Strobe Rainbow", 109 | "25":"Multi Strobe", 110 | "26":"Blink Rainbow", 111 | "27":"Chase White", 112 | "28":"Chase Color", 113 | "29":"Chase Random", 114 | "30":"Chase Rainbow", 115 | "31":"Chase Flash", 116 | "32":"Chase Flash Random", 117 | "33":"Chase Rainbow White", 118 | "34":"Chase Blackout", 119 | "35":"Chase Blackout Rainbow", 120 | "36":"Color Sweep Random", 121 | "37":"Running Color", 122 | "38":"Running Red Blue", 123 | "39":"Running Random", 124 | "40":"Larson Scanner", 125 | "41":"Comet", 126 | "42":"Fireworks", 127 | "43":"Fireworks random", 128 | "44":"Merry Christmas" 129 | } 130 | }, 131 | 132 | 133 | { 134 | "type":"h4", 135 | "title":"{{LangTime8}} {{LangSoon}}" 136 | }, 137 | { 138 | "type":"select", 139 | "state":"{{timeRGB}}", 140 | "name":"time", 141 | "response":"[[rgb]]", 142 | "action":"set?c=[[color]]&time=[[time]]&sound=[[sound]]&s=[[speed]]&b=[[brightness]]", 143 | "title":{ 144 | "60":"1", 145 | "300":"5", 146 | "600":"10", 147 | "1500":"15", 148 | "1800":"30", 149 | "3600":"60", 150 | "5400":"1:30", 151 | "7200":"2:00", 152 | "10800":"3:00", 153 | "0":"∞" 154 | } 155 | }, 156 | { 157 | "type":"h4", 158 | "title":"{{LangTime5}} {{LangSoon}}" 159 | }, 160 | { 161 | "type":"input", 162 | "title":"", 163 | "name":"sound", 164 | "state":"{{timeBUZ}}", 165 | "pattern":"[-+]?[0-9]*[.]?[0-9]+" 166 | }, 167 | 168 | { 169 | "type":"range", 170 | "title":"{{LangSpeed}}", 171 | "name":"speed", 172 | "state":"{{speedRGB}}", 173 | "response":"[[rgb]]", 174 | "action":"set?c=[[color]]&time=[[time]]&sound=[[sound]]&s=[[speed]]&b=[[brightness]]", 175 | "pattern":"min=0 max=255 step=1" 176 | }, 177 | { 178 | "type":"range", 179 | "title":"{{LengBrightness}}", 180 | "name":"brightness", 181 | "state":"{{brightnessRGB}}", 182 | "response":"[[rgb]]", 183 | "action":"set?c=[[color]]&time=[[time]]&sound=[[sound]]&s=[[speed]]&b=[[brightness]]", 184 | "pattern":"min=0 max=255 step=1" 185 | }, 186 | 187 | 188 | 189 | { 190 | "type":"button", 191 | "title":"({{stateRGB}}==0?'{{LangOn}}':'{{LangOff}}')", 192 | "name":"rgb", 193 | "response":"[[rgb]]", 194 | "action":"rgb", 195 | "class":"btn btn-block btn-lg btn-primary" 196 | }, 197 | 198 | 199 | { 200 | "type":"hr", 201 | "module":"timers" 202 | }, 203 | 204 | 205 | { 206 | "type":"h2", 207 | "module":"timers", 208 | "title":"{{LangTimer}}" 209 | }, 210 | { 211 | "type":"table", 212 | "module":"timers", 213 | "state":"timer.save.json", 214 | "title":{ 215 | "module":"", 216 | "trigger":"{{LangOn.}}/{{LangOff.}}", 217 | "day":"{{LangDay}}", 218 | "time":"{{LangTime4}}", 219 | "work":"{{LangWorkTime}}" 220 | }, 221 | "class":"table alert alert-dismissible alert-warning", 222 | "style":"width:100%;" 223 | }, 224 | { 225 | "type":"link", 226 | "module":"timers", 227 | "title":"{{LangTimer}}", 228 | "action":"page.htm?timer", 229 | "class":"btn btn-block btn-default" 230 | }, 231 | 232 | 233 | { 234 | "type":"hr" 235 | }, 236 | 237 | 238 | { 239 | "type":"chart", 240 | "title":"{{LangAnalog}}", 241 | "state":"analog.json", 242 | "module":"analog", 243 | "action":"/page.htm?chart&analog", 244 | "style":"height:200px;margin-left:-20px" 245 | }, 246 | { 247 | "type":"chart", 248 | "title":"{{LangTemperature}}", 249 | "state":"temperature.json", 250 | "module":"temperature", 251 | "action":"/page.htm?chart&temperature", 252 | "style":"height:200px;margin-left:-20px" 253 | }, 254 | { 255 | "type":"chart", 256 | "title":"{{LangHumidity}}", 257 | "state":"humidity.json", 258 | "module":"humidity", 259 | "action":"/page.htm?chart&humidity", 260 | "style":"height:200px;margin-left:-20px" 261 | }, 262 | 263 | { 264 | "type":"h2", 265 | "module":"movement", 266 | "title":"{{LangPir1}}" 267 | }, 268 | { 269 | "type":"text", 270 | "module":"movement", 271 | "title":"{{LangPir2}} {{LangSoon}}", 272 | "class":"alert alert-info", 273 | "style":"width:60%;float:left;" 274 | }, 275 | 276 | { 277 | "type":"input", 278 | "module":"movement", 279 | "title":"", 280 | "name":"pir-time", 281 | "state":"{{pirTime}}", 282 | "style":"width:35%;float:right;", 283 | "pattern":"[0-9]*[.,]?[0-9]+" 284 | }, 285 | { 286 | "type":"button", 287 | "module":"movement", 288 | "title":"{{LangOff.}}", 289 | "action":"/pir?t=0", 290 | "class":"btn btn-block btn-default", 291 | "style":"width:15%;float:right;margin-top:5px;" 292 | }, 293 | { 294 | "type":"button", 295 | "module":"movement", 296 | "title":"{{LangSave}}", 297 | "action":"/pir?t=[[pir-time]]", 298 | "class":"btn btn-block btn-success", 299 | "style":"width:20%;float:right;" 300 | }, 301 | 302 | 303 | { 304 | "type":"hr", 305 | "module":"movement", 306 | "style":"clear:both;" 307 | }, 308 | 309 | 310 | { 311 | "type":"link", 312 | "title":" {{LangSetting3}}", 313 | "action":"/page.htm?setup", 314 | "class":"btn btn-block btn-default" 315 | } 316 | 317 | ] 318 | } 319 | -------------------------------------------------------------------------------- /data/scenary.json: -------------------------------------------------------------------------------- 1 | { 2 | "configs":[ 3 | "/config.options.json", 4 | "/lang/lang.{{lang}}.json", 5 | "/modules.json" 6 | ], 7 | "title":"{{LangScenary}}", 8 | "class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6", 9 | "content":[ 10 | { 11 | "type":"h5", 12 | "title":"{{SSDP}}", 13 | "class":"alert-danger" 14 | }, 15 | { 16 | "type":"select", 17 | "state":"{{lang}}", 18 | "name":"languages", 19 | "action":"/lang?set=[[languages]]", 20 | "response":"page.htm?{{urlArray0}}", 21 | "style":"margin-top:-47px;float:right;width:70px", 22 | "title":{"ru":"RU","en":"EN","lv":"LV","ua":"UA"} 23 | }, 24 | 25 | 26 | { 27 | "type":"link", 28 | "title":"{{LangDevices}}", 29 | "action":"/", 30 | "class":"btn btn-block btn-danger" 31 | }, 32 | 33 | 34 | { 35 | "type":"link", 36 | "title":"{{LangOptions1}} RGB", 37 | "module":"rgb", 38 | "action":"/page.htm?rgb", 39 | "class":"btn btn-block btn-default" 40 | }, 41 | { 42 | "type":"link", 43 | "title":"{{LangOptions1}} Relay", 44 | "module":"relay", 45 | "action":"/page.htm?relay", 46 | "class":"btn btn-block btn-default" 47 | }, 48 | { 49 | "type":"link", 50 | "title":"{{LangOptions1}} Jalousie", 51 | "module":"jalousie", 52 | "action":"/page.htm?jalousie", 53 | "class":"btn btn-block btn-default" 54 | }, 55 | { 56 | "type":"link", 57 | "title":" {{LangSetting3}}", 58 | "action":"/page.htm?setup", 59 | "class":"btn btn-block btn-default" 60 | }, 61 | 62 | 63 | { 64 | "type":"hr" 65 | }, 66 | 67 | 68 | { 69 | "type":"h2", 70 | "title":"{{LangScenary}}" 71 | }, 72 | 73 | 74 | { 75 | "type":"scenary-list", 76 | "style":"width:100%" 77 | }, 78 | 79 | 80 | { 81 | "type":"hr" 82 | }, 83 | 84 | 85 | { 86 | "type":"h2", 87 | "title":"{{LangAddScenery}}" 88 | }, 89 | { 90 | "type":"text", 91 | "title":"{{LangScenery1}}", 92 | "class":"alert alert-info" 93 | }, 94 | 95 | { 96 | "type":"scenary" 97 | }, 98 | 99 | { 100 | "type":"hr" 101 | }, 102 | 103 | { 104 | "type":"link", 105 | "title":" {{LangSetting3}}", 106 | "action":"/page.htm?setup", 107 | "class":"btn btn-block btn-default" 108 | } 109 | 110 | ] 111 | } 112 | -------------------------------------------------------------------------------- /data/scenary.save.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/data/scenary.save.txt -------------------------------------------------------------------------------- /data/starting.json: -------------------------------------------------------------------------------- 1 | { 2 | "configs": [ 3 | "/config.options.json", 4 | "/config.setup.json", 5 | "/lang/lang.{{lang}}.json", 6 | "/modules.json" 7 | ], 8 | "title": "Starting Log", 9 | "class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6", 10 | "content": [ 11 | { 12 | "type": "h5", 13 | "title": "{{SSDP}}", 14 | "class":"alert-default" 15 | }, 16 | { 17 | "type": "select", 18 | "state": "{{lang}}", 19 | "name":"languages", 20 | "action": "/lang?set=[[languages]]", 21 | "response":"page.htm?{{urlArray0}}", 22 | "style": "margin-top:-47px;float:right;width:70px", 23 | "title": {"ru":"RU","en":"EN","lv":"LV","ua":"UA"} 24 | }, 25 | 26 | 27 | { 28 | "type": "link", 29 | "title": "{{LangDevices}}", 30 | "action": "/", 31 | "class": "btn btn-block btn-danger" 32 | }, 33 | { 34 | "type": "link", 35 | "title": "{{LangOptions1}} RGB", 36 | "module": "rgb", 37 | "action": "/page.htm?rgb", 38 | "class": "btn btn-block btn-default" 39 | }, 40 | { 41 | "type": "link", 42 | "title": "{{LangOptions1}} Relay", 43 | "module": "relay", 44 | "action": "/page.htm?relay", 45 | "class": "btn btn-block btn-default" 46 | }, 47 | { 48 | "type": "link", 49 | "title": "{{LangOptions1}} Jalousie", 50 | "module": "jalousie", 51 | "action": "/page.htm?jalousie", 52 | "class": "btn btn-block btn-default" 53 | }, 54 | { 55 | "type": "link", 56 | "title": " {{LangSetting3}}", 57 | "action": "/page.htm?setup", 58 | "class": "btn btn-block btn-default" 59 | }, 60 | 61 | { 62 | "type": "hr" 63 | }, 64 | { 65 | "type": "h2", 66 | "title": "{{LangType}} {{configs}}" 67 | }, 68 | { 69 | "type": "text", 70 | "title":"Обратите внимание на данный момент время показывается в GMT 0 зоне.", 71 | "class": "alert alert-info" 72 | }, 73 | 74 | 75 | { 76 | "type": "table", 77 | "state": "http://backup.privet.lv/visitors/{{mac}}.json", 78 | "title": { 79 | "starting":"Starting", 80 | "startingInfo":"Starting Info", 81 | "module":"Module" 82 | }, 83 | "class": "table table-striped table-hover", 84 | "style": "width:100%;" 85 | }, 86 | 87 | { 88 | "type": "hr" 89 | }, 90 | { 91 | "type": "link", 92 | "title": " {{LangSetting3}}", 93 | "action": "/page.htm?setup", 94 | "class": "btn btn-block btn-default" 95 | } 96 | 97 | ] 98 | } 99 | -------------------------------------------------------------------------------- /data/timer.json: -------------------------------------------------------------------------------- 1 | { 2 | "configs":[ 3 | "/config.live.json", 4 | "/config.options.json", 5 | "/lang/lang.{{lang}}.json", 6 | "/modules.json" 7 | ], 8 | "title":"{{LangTimer}}", 9 | "class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6", 10 | "content":[ 11 | { 12 | "type":"h5", 13 | "title":"{{SSDP}}", 14 | "class":"alert-danger" 15 | }, 16 | { 17 | "type":"select", 18 | "state":"{{lang}}", 19 | "name":"languages", 20 | "action":"/lang?set=[[languages]]", 21 | "response":"page.htm?{{urlArray0}}", 22 | "style":"margin-top:-47px;float:right;width:70px", 23 | "title":{"ru":"RU","en":"EN","lv":"LV","ua":"UA"} 24 | }, 25 | 26 | 27 | { 28 | "type":"link", 29 | "title":"{{LangDevices}}", 30 | "action":"/", 31 | "class":"btn btn-block btn-danger" 32 | }, 33 | 34 | 35 | { 36 | "type":"link", 37 | "title":"{{LangOptions1}} RGB", 38 | "module":"rgb", 39 | "action":"/page.htm?rgb", 40 | "class":"btn btn-block btn-default" 41 | }, 42 | { 43 | "type":"link", 44 | "title":"{{LangOptions1}} Relay", 45 | "module":"relay", 46 | "action":"/page.htm?relay", 47 | "class":"btn btn-block btn-default" 48 | }, 49 | { 50 | "type":"link", 51 | "title":"{{LangOptions1}} Jalousie", 52 | "module":"jalousie", 53 | "action":"/page.htm?jalousie", 54 | "class":"btn btn-block btn-default" 55 | }, 56 | { 57 | "type":"link", 58 | "title":" {{LangSetting3}}", 59 | "action":"/page.htm?setup", 60 | "class":"btn btn-block btn-default" 61 | }, 62 | 63 | 64 | { 65 | "type":"hr" 66 | }, 67 | { 68 | "type":"time", 69 | "title":"{{LangTime1}}", 70 | "state":"{{time}}" 71 | }, 72 | 73 | { 74 | "type":"hr" 75 | }, 76 | { 77 | "type":"h2", 78 | "title":"{{LangList}}" 79 | }, 80 | { 81 | "type":"table", 82 | "name":"timer-list", 83 | "state":"timer.save.json", 84 | "title":{ 85 | "module":"", 86 | "trigger":"{{LangOn.}}/{{LangOff.}}", 87 | "day":"{{LangDay}}", 88 | "time":"{{LangTime4}}", 89 | "work":"{{LangWorkTime}}{{LangSoon}}", 90 | "id":"{{LangDel}}" 91 | }, 92 | "class":"table", 93 | "style":"width:100%;" 94 | }, 95 | 96 | 97 | 98 | { 99 | "type":"hr" 100 | }, 101 | { 102 | "type":"h2", 103 | "title":"{{LangTime3}}" 104 | }, 105 | { 106 | "type":"text", 107 | "title":"{{LangTime6}}", 108 | "class":"alert alert-warning" 109 | }, 110 | 111 | 112 | { 113 | "type":"select", 114 | "name":"module", 115 | "response":"[[trigger]]", 116 | "action":"/trigger.[[module]].json", 117 | "title":{"rgb":"RGB","relay":"Relay","jalousie":"Jalousie"} 118 | }, 119 | 120 | 121 | 122 | { 123 | "type":"select", 124 | "name":"trigger", 125 | "style":"width:50%;display:inline", 126 | "title":{"not":"{{LangSwitch.}}","on":"{{LangOn.}}","off":"{{LangOff.}}"} 127 | }, 128 | { 129 | "type":"select", 130 | "name":"day", 131 | "style":"width:50%;display:inline", 132 | "title":{ 133 | "All":"{{LangDay}}", 134 | "All":"{{LangAll}}", 135 | "Mon":"{{LangMon}}", 136 | "Tue":"{{LangTue}}", 137 | "Wed":"{{LangWed}}", 138 | "Thu":"{{LangThu}}", 139 | "Fri":"{{LangFri}}", 140 | "Sat":"{{LangSat}}", 141 | "Sun":"{{LangSun}}" 142 | } 143 | }, 144 | { 145 | "type":"input", 146 | "name":"set-time", 147 | "title":"Start. {{LangExample}}: 07:09:30", 148 | "style":"width:50%;display:inline", 149 | "pattern":"(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){2}" 150 | }, 151 | { 152 | "type":"input", 153 | "name":"work", 154 | "title":"{{LangWorkTime}}. {{LangExample}}: 00:40:00", 155 | "style":"width:50%;display:inline", 156 | "pattern":"(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){2}" 157 | }, 158 | { 159 | "type":"button", 160 | "title":"{{LangSave}}", 161 | "response":"[[timer-list]]", 162 | "module":"", 163 | "class":"btn btn-block btn-success", 164 | "action":"/timerSave?module=[[module]]&trigger=[[trigger]]&id=[[time]]&day=[[day]]&time=[[set-time]]&work=[[work]]" 165 | }, 166 | { 167 | "type":"hr" 168 | }, 169 | 170 | { 171 | "type":"link", 172 | "title":" {{LangSetting3}}", 173 | "action":"/page.htm?setup", 174 | "class":"btn btn-block btn-default" 175 | } 176 | 177 | ] 178 | } 179 | -------------------------------------------------------------------------------- /data/timer.save.json: -------------------------------------------------------------------------------- 1 | {"timer":[]} 2 | -------------------------------------------------------------------------------- /data/trigger.jalousie.json: -------------------------------------------------------------------------------- 1 | {"title":{"not":"{{LangSwitch.}}","open":"{{LangOpen}}","close":"{{LangClose}}"}} 2 | -------------------------------------------------------------------------------- /data/trigger.relay.json: -------------------------------------------------------------------------------- 1 | {"title":{"not":"{{LangSwitch.}}","on":"{{LangOn.}}","off":"{{LangOff.}}"}} 2 | -------------------------------------------------------------------------------- /data/trigger.rgb.json: -------------------------------------------------------------------------------- 1 | {"title":{"not":"{{LangSwitch.}}","on":"{{LangOn.}}","off":"{{LangOff.}}"}} 2 | -------------------------------------------------------------------------------- /dev_data/block-analog.htm: -------------------------------------------------------------------------------- 1 |
2 |
3 |
{{SSDP}}
4 |

{{LangAnalog}}

5 |
6 |
7 | {{LangOptions1}} 8 | 9 |
10 |
11 |
12 | -------------------------------------------------------------------------------- /dev_data/block-humidity.htm: -------------------------------------------------------------------------------- 1 |
2 |
3 |
{{SSDP}}
4 |

{{LangHumidity}}

5 |
6 |
7 | {{LangOptions1}} 8 | 9 |
10 |
11 |
12 | -------------------------------------------------------------------------------- /dev_data/block-jalousie.htm: -------------------------------------------------------------------------------- 1 |
2 |
3 |
{{SSDP}}
4 |
5 | 6 | 7 |
    {{timerList}}
8 |
9 |
10 | 11 |
12 |
13 | {{LangOptions1}} 14 | 15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /dev_data/block-leakag.htm: -------------------------------------------------------------------------------- 1 |
2 |
3 |
{{SSDP}}
4 |
5 | 6 | 7 |
    {{timerList}}
8 |
9 |
10 | 11 |
12 |
13 | {{LangOptions1}} 14 | 15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /dev_data/block-relay.htm: -------------------------------------------------------------------------------- 1 |
2 |
3 |
{{SSDP}}
4 |
5 | 6 | 7 |
    {{timerList}}
8 |
9 |
10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | {{LangOptions1}} 18 | 19 |
20 |
21 |
22 | -------------------------------------------------------------------------------- /dev_data/block-rgb.htm: -------------------------------------------------------------------------------- 1 |
2 |
3 |
{{SSDP}}
4 |
5 | 6 | 7 |
    {{timerList}}
8 |
9 |
10 | 11 | 12 |
13 |
14 | {{LangOptions1}} 15 | 16 |
17 |
18 |
19 | -------------------------------------------------------------------------------- /dev_data/block-temperature.htm: -------------------------------------------------------------------------------- 1 |
2 |
3 |
{{SSDP}}
4 |

{{LangTemperature}}

5 |
6 |
7 | {{LangOptions1}} 8 | 9 |
10 |
11 |
12 | -------------------------------------------------------------------------------- /dev_data/css/chartist.min.css: -------------------------------------------------------------------------------- 1 | .ct-double-octave:after,.ct-major-eleventh:after,.ct-major-second:after,.ct-major-seventh:after,.ct-major-sixth:after,.ct-major-tenth:after,.ct-major-third:after,.ct-major-twelfth:after,.ct-minor-second:after,.ct-minor-seventh:after,.ct-minor-sixth:after,.ct-minor-third:after,.ct-octave:after,.ct-perfect-fifth:after,.ct-perfect-fourth:after,.ct-square:after{content:"";clear:both}.ct-label{fill:rgba(0,0,0,.4);color:rgba(0,0,0,.4);font-size:.75rem;line-height:1}.ct-grid-background,.ct-line{fill:none}.ct-chart-bar .ct-label,.ct-chart-line .ct-label{display:block;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}.ct-chart-donut .ct-label,.ct-chart-pie .ct-label{dominant-baseline:central}.ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-vertical.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-label.ct-vertical.ct-end{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:end}.ct-grid{stroke:rgba(0,0,0,.2);stroke-width:1px;stroke-dasharray:2px}.ct-point{stroke-width:10px;stroke-linecap:round}.ct-line{stroke-width:4px}.ct-area{stroke:none;fill-opacity:.1}.ct-bar{fill:none;stroke-width:10px}.ct-slice-donut{fill:none;stroke-width:60px}.ct-series-a .ct-bar,.ct-series-a .ct-line,.ct-series-a .ct-point,.ct-series-a .ct-slice-donut{stroke:#d70206}.ct-series-a .ct-area,.ct-series-a .ct-slice-pie{fill:#d70206}.ct-series-b .ct-bar,.ct-series-b .ct-line,.ct-series-b .ct-point,.ct-series-b .ct-slice-donut{stroke:#f05b4f}.ct-series-b .ct-area,.ct-series-b .ct-slice-pie{fill:#f05b4f}.ct-series-c .ct-bar,.ct-series-c .ct-line,.ct-series-c .ct-point,.ct-series-c .ct-slice-donut{stroke:#f4c63d}.ct-series-c .ct-area,.ct-series-c .ct-slice-pie{fill:#f4c63d}.ct-series-d .ct-bar,.ct-series-d .ct-line,.ct-series-d .ct-point,.ct-series-d .ct-slice-donut{stroke:#d17905}.ct-series-d .ct-area,.ct-series-d .ct-slice-pie{fill:#d17905}.ct-series-e .ct-bar,.ct-series-e .ct-line,.ct-series-e .ct-point,.ct-series-e .ct-slice-donut{stroke:#453d3f}.ct-series-e .ct-area,.ct-series-e .ct-slice-pie{fill:#453d3f}.ct-series-f .ct-bar,.ct-series-f .ct-line,.ct-series-f .ct-point,.ct-series-f .ct-slice-donut{stroke:#59922b}.ct-series-f .ct-area,.ct-series-f .ct-slice-pie{fill:#59922b}.ct-series-g .ct-bar,.ct-series-g .ct-line,.ct-series-g .ct-point,.ct-series-g .ct-slice-donut{stroke:#0544d3}.ct-series-g .ct-area,.ct-series-g .ct-slice-pie{fill:#0544d3}.ct-series-h .ct-bar,.ct-series-h .ct-line,.ct-series-h .ct-point,.ct-series-h .ct-slice-donut{stroke:#6b0392}.ct-series-h .ct-area,.ct-series-h .ct-slice-pie{fill:#6b0392}.ct-series-i .ct-bar,.ct-series-i .ct-line,.ct-series-i .ct-point,.ct-series-i .ct-slice-donut{stroke:#f05b4f}.ct-series-i .ct-area,.ct-series-i .ct-slice-pie{fill:#f05b4f}.ct-series-j .ct-bar,.ct-series-j .ct-line,.ct-series-j .ct-point,.ct-series-j .ct-slice-donut{stroke:#dda458}.ct-series-j .ct-area,.ct-series-j .ct-slice-pie{fill:#dda458}.ct-series-k .ct-bar,.ct-series-k .ct-line,.ct-series-k .ct-point,.ct-series-k .ct-slice-donut{stroke:#eacf7d}.ct-series-k .ct-area,.ct-series-k .ct-slice-pie{fill:#eacf7d}.ct-series-l .ct-bar,.ct-series-l .ct-line,.ct-series-l .ct-point,.ct-series-l .ct-slice-donut{stroke:#86797d}.ct-series-l .ct-area,.ct-series-l .ct-slice-pie{fill:#86797d}.ct-series-m .ct-bar,.ct-series-m .ct-line,.ct-series-m .ct-point,.ct-series-m .ct-slice-donut{stroke:#b2c326}.ct-series-m .ct-area,.ct-series-m .ct-slice-pie{fill:#b2c326}.ct-series-n .ct-bar,.ct-series-n .ct-line,.ct-series-n .ct-point,.ct-series-n .ct-slice-donut{stroke:#6188e2}.ct-series-n .ct-area,.ct-series-n .ct-slice-pie{fill:#6188e2}.ct-series-o .ct-bar,.ct-series-o .ct-line,.ct-series-o .ct-point,.ct-series-o .ct-slice-donut{stroke:#a748ca}.ct-series-o .ct-area,.ct-series-o .ct-slice-pie{fill:#a748ca}.ct-square{display:block;position:relative;width:100%}.ct-square:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:100%}.ct-square:after{display:table}.ct-square>svg{display:block;position:absolute;top:0;left:0}.ct-minor-second{display:block;position:relative;width:100%}.ct-minor-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:93.75%}.ct-minor-second:after{display:table}.ct-minor-second>svg{display:block;position:absolute;top:0;left:0}.ct-major-second{display:block;position:relative;width:100%}.ct-major-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:88.8888888889%}.ct-major-second:after{display:table}.ct-major-second>svg{display:block;position:absolute;top:0;left:0}.ct-minor-third{display:block;position:relative;width:100%}.ct-minor-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:83.3333333333%}.ct-minor-third:after{display:table}.ct-minor-third>svg{display:block;position:absolute;top:0;left:0}.ct-major-third{display:block;position:relative;width:100%}.ct-major-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:80%}.ct-major-third:after{display:table}.ct-major-third>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fourth{display:block;position:relative;width:100%}.ct-perfect-fourth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:75%}.ct-perfect-fourth:after{display:table}.ct-perfect-fourth>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fifth{display:block;position:relative;width:100%}.ct-perfect-fifth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:66.6666666667%}.ct-perfect-fifth:after{display:table}.ct-perfect-fifth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-sixth{display:block;position:relative;width:100%}.ct-minor-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:62.5%}.ct-minor-sixth:after{display:table}.ct-minor-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-golden-section{display:block;position:relative;width:100%}.ct-golden-section:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:61.804697157%}.ct-golden-section:after{content:"";display:table;clear:both}.ct-golden-section>svg{display:block;position:absolute;top:0;left:0}.ct-major-sixth{display:block;position:relative;width:100%}.ct-major-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:60%}.ct-major-sixth:after{display:table}.ct-major-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-seventh{display:block;position:relative;width:100%}.ct-minor-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:56.25%}.ct-minor-seventh:after{display:table}.ct-minor-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-seventh{display:block;position:relative;width:100%}.ct-major-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:53.3333333333%}.ct-major-seventh:after{display:table}.ct-major-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-octave{display:block;position:relative;width:100%}.ct-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:50%}.ct-octave:after{display:table}.ct-octave>svg{display:block;position:absolute;top:0;left:0}.ct-major-tenth{display:block;position:relative;width:100%}.ct-major-tenth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:40%}.ct-major-tenth:after{display:table}.ct-major-tenth>svg{display:block;position:absolute;top:0;left:0}.ct-major-eleventh{display:block;position:relative;width:100%}.ct-major-eleventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:37.5%}.ct-major-eleventh:after{display:table}.ct-major-eleventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-twelfth{display:block;position:relative;width:100%}.ct-major-twelfth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:33.3333333333%}.ct-major-twelfth:after{display:table}.ct-major-twelfth>svg{display:block;position:absolute;top:0;left:0}.ct-double-octave{display:block;position:relative;width:100%}.ct-double-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:25%}.ct-double-octave:after{display:table}.ct-double-octave>svg{display:block;position:absolute;top:0;left:0} 2 | -------------------------------------------------------------------------------- /dev_data/css/style.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | background-color:#E9F0F0; 3 | } 4 | .pop-up { 5 | z-index:111; 6 | background-color:#fff; 7 | box-shadow:0 12px 15px rgba(0, 0, 0, 0.4); 8 | padding:20px; 9 | position:absolute; 10 | } 11 | 12 | /* Setup */ 13 | input:invalid { 14 | border:2px solid red !important; 15 | } 16 | input:invalid ~ input[type=button] { 17 | pointer-events:none; 18 | opacity:0.5; 19 | } 20 | .col-sm-offset-1 { 21 | background-color:#fff; 22 | box-shadow:0 12px 15px rgba(0, 0, 0, 0.4); 23 | padding:20px; 24 | } 25 | 26 | /* device */ 27 | .block { 28 | background-color:#fff; 29 | box-shadow:0 12px 15px rgba(0, 0, 0, 0.4); 30 | padding:20px; 31 | margin:20px 0; 32 | } 33 | .history { 34 | background-color:#fff; 35 | box-shadow:0 12px 15px rgba(0, 0, 0, 0.4); 36 | padding:10px; 37 | margin:10px 15px 15px 5px; 38 | display:block; 39 | } 40 | .header { 41 | background-color:#fff; 42 | box-shadow:0 22px 22px -22px gray; 43 | margin:0 -15px 23px; 44 | padding:1px 50px 15px; 45 | border-radius:10px 10px 0 0; 46 | } 47 | .device { 48 | background-color:#F5F5F5; 49 | box-shadow:0 5px 25px rgba(0, 0, 0, 0.4); 50 | border-radius:10px; 51 | margin-top:5%; 52 | } 53 | @media (max-width:480px) { 54 | .block { 55 | margin:20px -15px; 56 | } 57 | #content .block { 58 | margin:30px -30px; 59 | } 60 | .device { 61 | margin-top:0; 62 | } 63 | .header { 64 | padding:1px 20px 15px; 65 | } 66 | } 67 | @media (min-width:1200px) { 68 | .block { 69 | margin:20px 15px; 70 | } 71 | } 72 | h5 { 73 | background-color:#4db6ac; 74 | color:#fff; 75 | margin-top:-40px; 76 | padding:10px 0; 77 | width:50%; 78 | text-align:center; 79 | text-transform:uppercase; 80 | } 81 | h5 a, h5 a:hover { 82 | color:#fff; 83 | } 84 | .add span { 85 | background-color:#c0c7ca; 86 | border-radius:100px; 87 | box-shadow:0 5px 25px rgba(0, 0, 0, 0.4); 88 | padding:0 20px; 89 | } 90 | .add { 91 | font-size:40px; 92 | } 93 | #date { 94 | text-transform:capitalize; 95 | } 96 | #content h1,#content h2,#content h3 { 97 | text-align:center; 98 | } 99 | #content ul li { 100 | text-align:left; 101 | } 102 | #title { 103 | margin:50px; 104 | } 105 | #language { 106 | margin-top:-45px; 107 | float:right; 108 | } 109 | 110 | /* loader */ 111 | .loader, .loader-bg:after { 112 | border:15px solid #fff; 113 | border-top:15px solid #FF851B; 114 | border-radius:50%; 115 | width:70px; 116 | height:70px; 117 | animation:spin 1s linear infinite; 118 | display:block; 119 | margin:0 auto; 120 | } 121 | .loader-bg:after { 122 | content: ''; 123 | position:fixed; 124 | left:50%; 125 | margin-left:-35px; 126 | top:150px; 127 | z-index:-999; 128 | } 129 | @keyframes spin { 130 | 0% { transform:rotate(0deg); } 131 | 100% { transform:rotate(360deg); } 132 | } 133 | 134 | ul#history { 135 | text-indent: .5em; 136 | border-left: .25em solid #c0c7ca; 137 | margin-left: 5px; 138 | } 139 | #history li { 140 | margin-left:-31px; 141 | } 142 | .alert ul{ 143 | margin-left: -20px; 144 | } 145 | .dropdown-menu { 146 | display: block; 147 | } 148 | .NaN,.nan { 149 | display: none; 150 | } 151 | .ct-label{ 152 | font-size:10px; 153 | } 154 | #timer-list,.timer-list { 155 | -webkit-columns:2; 156 | -moz-columns:2; 157 | columns:2; 158 | } 159 | 160 | #url-content { 161 | height:90%; 162 | left:-15px; 163 | position:fixed; 164 | top:0%; 165 | width:26%; 166 | overflow-y:auto; 167 | word-wrap:break-word; 168 | z-index:1; 169 | } 170 | 171 | #edit-content { 172 | height:100%; 173 | right:0; 174 | position:fixed; 175 | top:0%; 176 | width:25%; 177 | } 178 | 179 | #edit-json { 180 | width:100%; 181 | height:90%; 182 | } 183 | 184 | .index .col-md-6 { 185 | min-height: 390px; 186 | } 187 | 188 | .opt-img, .popup-img, .refresh-img, .help-img, .warning-img, .set-img, .download-img, .find-replace-img, .cloud-download-img, .cloud-upload-img, .cloud-img { 189 | display:inline-block; 190 | width:16px; 191 | height:16px; 192 | background-size:16px; 193 | background-position:center center; 194 | background-repeat:no-repeat; 195 | vertical-align:middle; 196 | margin-right:3px; 197 | } 198 | 199 | .popup-img {background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAM0lEQVQ4jWNgQAN+fgH/ScHo+oeiAUSbjMOi4WQAhsSAG0ByNFLNAIJOJlqCVAMGLPMAAM5NI5iNV9vsAAAAAElFTkSuQmCC);} 200 | .opt-img {background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAaklEQVQ4jWNgGErgPwMDQwg+BWtw4AIkA44jiWOAFThwHpIBR5DEqe8FGIiAKiYZwPx2AsmAYgbcYYMBYH47hmRAAQPusKG+F7CBNYRsQ1eM7sc1DAwMj7HIEZUOYAY8xCJHkqvISjT0AwCiojUjvxm5+AAAAABJRU5ErkJggg==);} 201 | .refresh-img {background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAtElEQVQ4jaWSUQrCMAyGv1eZY8/K5o4jDOrOIHgJ33olYUdQ8Aa7gNdw+pAMOnUpnT8UWtL/S0gCtopIPGq+/2t+AS1QpwJOag5PB1QpEK/GDHBADzyAMmbKP96jCoVc5sw7zbg3EhyAAdj+CrYKWBmAtf5pLEC2FFBr0BkABzyBzdyHDmlUuIE+uOfA2UhAhYyqRxo2luwNz5dKZFQD00U6pkBARtWo+arVLNKN6XIlyzS/AZEiKCyi36BoAAAAAElFTkSuQmCC);} 202 | .help-img {background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAWklEQVQ4je3RsQmAQBAEwOlFrMFGLMhKDD4SsT1jjYRP3vN9Qxc2He5YPkqPhO1hE7ocSDgqO+fA9gJYSkCUEIj+/y8oAKt4ttsZR+wtQE2mVuBCmgAYWgFwAo7ccHNmDIiwAAAAAElFTkSuQmCC);} 203 | .warning-img {background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAA+0lEQVQ4je3RMUoDURSF4S8qiDZiI9gLrsPGJdjYmMbGDQjauAWbNCJo4xos7Ay4BEFRQRBiIyLCaN7j2UxgHGaGTNKJF07x3uX8nMPlf8qTmA2cBU4TM1MDI3uJlGt3Ktgnq5H3ETDy9sHKxMDARSFdSqTA+USwIZsFyHWgP3oP2WgFe2Yhcl8AdgPdQvXbO+bbpDsqVd3JlQrQw7FgGeuRrzGAWcZaIyzRCVxVHOJX5cL/ZaJTCwxsl025sR+4qdlt1aVbjgyqTJFB5LVm95JYqkrXqzLk2o8c1O0Dx+V0i5HYAGxU5DsxVz7GSeQx8tRSD4Fe47X/9vwAgKkTxeU5B+oAAAAASUVORK5CYII=);} 204 | .set-img {background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAARElEQVQ4jd3QwQnAIBQE0VdSIjH2X1iCFyvwK4oLe5xlGXbPixyB/9bUM/A0+MPV++KOwKx2kA1wkCIwFAEHxREO5qcC4gcQtPOUOGgAAAAASUVORK5CYII=);} 205 | .download-img {background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgUlEQVQ4jc3RsQkCQRAF0BdpZjliIfYgGGgjdmAgV8gZqo2IXeyaKCzHrHecHDrwoz88dhn+aRok5A+5YFEDEg5YV/JGrjUkvxZrU77k9i2Qhyz0ZXogocVZfJ1eYFN02zHArOjmY4Bl0a2GAN1/3rHDHo9OlyLgFCBREo4R8Jt5AvM7bIF02g/DAAAAAElFTkSuQmCC);} 206 | .find-replace-img {background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAuklEQVQ4jc3OMUrDABTG8d8g1C2zdXDp7qaZM/UAHbqoJyi4dTGSMwRHD+BNbFfp6gFExGwtOOjyijFgEgiCf3jL9/j+7/FfOUSGGU5redKnfIU3fNZmjTOsusqXUShxggOkeKzJfmWE1yjXSeJyp2CCB4wb+XXk+/k75r7frHDe2Jd46ivIGrsUWyy6BBVe8IwlLnCHXYiLNsE03j7GfYg+sInLRUjyNkkXtyG5GSLJ8Y6jIZJB5R98ATFFLZPmfkCHAAAAAElFTkSuQmCC);} 207 | .cloud-img {background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAl0lEQVQ4jc3RsQnCUBhF4Q+sYhPE1i0cwk4LBTsncAI3cAexFXdQcQLR3tIFLKyExCYPQhCTmEIvHHjNOcX/+Of1MMQoe1deF1skSDMSbNApk9u45MQiJ0TvxBZm2H+QA4uiHOFYQQxc0c8HljXkPAfEcPsykGINzwaBO5ybBqYNAqtwyDkeNeVdOGJYjAEmJYwVvvG3ewFDm4AegEs/zQAAAABJRU5ErkJggg==);} 208 | 209 | .wifi-0-60 {background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAn0lEQVQ4jc3QTQpBYRgF4McUmxBhLEtQlJ0YGCkptiMpc2ITyhoY+Rka3Bujr9CNe5k49Q6f09vh31LHGGvscUWEAzaYoJYEm1jhlvKWaATcR5wBh4vRgyouXxScUA5fdDN+EaP9usM4Q8EwacgcFinwLAmHFLF7g7fIvyuACs4J+IjSJxzS8TxqhFZaHDJ6KBhkxSFzTL/FUJBitJ9yB0PAZo1JMnGDAAAAAElFTkSuQmCC)} 210 | .wifi-60-70 {background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAyElEQVQ4jc3QPU4CURTF8Z+tHxALbbWAioQSNmAkjonRhMKlUNBgY+MapCf0JFrIRoxrGKhVCt5LJmScGaDxJCd5ybv/e08O/03HaKCLK9wgCe8umjjKA+vo4LaiO4EBl+FKVTg6wYUQqZf5eMAIE3xgjimecJ+Zu8ZhTHGOO4yR4vcPp3gNs2ebPQwLwE0P8oo8CJHL4Lc8OOoUXwXwJ2pFC6CNZQ68QKsMjnrETwb+Rr8qHPWSWfC8LRz1jtmuMOvCTvZZUKoVlb9FjouX7uMAAAAASUVORK5CYII=)} 211 | .wifi-70-80 {background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAvklEQVQ4jc3QPUoDYRjE8V+t8aOJrYGsRcB69wJicLNNLLyExzCk8RKSkDOkyFEC3kAhWPtR+C4sL+u6GxsHBp7mP88w/Df1kCDDFW6QhzvDBQ7rwBOkmLR0GhgwCF/awqVznAuVxnsEXOOgbHEWtShwjwfMwl1E3/vxDgluscQrPiO/YIEphnVDwqoGjP30EwyneG6AtzhqCoBLvNXAO4x+g0vd4aMCv/vep5MeKwHzrnCpDdb7wnCsxWh/0hf7eTrEN0FYwgAAAABJRU5ErkJggg==)} 212 | .wifi-80-90 {background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAt0lEQVQ4jc3QMUoDQRiG4UdMFZWtTKuQtbKQENhcIChZ6zRJIYg30cYm90nhJcxRTJ2kmYEhbMzupskHHwzDvO/8/JxbrpFjhDEmKMN5hAdcVYEZCrzWbBEYcB9+qQvHlrgTRnppIXhGN07RazhFidv9PeQNBP2qRcIwefSBL3ziPbkfHIKhgzessN3rL+a4/E8AT1hXCP7weAyOmWGTwBtM68Ixi0Tw3RSGC/xg2QaOyXBziuBodokKLg6opnwBAAAAAElFTkSuQmCC)} 213 | .wifi-90-100 {background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAkklEQVQ4jc3QMQrCQBhE4Q9ipYKNsVU0HkCFpNJKIq73v4+FWTASzUYbB37Y5s0Oj3/LFAUqnHFFaN4Vtph0gTOUuCVe2TBg1fySCscLWGomXb4oqDGOKxYDVwTkrx6KAQWbLpFwSIB372AY4fQBPiL7VMBDat0Bt6T1JdeWGjBPhWOepa6HwjF7PdL6kkmQ9lPu7WseJohUYa0AAAAASUVORK5CYII=)} 214 | .wifi-key {background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAmUlEQVQ4je3QvwqBYRgF8F8mVkZGuRq2b1AuQhnYldyMzaCU2ahcA8kNUL6B5VVvL58/M6fO8jznnOfp8EeMHrbIsccUlU/NA1yfcIXSO3MN52C4YI5DFDJBt4AN6ETiYQhtFnyUMoN2NBiFgNY3AVWcwiDHAsdINA7CDOvEXL/30C+4sExKnEW7B3SxCV/sQnnlRPMy4FdxA96PRYPg7eb3AAAAAElFTkSuQmCC)} 215 | .wifi {display:inline-block;width:16px;height:16px;background-size:16px;background-position:center center;background-repeat:no-repeat;vertical-align:middle;margin-right:3px;} 216 | 217 | 218 | -------------------------------------------------------------------------------- /dev_data/donate.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | Donate 10 | 11 | 12 | 18 |
19 |
20 |

Спасибо! / Thanks! / Paldies!

21 |
22 |

Web Developer
Веб разработчик

23 |

Ренат К.

24 | 25 | AdvCash 26 |
    27 |
  • U 0586 7862 1354
  • 28 |
  • E 8788 6352 1126
  • 29 |
  • R 7705 0208 6566
  • 30 |
31 | PayPal 32 | 35 | WebMoney 36 |
    37 |
  • Z242847016348
  • 38 |
  • R466173026928
  • 39 |
  • E555861976545
  • 40 |
41 |

Arduino Developer
Ардуино разработчик

42 |

Сергей Т.

43 | 44 | YandexMoney 45 |
    46 |
  • 410011740665305
  • 47 |
48 | WebMoney 49 |
    50 |
  • Z343206590467
  • 51 |
  • R124424038680
  • 52 |
  • U883416626152
  • 53 |
  • E211342115147
  • 54 |
55 |
56 |
57 |
58 | 59 | 60 | -------------------------------------------------------------------------------- /dev_data/help.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | Помощь 14 | 15 | 16 |
17 |
18 |

Wiki

19 |

Sonoff WiFi switch, RGB, Jalousie

20 |
21 |

GET JSON

22 |

GET /config.live.json

23 |

Динамические данные

24 |
Loading...
25 | 26 |

GET /config.options.json

27 |

Основные настройки

28 |
Loading...
29 | 30 |

GET /config.setup.json

31 |

Данные для страинцы "Конфигурация"

32 |
Loading...
33 | 34 |

GET /config.save.json

35 |

Файл хранится на ESP и содержит в себе все настройки (Эти настройки восстанавливаются посте рестарта)

36 |
Loading...
37 | 38 |

GET /ssdp.list.json

39 |

Количество устройст найденых в локальной сети.

40 |
Loading...
41 | 42 |

GET /modules.json

43 |
Loading...
44 | 45 |

GET /timer.save.json

46 |

Таймеры включения\выключения устройсва

47 |
Loading...
48 | 49 |

GET /lang/lang.ru.json

50 |

Изменить язык можно GET запросом /lang?set=en

51 |
Loading...
52 |

Cookie

53 |

Список ваших Cookie

54 |
Loading...
55 |
56 |
57 | 58 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /dev_data/js/chart.js: -------------------------------------------------------------------------------- 1 | function loadChart(chartId,chartUrl,charOptions,charRefresh,charPoints){ 2 | var valTime; 3 | function viewTime() { 4 | var now = new Date(); 5 | return now.getHours()+':'+now.getMinutes()+':'+now.getSeconds(); 6 | } 7 | 8 | var ne = document.createElement('h2'); 9 | ne.id = chartId+'-title'; 10 | document.getElementById(chartId).parentNode.insertBefore(ne,document.getElementById(chartId)); 11 | 12 | function adddata() { 13 | var xmlHttp=createXmlHttpObject(); 14 | xmlHttp.open("GET", chartUrl, true); 15 | xmlHttp.send(null); 16 | xmlHttp.onload = function() { 17 | var module=JSON.parse(xmlHttp.responseText); 18 | if (module.title != null) { 19 | document.getElementById(chartId+'-title').innerHTML = module.title; 20 | } 21 | if (typeof module.data != null && typeof module.data2 != null && typeof module.data3 != null) { 22 | for (var i = 0; i < module.data.length; i++) { 23 | var points = (charPoints?charPoints:module.points); 24 | if (points != null && points <= LineChart.data.series[0].length) { 25 | LineChart.data.labels.shift(); 26 | LineChart.data.series[0].shift(); 27 | if (module.data2 != null) { 28 | LineChart.data.series[1].shift(); 29 | } 30 | if (module.data3 != null) { 31 | LineChart.data.series[2].shift(); 32 | } 33 | } 34 | 35 | LineChart.data.series[0].push(module.data[i]); 36 | if (module.data2 != null) { 37 | LineChart.data.series[1].push(module.data2[i]); 38 | } 39 | if (module.data3 != null) { 40 | LineChart.data.series[2].push(module.data3[i]); 41 | } 42 | if (module.label != null) { 43 | LineChart.data.labels.push(module.label[i]); 44 | } else { 45 | LineChart.data.labels.push(viewTime()); 46 | } 47 | LineChart.update(); 48 | } 49 | } 50 | 51 | charOptions = (charOptions=!'{}'?charOptions:'{'+module.options+'}'); 52 | //LineChart.update(,,charOptions); 53 | 54 | var strUser = module.refresh; 55 | var strUser = (charRefresh?charRefresh:module.refresh); 56 | clearInterval(valTime); 57 | valTime=setInterval(function(){adddata();}, strUser); 58 | } 59 | } 60 | var LineChart = Chartist.Line("#"+chartId, { 61 | labels: [], 62 | series: [[],[],[]] 63 | //}, {fullWidth:true}); 64 | }, charOptions); 65 | adddata(); 66 | } 67 | -------------------------------------------------------------------------------- /dev_data/js/siema.min.js: -------------------------------------------------------------------------------- 1 | "use strict";var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};!function(t){function e(t){var e=this;this.config=s({selector:".siema",duration:200,easing:"ease-out",perPage:1,startIndex:0,draggable:!0,threshold:20,loop:!1},t),this.selector="string"==typeof this.config.selector?document.querySelector(this.config.selector):this.config.selector,this.selectorWidth=this.selector.getBoundingClientRect().width,this.innerElements=[].slice.call(this.selector.children),this.currentSlide=this.config.startIndex,this.init(),window.addEventListener("resize",function(){e.resize(),e.slideToCurrent()}),this.config.draggable&&(this.pointerDown=!1,this.drag={start:0,end:0},this.selector.addEventListener("touchstart",this.touchstartHandler.bind(this)),this.selector.addEventListener("touchend",this.touchendHandler.bind(this)),this.selector.addEventListener("touchmove",this.touchmoveHandler.bind(this),{passive:!0}),this.selector.addEventListener("mousedown",this.mousedownHandler.bind(this)),this.selector.addEventListener("mouseup",this.mouseupHandler.bind(this)),this.selector.addEventListener("mouseleave",this.mouseleaveHandler.bind(this)),this.selector.addEventListener("mousemove",this.mousemoveHandler.bind(this)))}e.prototype.init=function(){if(null===this.selector)throw new Error("Something wrong with your selector 😭");this.resolveSlidesNumber(),this.selector.style.overflow="hidden",this.sliderFrame=document.createElement("div"),this.sliderFrame.style.width=this.selectorWidth/this.perPage*this.innerElements.length+"px",this.sliderFrame.style.webkitTransition="all "+this.config.duration+"ms "+this.config.easing,this.sliderFrame.style.transition="all "+this.config.duration+"ms "+this.config.easing,this.config.draggable&&(this.sliderFrame.style.cursor="-webkit-grab");for(var t=document.createDocumentFragment(),e=0;et&&(this.perPage=this.config.perPage[t])}},e.prototype.prev=function(){0===this.currentSlide&&this.config.loop?this.currentSlide=this.innerElements.length-this.perPage:this.currentSlide=Math.max(this.currentSlide-1,0),this.slideToCurrent()},e.prototype.next=function(){this.currentSlide===this.innerElements.length-this.perPage&&this.config.loop?this.currentSlide=0:this.currentSlide=Math.min(this.currentSlide+1,this.innerElements.length-this.perPage),this.slideToCurrent()},e.prototype.goTo=function(t){this.currentSlide=Math.min(Math.max(t,0),this.innerElements.length-1),this.slideToCurrent()},e.prototype.slideToCurrent=function(){this.sliderFrame.style[i]="translate3d(-"+this.currentSlide*(this.selectorWidth/this.perPage)+"px, 0, 0)"},e.prototype.updateAfterDrag=function(){var t=this.drag.end-this.drag.start;t>0&&Math.abs(t)>this.config.threshold?this.prev():t<0&&Math.abs(t)>this.config.threshold&&this.next(),this.slideToCurrent()},e.prototype.resize=function(){this.resolveSlidesNumber(),this.selectorWidth=this.selector.getBoundingClientRect().width,this.sliderFrame.style.width=this.selectorWidth/this.perPage*this.innerElements.length+"px"},e.prototype.clearDrag=function(){this.drag={start:0,end:0}},e.prototype.touchstartHandler=function(t){t.stopPropagation(),this.pointerDown=!0,this.drag.start=t.touches[0].pageX},e.prototype.touchendHandler=function(t){t.stopPropagation(),this.pointerDown=!1,this.sliderFrame.style.webkitTransition="all "+this.config.duration+"ms "+this.config.easing,this.sliderFrame.style.transition="all "+this.config.duration+"ms "+this.config.easing,this.drag.end&&this.updateAfterDrag(),this.clearDrag()},e.prototype.touchmoveHandler=function(t){t.stopPropagation(),this.pointerDown&&(this.drag.end=t.touches[0].pageX,this.sliderFrame.style.webkitTransition="all 0ms "+this.config.easing,this.sliderFrame.style.transition="all 0ms "+this.config.easing,this.sliderFrame.style[i]="translate3d("+(this.currentSlide*(this.selectorWidth/this.perPage)+(this.drag.start-this.drag.end))*-1+"px, 0, 0)")},e.prototype.mousedownHandler=function(t){t.preventDefault(),t.stopPropagation(),this.pointerDown=!0,this.drag.start=t.pageX},e.prototype.mouseupHandler=function(t){t.stopPropagation(),this.pointerDown=!1,this.sliderFrame.style.cursor="-webkit-grab",this.sliderFrame.style.webkitTransition="all "+this.config.duration+"ms "+this.config.easing,this.sliderFrame.style.transition="all "+this.config.duration+"ms "+this.config.easing,this.drag.end&&this.updateAfterDrag(),this.clearDrag()},e.prototype.mousemoveHandler=function(t){t.preventDefault(),this.pointerDown&&(this.drag.end=t.pageX,this.sliderFrame.style.cursor="-webkit-grabbing",this.sliderFrame.style.webkitTransition="all 0ms "+this.config.easing,this.sliderFrame.style.transition="all 0ms "+this.config.easing,this.sliderFrame.style[i]="translate3d("+(this.currentSlide*(this.selectorWidth/this.perPage)+(this.drag.start-this.drag.end))*-1+"px, 0, 0)")},e.prototype.mouseleaveHandler=function(t){this.pointerDown&&(this.pointerDown=!1,this.sliderFrame.style.cursor="-webkit-grab",this.drag.end=t.pageX,this.sliderFrame.style.webkitTransition="all "+this.config.duration+"ms "+this.config.easing,this.sliderFrame.style.transition="all "+this.config.duration+"ms "+this.config.easing,this.updateAfterDrag(),this.clearDrag())};var i=function(){var t=document.documentElement.style;return"string"==typeof t.transform?"transform":"WebkitTransform"}(),s=Object.assign||function(t){for(var e=1;eSoon...", 31 | 32 | "_comment": "---page.htm?setup---", 33 | "LangDevice":"Device Name", 34 | "LangSpace":"Space", 35 | "LangSetting":"Open Developer settings
Carefully, ill-considered actions could damage the device.", 36 | "LangOtheSetting":"Othe options", 37 | "LangPass":"Password", 38 | "LangWiFi1":"WiFi Network Name", 39 | "LangWiFi2":"Connecting to the Wi-Fi router", 40 | "LangWiFi3":"Please connect to your router. It enables you to control your device on the local network.", 41 | "LangWiFi4":"After the device is connected to the router, Wi-Fi will disappear.", 42 | "LangGMT1":"Time zone GMT", 43 | "LangGMT2":"Auto search and save GMT zone", 44 | "LangAP":"Access point", 45 | "LangDdns1":"Dynamic DNS", 46 | "LangDdns2":"At 15, 30, 45, 00 minutes every hour the device switched to the link. You can use freemyip.com or dyndns.dk and this make a domain on a dynamic IP. That will allow comfortable use ifttt.com. Video option DDNS and ifttt.com", 47 | "LangTime1":"Device time", 48 | "LangTime2":"Synchronize time", 49 | "LangReset1":"Reload this device", 50 | "LangReset2":"Changes will take effect after a reboot. Please reboot your device.", 51 | "LangReset3":"Are you sure you want to reboot the device?", 52 | "LangRedirect":"Auto redirection through", 53 | "LangHiddenWifi":"Connect to hidden WiFi network", 54 | "LangType":"Type device", 55 | 56 | "_comment": "---page.htm?timer---", 57 | "LangTime3":"Set time", 58 | "LangTime4":"Time", 59 | "LangList":"List", 60 | "LangDay":"Day", 61 | "LangTimer":"Timers", 62 | "LangWorkTime":"Work time", 63 | "LangMin.":"Min.", 64 | "LangDel":"Delete", 65 | "LangMon":"Monday", 66 | "LangTue":"Tuesday", 67 | "LangWed":"Wednesday", 68 | "LangThu":"Thursday", 69 | "LangFri":"Friday", 70 | "LangSat":"Saturday", 71 | "LangSun":"Sunday", 72 | "LangAll":"Always", 73 | "LangSwitch.":"Switch", 74 | "LangTime6":"Attention. By adjusting the time write \"0\" before a single digit. \"Work time\" is optional.", 75 | 76 | "_comment": "---page.htm?relay---", 77 | "LangIfttt1":"With service ifttt.com device can be switched in many scenarios, such as: new message on facebook, twitter, more... setting in Google calendar, mail, etc. More information how to do this, you can see in the video here.
Local link:
Global link:
", 78 | "LangOn":"On", 79 | "LangOff":"Off", 80 | "LangPir1":"PIR Sensor", 81 | "LangPir2":"Time in seconds how long the LED will light on the sensor to movement. If the sensor is not connected PIR, the value should be 0.", 82 | 83 | "_comment": "---page.htm?rgb---", 84 | "LangClose":"Close", 85 | "LangTime5":"Alarm time work", 86 | "LangTime8":"How many minutes of play?", 87 | "LangTime9":"minutes", 88 | "LangColor1":"Red", 89 | "LangColor2":"Green", 90 | "LangColor3":"Blue", 91 | "LangSpeed":"Speed", 92 | "LengBrightness":"Brightness", 93 | 94 | "_comment": "---page.htm?jalousie---", 95 | "LangClose":"Closen", 96 | "LangOpen":"Open", 97 | "LangTurn":"Turn of blinds", 98 | 99 | "_comment": "---page.htm?scenary---", 100 | "LangScenary":"Scenary", 101 | "LangIf":"If", 102 | "LangThen":"Then", 103 | "LangScenery1":"Here you can automatize your life. :) . How it works?", 104 | "LangAddScenery":"Add scenery", 105 | "LangLess":"less", 106 | "LangMore":"more", 107 | "LangEqual":"equal", 108 | "LangNotEqual":"Not equal", 109 | "LangOr":"or", 110 | "Langrgbon":"On RGB", 111 | "Langrgboff":"Off RGB", 112 | "Langrgbnot":"Turn RGB", 113 | "Langrelayon":"On relay", 114 | "Langrelayoff":"off relay", 115 | "Langrelaynot":"Turn relay", 116 | "Langjalousieopen":"Open jalousie", 117 | "Langjalousieclose":"Close jalousie", 118 | "Langjalousienot":"Turn jalousie", 119 | "LangstateJalousie":"State jalousie", 120 | "LangstateRGB":"State RGB", 121 | "LangstateRelay":"State relay", 122 | "LangturnSensor":"Tern sensor", 123 | "Langtime":"Time", 124 | "Langweekday":"Weekday", 125 | "LangcolorRGB":"color RGB", 126 | "LangspeedRGB":"Speed RGB", 127 | "LangbrightnessRGB":"Brightness RGB", 128 | "LangmodeRGB":"Mode RGB", 129 | "LangReceived":"Received", 130 | 131 | "_comment": "---page.htm?chart---", 132 | "LangTemperature":"Temperature", 133 | "LangHumidity":"Humidity", 134 | "LangChart":"Chart", 135 | "LangAnalog":"Analog (ADC/A0)" 136 | } 137 | -------------------------------------------------------------------------------- /dev_data/lang/lang.lv.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment": "---INDEX.HTM---", 3 | "LangDevices":"Galvena", 4 | "LangOptions1":"Vadības lapa", 5 | "LangSetting3":"Ekstras iestatījumi", 6 | "LangExample":"Piemērs", 7 | "LangSec":"Sek.", 8 | "LangOff.":"Izsl.", 9 | "LangOn.":"Iesl.", 10 | "LangSave":"Saglabāt", 11 | "LangCancel":"Atcelt", 12 | "LangHistory":"Vēsture", 13 | "LangLoading":"Ielādē...", 14 | "LangSorting":"Sorting", 15 | "LangSearch1":"Meklēt", 16 | "LangSearch4":"Lūdzu, uzgaidiet, skenējot tīklu.", 17 | "LangOptions2":"Mainīt konfigurāciju ierīcē, jūs varat \"Vadība lapa\".", 18 | "LangLanguage":"Latviski", 19 | "LangConnect1":"Pagaidiet, ierīce savienojas ar tīklu.", 20 | "LangConnect2":"IP adresi ierīces jūsu tīklā būs:", 21 | "LangCookie":"Atjaunot slēgtas bloki", 22 | "LangHedden":"Slēpt bloku?\nTo var atjaunot no \"Ekstras iestatījumi\".", 23 | "LangRefresh":"Atjaunat", 24 | "LangHelp":"Palīdziba", 25 | "LangNewDesign":"jauns dizains", 26 | "LangDesign":"Dizains", 27 | "LangQuestion":"Vai tu esi pārliecināts?", 28 | "LangUpgrade":"Installet jaunu versiju?", 29 | "LangDonate":"Atbalstīt projektu", 30 | "LangSoon":"", 31 | 32 | "_comment": "---page.htm?setup---", 33 | "LangDevice":"Ierīces nosaukums", 34 | "LangSpace":"Space", 35 | "LangSetting":"Atvērt Izstrādātāja iestatījumus
Uzmanīgi, nepārdomāta rīcība var bojāt ierīci.", 36 | "LangOtheSetting":"Citi iestadijumi", 37 | "LangPass":"Parole", 38 | "LangWiFi1":"WiFi punkta nosaukums", 39 | "LangWiFi2":"Pieslēgšanās pie Wi-Fi routera", 40 | "LangWiFi3":"Lūdzu, izveidojiet savienojumu ar savu maršrutētāju. Tas ļauj jums kontrolēt savu ierīci uz vietējo tīklu, izmantojot savu maršrutētāju.", 41 | "LangWiFi4":"Kad ierīce ir savienota ar routeru, pazudīs tās Wi-Fi punkts.", 42 | "LangGMT1":"Laika zona GMT", 43 | "LangGMT2":"Automātiska laika joslas izvēle un saglabāšana", 44 | "LangAP":"Piekļuves punkts", 45 | "LangDdns1":"Dinamisks DNS", 46 | "LangDdns2":"Katras stundas 15., 30., 45., 00 minūtē iekārta iet uz linku. Jūs varat izmantot freemyip.com vai dyndns.dk un tādējādi izveidot sev domēnu ar dinamisko IP adresi. Tas ļaus ērti izmantot ifttt.com. Paskaties video", 47 | "LangTime1":"Plkst. uz ierīces tagad", 48 | "LangTime2":"Sinhronizēt laiku", 49 | "LangReset1":"Pārlādēt šo ierīci", 50 | "LangReset2":"Izmaiņas stāsies spēkā pēc restarta. Lūdzu, restartējiet ierīci.", 51 | "LangReset3":"Vai jūs tiešām vēlaties restartēt ierīci?", 52 | "LangRedirect":"Auto novirzīšana caur", 53 | "LangHiddenWifi":"Savienojumu ar slēpto WiFi tīklam", 54 | "LangType":"Ierīce tips", 55 | 56 | "_comment": "---page.htm?timer---", 57 | "LangTime3":"Uzstadinal laiks", 58 | "LangTime4":"Laiks", 59 | "LangList":"Saraksts", 60 | "LangDay":"Diena", 61 | "LangTimer":"Taimeri", 62 | "LangWorkTime":"Darba laiks", 63 | "LangMin.":"Min.", 64 | "LangDel":"Dzest", 65 | "LangMon":"Pirmdiena", 66 | "LangTue":"Otrdiena", 67 | "LangWed":"Trešdiena", 68 | "LangThu":"Ceturdiena", 69 | "LangFri":"Piektdiena", 70 | "LangSat":"Sestdiena", 71 | "LangSun":"Svetdiena", 72 | "LangAll":"Visas", 73 | "LangSwitch.":"Pārs.", 74 | "LangTime6":"Svarigi. Norādot laiku, rakstīt \"0\" pirms vienciparu skaitļa.", 75 | 76 | "_comment": "---page.htm?relay---", 77 | "LangIfttt1":"Ar pakalpojumu ifttt.com ierīcei var pieslēgt vairākus scenārijus, piemēram: jauna vēstule facebook, twitter, vairāk... pasākums Google kalendārā, e-pasts un daudz ko citu. Vairāk informācijas par to, kā to izdarīt, jūs varat redzēt video šeit.
Local saite:
Global saite:
", 78 | "LangOn":"Ieslēgt", 79 | "LangOff":"Izslēgt", 80 | "LangPir1":"PIR Sensor", 81 | "LangPir2":"Ja sensors nav pieslēgts PIR, vērtība 0.", 82 | 83 | "_comment": "---page.htm?rgb---", 84 | "LangClose":"Aizvert", 85 | "LangTime5":"Signāla darba laiks", 86 | "LangTime8":"Uz cik minūtes ieslegt?", 87 | "LangTime9":"minūtes", 88 | "LangColor1":"Sarkans", 89 | "LangColor2":"Zaļš", 90 | "LangColor3":"Zils", 91 | "LangSpeed":"Atrums", 92 | "LengBrightness":"Spilgtums", 93 | 94 | "_comment": "---page.htm?jalousie---", 95 | "LangClose":"Aizvert", 96 | "LangOpen":"Atvert", 97 | "LangTurn":"Motora apgriezienu skaits", 98 | 99 | "_comment": "---page.htm?scenary---", 100 | "LangScenary":"Scenāriji", 101 | "LangIf":"Ja", 102 | "LangThen":"Tā", 103 | "LangScenery1":"Zemāk jūs varat automatizēt dažus uzdevumus. kā tas darbojas", 104 | "LangAddScenery":"Pievienot scenāriju", 105 | "LangLess":"less", 106 | "LangMore":"more", 107 | "LangEqual":"equal", 108 | "LangNotEqual":"Not equal", 109 | "LangOr":"or", 110 | "Langrgbon":"Ieslēdziet RGB", 111 | "Langrgboff":"Izslēdziet RGB", 112 | "Langrgbnot":"Pārslēgt RGB", 113 | "Langrelayon":"Ieslēdziet rele", 114 | "Langrelayoff":"Izslēdziet rele", 115 | "Langrelaynot":"Pārslēgt rele", 116 | "Langjalousieopen":"Atveriet žalūzijas", 117 | "Langjalousieclose":"Aizvērt žalūzijas", 118 | "Langjalousienot":"Pārslēgt žalūzijas", 119 | "LangstateJalousie":"Nosacījums žalūzijas", 120 | "LangstateRGB":"Nosacījums RGB", 121 | "LangstateRelay":"Nosacījums rele", 122 | "LangturnSensor":"Apgrozījumi sensors", 123 | "Langtime":"Laiks", 124 | "Langweekday":"Nedēļas diena", 125 | "LangcolorRGB":"Цвет RGB", 126 | "LangspeedRGB":"Скорость RGB", 127 | "LangbrightnessRGB":"Яркость RGB", 128 | "LangmodeRGB":"Динамический режим RGB", 129 | "LangReceived":"Беспроводной приемник", 130 | 131 | "_comment": "---page.htm?chart---", 132 | "LangTemperature":"Temperatūra", 133 | "LangHumidity":"Mitrums", 134 | "LangChart":"Grafik", 135 | "LangAnalog":"Analog (ADC/A0)" 136 | } 137 | -------------------------------------------------------------------------------- /dev_data/lang/lang.ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment": "---INDEX.HTM---", 3 | "LangDevices":"Главная", 4 | "LangOptions1":"Управления", 5 | "LangSetting3":"Конфигурация", 6 | "LangExample":"Пример", 7 | "LangSec":"Сек.", 8 | "LangOff.":"выкл", 9 | "LangOn.":"вкл", 10 | "LangSave":"Сохранить", 11 | "LangCancel":"Отмена", 12 | "LangHistory":"История", 13 | "LangLoading":"Загрузка...", 14 | "LangSorting":"Сортировка", 15 | "LangSearch1":"Поиск", 16 | "LangSearch4":"Пожалуйста подождите, идет сканирование сети.", 17 | "LangOptions2":"Изменить конфигурацию модуля вы можете на \"Cтранице управления\"", 18 | "LangLanguage":"Русский", 19 | "LangConnect1":"Подождите, модуль подключается к вашей сети.", 20 | "LangConnect2":"IP адрес модуля в вашей сети:", 21 | "LangCookie":"Восстановить закрытые блоки", 22 | "LangHedden":"Скрыть блок?\nЕго можно будет восстановить на странице \"Конфигурация\".", 23 | "LangRefresh":"Обновить", 24 | "LangHelp":"Помощь", 25 | "LangDesign":"вид", 26 | "LangNoTimers":"Таймер не установлен", 27 | "LangQuestion":"Вы уверены?", 28 | "LangUpgrade":"Установить новое обновление?", 29 | "LangDonate":"Поддержи проект", 30 | "LangSoon":"", 31 | 32 | "_comment": "---page.htm?setup---", 33 | "LangDevice":"Имя модуля", 34 | "LangSpace":"Пространство", 35 | "LangSetting":"Настройки разработчика
Осторожно, непродуманные действия могут повредить устройство.", 36 | "LangOtheSetting":"Дополнительные настройки", 37 | "LangPass":"Пароль", 38 | "LangWiFi1":"Имя Wi-Fi сети", 39 | "LangWiFi2":"Подключение к Wi-Fi роутеру", 40 | "LangWiFi3":"Пожалуйста подключитесь к своему роутеру. Это позволит управлять вашим устройством в локальной сети.", 41 | "LangWiFi4":"После того как устройство подключается к роутеру, его Wi-Fi исчезнет.", 42 | "LangGMT1":"Временная зона GMT", 43 | "LangGMT2":"Автоопределение и сохранение зоны", 44 | "LangAP":"Точка доступа", 45 | "LangDdns1":"Динамический DNS", 46 | "LangDdns2":"В 15, 30, 45, 00 минут каждого часа устройство переходить по ссылке. Вы можете воспользоваться freemyip.com или dyndns.dk и таким образом сделать себе домен на динамическом IP. Что позволит комфортно пользоваться ifttt.com. Посмотрите видео о настройки DDNS и ifttt.com", 47 | "LangTime1":"Время модуля", 48 | "LangTime2":"Синхронизировать время", 49 | "LangReset1":"Перезагрузка модуля", 50 | "LangReset2":"Изменения вступят в силу после перезагрузки. Пожалуйста перезагрузите модуль.", 51 | "LangReset3":"Перезагрузить модуль?", 52 | "LangRedirect":"Авто перенаправление через", 53 | "LangHiddenWifi":"Подключится к скрытой WiFi сети", 54 | "LangType":"Тип модуля", 55 | 56 | "_comment": "---page.htm?timer---", 57 | "LangTime3":"Добавить таймер", 58 | "LangTime4":"время", 59 | "LangList":"Список", 60 | "LangDay":"день", 61 | "LangTimer":"Таймер", 62 | "LangWorkTime":"время работы", 63 | "LangMin.":"мин.", 64 | "LangDel":"Удалить", 65 | "LangMon":"Понедельник", 66 | "LangTue":"Вторник", 67 | "LangWed":"Среда", 68 | "LangThu":"Четверг", 69 | "LangFri":"Пятница", 70 | "LangSat":"Суббота", 71 | "LangSun":"Воскресенье", 72 | "LangAll":"Всегда", 73 | "LangSwitch.":"перекл", 74 | "LangTime6":"Настраивая время перед одиночными цифрами пишите 0. Ячейку \"Продолж. работы\" заполнять не обязательно.", 75 | 76 | "_comment": "---page.htm?relay---", 77 | "LangIfttt1":"С помощью сервиса ifttt.com Устройство может включатся по многим сценариев, например: новое сообщение в facebook, twitter, подробнее... задания в Google calendar, почта и многое другое. Подробней о том как это сделать вы можете посмотреть видео здесь.
Локальная ссылка:
Глобальная ссылка:
", 78 | "LangOn":"Включить", 79 | "LangOff":"Выключить", 80 | "LangPir1":"Датчик движения", 81 | "LangPir2":"Время в секундах как долго будет гореть LED от сенсора на движения. Если PIR сенсор не подключен, значение должно быть 0.", 82 | 83 | "_comment": "---page.htm?rgb---", 84 | "LangClose":"Закрыть", 85 | "LangTime5":"Время работы сигнала", 86 | "LangTime8":"На сколько минут включить?", 87 | "LangTime9":"минут", 88 | "LangColor1":"Красный", 89 | "LangColor2":"Зеленый", 90 | "LangColor3":"Синий", 91 | "LangSpeed":"Скорость", 92 | "LengBrightness":"Яркость", 93 | 94 | "_comment": "---page.htm?jalousie---", 95 | "LangClose":"Закрыть", 96 | "LangOpen":"Открыть", 97 | "LangTurn":"Обороты мотора", 98 | 99 | "_comment": "---page.htm?scenary---", 100 | "LangScenary":"Сценарии", 101 | "LangIf":"Если", 102 | "LangThen":"Тогда", 103 | "LangScenery1":"Ниже вы можете автоматизировать некоторые задачи. Посмотрите видео как это работает", 104 | "LangAddScenery":"Добавить сценарий", 105 | "LangLess":"Меньше", 106 | "LangMore":"Больше", 107 | "LangEqual":"Равно", 108 | "LangNotEqual":"Не равно", 109 | "LangOr":"или", 110 | "Langrgbon":"Включить RGB", 111 | "Langrgboff":"Выключить RGB", 112 | "Langrgbnot":"Переключить RGB", 113 | "Langrelayon":"Включить реле", 114 | "Langrelayoff":"Выключить реле", 115 | "Langrelaynot":"Переключить реле", 116 | "Langjalousieopen":"Открыть жалюзи", 117 | "Langjalousieclose":"Закрыть жалюзи", 118 | "Langjalousienot":"Переключить жалюзи", 119 | "LangstateJalousie":"Состояние жалюзи", 120 | "LangstateRGB":"Состояние RGB", 121 | "LangstateRelay":"Состояние реле", 122 | "LangturnSensor":"Сенсор оборотов", 123 | "Langtime":"Время", 124 | "Langweekday":"День недели", 125 | "LangcolorRGB":"Цвет RGB", 126 | "LangspeedRGB":"Скорость RGB", 127 | "LangbrightnessRGB":"Яркость RGB", 128 | "LangmodeRGB":"Динамический режим RGB", 129 | "LangReceived":"Беспроводной приемник", 130 | 131 | "_comment": "---page.htm?chart---", 132 | "LangTemperature":"Температура", 133 | "LangHumidity":"Влажность", 134 | "LangChart":"График", 135 | "LangAnalog":"Освещенность" 136 | } 137 | -------------------------------------------------------------------------------- /dev_data/lang/lang.ua.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment": "---INDEX.HTM---", 3 | "LangDevices":"Главная", 4 | "LangOptions1":"Сторінка керування", 5 | "LangSetting3":"Конфігурація", 6 | "LangExample":"Приклад", 7 | "LangSec":"Сек.", 8 | "LangOff.":"Вимк.", 9 | "LangOn.":"Увімк.", 10 | "LangSave":"Зберегти", 11 | "LangCancel":"Відмінити", 12 | "LangHistory":"Історія", 13 | "LangLoading":"Завантаження...", 14 | "LangSorting":"Сортування", 15 | "LangSearch1":"Пошук", 16 | "LangSearch4":"Будь ласка зачекайте, йде сканування мережі...", 17 | "LangOptions2":"Змінити конфігурацію пристрою Ви можете на \"Cторінка керування\"", 18 | "LangLanguage":"Українська", 19 | "LangConnect1":"Почекайте, пристрій підключається до Вашої мережі.", 20 | "LangConnect2":"IP адреса пристрою у Вашій мережі:", 21 | "LangCookie":"Відновити закриті блоки", 22 | "LangHedden":"Приховати блок?\nЙого можна буде відновити на сторінці \"Конфігурація\".", 23 | "LangRefresh":"Обновити", 24 | "LangHelp":"Допомога", 25 | "LangDesign":"Дизайн", 26 | "LangNoTimers":"Нема таймерів", 27 | "LangQuestion":"Ви впевнені?", 28 | "LangUpgrade":"Встановити нове оновлення?", 29 | "LangDonate":"Підтримай проект", 30 | "LangSoon":"", 31 | 32 | "_comment": "---page.htm?setup---", 33 | "LangDevice":"Ім’я пристрою", 34 | "LangSpace":"Простір", 35 | "LangSetting":"Відкрити настройки розробника
Обережно, непродумані дії можуть пошкодити пристрій.", 36 | "LangOtheSetting":"Другие настройки", 37 | "LangPass":"Пароль", 38 | "LangWiFi1":"Ім’я Wi-Fi мережі", 39 | "LangWiFi2":"Підключення до Wi-Fi роутера", 40 | "LangWiFi3":"Будь ласка підключіться до свого роутера. Це дозволить керувати Вашим пристроєм в локальній мережі.", 41 | "LangWiFi4":"Після того як пристрій підключиться до роутера, його Wi-Fi зникне.", 42 | "LangGMT1":"Часова зона GMT", 43 | "LangGMT2":"Автовизначення і збереження зони", 44 | "LangAP":"Точка доступу", 45 | "LangDdns1":"Динамічний DNS", 46 | "LangDdns2":"Кожні 15 хвилин кожної години пристрій переходить за посиланням. Ви можете використати freemyip.com или dyndns.dk і таким чином зробити собі домен на динамічному IP. Це дозволить комфортно користуватися ifttt.com. Посмотрите видео о настройки DDNS и ifttt.com", 47 | "LangTime1":"На пристрої зараз", 48 | "LangTime2":"Синхронізувати час", 49 | "LangReset1":"Перезавантажити пристрій", 50 | "LangReset2":"Зміни набудуть чинності після перезавантаження. Будь ласка перезавантажте пристрій.", 51 | "LangReset3":"Ви дійсно хочете перезавантажити пристрій?", 52 | "LangRedirect":"Авто перенаправлення через", 53 | "LangHiddenWifi":"Підключитися до прихованої WiFi мережі", 54 | "LangType":"Тип устройства", 55 | 56 | "_comment": "---page.htm?timer---", 57 | "LangTime3":"Встановити час", 58 | "LangTime4":"Час", 59 | "LangList":"Список", 60 | "LangDay":"День", 61 | "LangTimer":"Таймери", 62 | "LangWorkTime":"Тривал. роботи", 63 | "LangMin.":"Хв.", 64 | "LangDel":"Видалити", 65 | "LangMon":"Понеділок", 66 | "LangTue":"Вівторок", 67 | "LangWed":"Середа", 68 | "LangThu":"Четвер", 69 | "LangFri":"П’ятниця", 70 | "LangSat":"Субота", 71 | "LangSun":"Неділя", 72 | "LangAll":"Завжди", 73 | "LangSwitch.":"Перемк.", 74 | "LangTime6":"Налаштовуючи час перед одиночними цифрами пишіть 0. Комірку \"Тривал. роботи\" заповнювати не обов’язково.", 75 | 76 | "_comment": "---page.htm?relay---", 77 | "LangIfttt1":"За допомогою сервісу ifttt.com Пристрій може вмикатися використовуючи багато сценаріїв, наприклад: нове повідомлення в facebook, twitter, детальніше... завдання в Google calendar, пошчта та багато іншого. Детальніше про те як це зробити Ви можете переглянувши відео тут.
Локальне посилання:
Глобальне посилання:
", 78 | "LangOn":"Увімкнути", 79 | "LangOff":"Вимкнути", 80 | "LangPir1":"Датчик руху", 81 | "LangPir2":"Тривалість горіння LED ввімкненого датчиком руху в секундах. Якщо PIR сенсор не підключений, значення повинно бути 0.", 82 | 83 | "_comment": "---RGB.HTM---", 84 | "LangClose":"Закрити", 85 | "LangTime5":"Час роботи сигналу", 86 | "LangTime8":"На скільки хвилин увімкнути?", 87 | "LangTime9":"хвилин", 88 | "LangColor1":"Червоний", 89 | "LangColor2":"Зелений", 90 | "LangColor3":"Синій", 91 | "LangSpeed":"Швидкість", 92 | "LengBrightness":"Яскравість", 93 | 94 | "_comment": "---page.htm?jalousie---", 95 | "LangClose":"Закрити", 96 | "LangOpen":"Відкрити", 97 | "LangTurn":"Обороты мотора", 98 | 99 | "_comment": "---page.htm?scenary---", 100 | "LangScenary":"Сценарії", 101 | "LangIf":"Якщо", 102 | "LangThen":"Значить", 103 | "LangScenery1":"Нижче Ви можете автоматизувати деякі задачі. Посмотрите видео как это работает", 104 | "LangAddScenery":"Добавити сценарій", 105 | "LangLess":"Меньше", 106 | "LangMore":"Больше", 107 | "LangEqual":"Равно", 108 | "LangNotEqual":"Не равно", 109 | "LangOr":"или", 110 | "Langrgbon":"Включити RGB", 111 | "Langrgboff":"Виключити RGB", 112 | "Langrgbnot":"Переключити RGB", 113 | "Langrelayon":"Включити релє", 114 | "Langrelayoff":"Виключити релє", 115 | "Langrelaynot":"Переключити релє", 116 | "Langjalousieopen":"Відкрити жалюзі", 117 | "Langjalousieclose":"Закрити жалюзі", 118 | "Langjalousienot":"Переключити жалюзі", 119 | "LangstateJalousie":"Стан жалюзі", 120 | "LangstateRGB":"Стан RGB", 121 | "LangstateRelay":"Стан релє", 122 | "LangturnSensor":"Сенсор обертів", 123 | "Langtime":"Час", 124 | "Langweekday":"День тижня", 125 | "LangcolorRGB":"Колір RGB", 126 | "LangspeedRGB":"Швидкість RGB", 127 | "LangbrightnessRGB":"Яскравість RGB", 128 | "LangmodeRGB":"Динамічний режим RGB", 129 | "LangReceived":"Беспроводной приемник", 130 | 131 | "_comment": "---page.htm?chart---", 132 | "LangTemperature":"Температура", 133 | "LangHumidity":"Вологість", 134 | "LangChart":"Графік", 135 | "LangAnalog":"Analog (ADC/A0)" 136 | } 137 | -------------------------------------------------------------------------------- /dev_data/page.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 12 | 13 | 14 | 15 | 64 | 65 | 66 |
67 | 68 | 69 | 70 | 74 | 75 | 84 | 85 |
86 | 87 | 88 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ESP Flasher by onclick.lv 7 | 8 | 9 | 10 | 13 | 14 | 15 | 16 |
17 |
18 |
19 |
RGB Smart Home
20 | 21 |
22 |
23 | 24 | 25 |
26 |

RGB Smart Home

27 |

Connect the ESP, click on Connect, in the pop-up window select the required COM port and click Connect.

28 | 29 | Your browser does not support installing things on ESP devices. Use Google Chrome or Microsoft Edge. 30 | 31 |
32 |
33 |
34 |
35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /jalousie.ino: -------------------------------------------------------------------------------- 1 | // ---------------- Управление двигателем жалюзи 2 | void initJalousie() { 3 | // Сенсор будет работать по прерыванию 4 | int pinTurn = readArgsInt(); 5 | attachInterrupt(pinTurn, turn_0, FALLING ); 6 | sendOptions("pinTurn", pinTurn); 7 | int pinMotor1 = readArgsInt(); 8 | int pinMotor2 = readArgsInt(); 9 | sendOptions("pinMotor1", pinMotor1); 10 | sendOptions("pinMotor2", pinMotor2); 11 | pinMode(pinMotor1, OUTPUT); 12 | pinMode(pinMotor2, OUTPUT); 13 | digitalWrite(pinMotor1, HIGH); 14 | digitalWrite(pinMotor2, HIGH); 15 | sendStatus("stateJalousie", 1); 16 | sendStatus("turnSensor", 0); 17 | sendOptions("turn", jsonReadtoInt(configSetup, "turn")); 18 | sCmd.addCommand("jalousieopen", jalousieOpen); 19 | sCmd.addCommand("jalousieclose", jalousieClose); 20 | sCmd.addCommand("jalousienot", jalousieNot); 21 | sCmd.addCommand("jalousiestop", jalousieStop); 22 | sCmd.addCommand("jalousieturn", jalousieTurn); 23 | commandsReg("jalousieopen", "jalousie"); 24 | commandsReg("jalousieclose", "jalousie"); 25 | commandsReg("jalousienot", "jalousie"); 26 | //commandsReg("jalousiestop", "jalousie"); 27 | //commandsReg("jalousieturn", "jalousie"); 28 | HTTPWAN.on("/jalousie", jalousieddns); // реакция на запрос 29 | HTTPWAN.on("/jalousieopen", jalousieopenddns); // реакция на запрос 30 | HTTPWAN.on("/jalousieclose", jalousiecloseddns); // реакция на запрос 31 | modulesReg("jalousie"); 32 | } 33 | 34 | void jalousieddns() { 35 | jalousieNot(); 36 | HTTPWAN.send(200, "text/plain", "Ok"); 37 | } 38 | void jalousieopenddns() { 39 | jalousieOpen(); 40 | HTTPWAN.send(200, "text/plain", "Ok"); 41 | } 42 | void jalousiecloseddns() { 43 | jalousieClose(); 44 | HTTPWAN.send(200, "text/plain", "Ok"); 45 | } 46 | void jalousie() { 47 | jalousieNot(); 48 | HTTP.send(200, "text/plain", "Ok"); 49 | } 50 | void jalousieopen() { 51 | jalousieOpen(); 52 | HTTP.send(200, "text/plain", "Ok"); 53 | } 54 | void jalousieclose() { 55 | jalousieClose(); 56 | HTTP.send(200, "text/plain", "Ok"); 57 | } 58 | 59 | 60 | // Выполняется при вращение сенсора 61 | void turn_0() { 62 | static unsigned long millis_prev; 63 | // Устроняем дребезг контакта 64 | if (millis() - 500 > millis_prev) { 65 | //Текущее состояние оборотов 66 | int turnSensor = jsonReadtoInt(configJson, "turnSensor"); 67 | turnSensor++; // счетчик количества оборотов 68 | flag = sendStatus("turnSensor", turnSensor); 69 | int turn = jsonReadtoInt(configSetup, "turn"); 70 | if (turnSensor == turn) { //Останавливаем 71 | configJson = jsonWrite(configJson, "turnSensor", 0); 72 | command = "jalousiestop"; 73 | 74 | } 75 | } 76 | millis_prev = millis(); 77 | } 78 | 79 | 80 | void jalousieOpen() { 81 | if (!getStatusInt("stateJalousie")) { 82 | flag = sendStatus("stateJalousie", 1); 83 | digitalWrite(getOptionsInt("pinMotor1"), LOW); 84 | digitalWrite(getOptionsInt("pinMotor2"), HIGH); 85 | topicPub("/Jalousie_not/status", String(getStatusInt("stateJalousie")), 1 ); 86 | } 87 | } 88 | 89 | 90 | 91 | 92 | void jalousieClose() { 93 | if (getStatusInt("stateJalousie")) { 94 | flag = sendStatus("stateJalousie", 0); 95 | digitalWrite(getOptionsInt("pinMotor1"), HIGH); 96 | digitalWrite(getOptionsInt("pinMotor2"), LOW); 97 | topicPub("/Jalousie_not/status", String(getStatusInt("stateJalousie")), 1 ); 98 | } 99 | } 100 | 101 | 102 | void jalousieStop() { 103 | digitalWrite(getOptionsInt("pinMotor1"), HIGH); 104 | digitalWrite(getOptionsInt("pinMotor2"), HIGH); 105 | 106 | } 107 | 108 | void jalousieTurn() { 109 | configSetup = jsonWrite(configSetup, "turn", readArgsInt()); 110 | sendOptions("turn", jsonReadtoInt(configSetup, "turn")); 111 | saveConfigSetup (); 112 | } 113 | 114 | void jalousieNot() { 115 | if (getStatusInt("stateJalousie")) { 116 | jalousieClose(); 117 | } 118 | else { 119 | jalousieOpen(); 120 | } 121 | } 122 | 123 | // читает данные из раздела state строки json и возвращает строку для смены класса кнопки 124 | String jalousieStatus(String json, String state) { 125 | String out = "{}"; 126 | if (jsonReadtoInt(json, state)) { 127 | out = jsonWrite(out, "title", "{{LangClose}}"); 128 | out = jsonWrite(out, "class", "btn btn-block btn-lg btn-info"); 129 | } 130 | else { 131 | out = jsonWrite(out, "title", "{{LangOpen}}"); 132 | out = jsonWrite(out, "class", "btn btn-block btn-lg btn-primary"); 133 | 134 | } 135 | return out; 136 | } 137 | 138 | 139 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RGB Smart home", 3 | "version": "3.0", 4 | "new_install_prompt_erase": true, 5 | "builds": [ 6 | { 7 | "chipFamily": "ESP8266", 8 | "parts": [ 9 | { "path": "./build/build.0x00000_flash_size_1Mb.256Kb_2017.10.11.bin", "offset": 0 }, 10 | { "path": "./build/spiffs.0xBB000_flash_size_1Mb.256Kb_2017.10.11.bin","offset": 765952 } 11 | ] 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /pre-commit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cat dev_data/css/chartist.min.css dev_data/css/bootstrap.min.css dev_data/css/style.css > dev_data/css/build.css 3 | cat dev_data/js/chartist.min.js dev_data/js/chart.js > dev_data/js/build.chart.js 4 | 5 | #find ./dev_data -iname "*.htm" -type f -exec sed -i 's/vvda$today/v07.06.2017/gi' {} \; 6 | 7 | gzip -vrkf dev_data/*.htm 8 | gzip -vrkf dev_data/css/*.css 9 | gzip -vrkf dev_data/js/*.js 10 | gzip -vrkf dev_data/lang/lang.*.json 11 | 12 | mv dev_data/*.htm.gz data/ 13 | mv dev_data/js/*.js.gz data/js 14 | mv dev_data/css/*.css.gz data/css 15 | mv dev_data/lang/*.json.gz data/lang 16 | 17 | rm dev_data/css/build.css 18 | rm dev_data/js/build.chart.js 19 | 20 | rm data/css/chartist.min.css.gz 21 | rm data/css/bootstrap.min.css.gz 22 | rm data/css/style.css.gz 23 | rm data/js/chartist.min.js.gz 24 | rm data/js/chart.js.gz 25 | rm data/js/siema.min.js.gz 26 | 27 | #test -f *.generic.bin && cp *.generic.bin build/build.generic_flash_size_1Mb.254Kb_`date '+%G.%m.%d'`.bin 28 | FILE_SUM=`md5sum rgb.ino.generic.bin` 29 | COPY_SUM=`md5sum ./build/$(ls -lt ./build | head -n2 |tail -n1 | awk '{print $9}')` 30 | if [ "$FILE_SUM" != "$COPY_SUM" ] 31 | then 32 | cp rgb.ino.generic.bin build/build.0x00000_flash_size_1Mb.256Kb_`date '+%G.%m.%d'`.bin 33 | fi 34 | 35 | 36 | cp /tmp/arduino_build_*/rgb.spiffs.bin ./build/spiffs.0xBB000_flash_size_1Mb.256Kb_`date '+%G.%m.%d'`.bin 37 | -------------------------------------------------------------------------------- /rgb.ino: -------------------------------------------------------------------------------- 1 | #include //Содержится в пакете 2 | #include //Содержится в пакете 3 | #include //Содержится в пакете 4 | #include //Содержится в пакете 5 | #include //Содержится в пакете 6 | //#include //Содержится в пакете 7 | #include //Содержится в пакете 8 | #include //Содержится в пакете 9 | #include //Содержится в пакете 10 | #include //Содержится в пакете 11 | #include //Содержится в пакете 12 | #include //Ставим через менеджер библиотек 13 | #include //https://github.com/Imroy/pubsubclient 14 | //#include 15 | //#include 16 | #include //https://github.com/Toshik/TickerScheduler 17 | #include //https://github.com/tretyakovsa/ESP8266-StringCommand 18 | // Библиотеки устройств 19 | #include //https://github.com/markruys/arduino-DHT 20 | #include //Ставим через менеджер библиотек 21 | #include //Ставим через менеджер библиотек 22 | #include //https://github.com/adafruit/Adafruit_NeoPixel 23 | #include //https://github.com/MTJoker/WS2812FX 24 | #include //https://github.com/sui77/rc-switch/ 25 | 26 | 27 | #define d18b20PIN 14 28 | DHT dht; 29 | RCSwitch mySwitch = RCSwitch(); 30 | 31 | // DNSServer для режима AP 32 | DNSServer dnsServer; 33 | 34 | // Web интерфейсы для устройства 35 | ESP8266WebServer HTTP(80); 36 | 37 | // Обнавление прошивки 38 | ESP8266HTTPUpdateServer httpUpdater; 39 | ESP8266WebServer HTTPWAN; 40 | 41 | // Для файловой системы 42 | File fsUploadFile; 43 | 44 | // Для тикера 45 | Ticker motion; 46 | 47 | // Для поиска других устройств по протоколу SSDP 48 | WiFiUDP udp; 49 | WiFiClient wclient; 50 | PubSubClient client(wclient); 51 | // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 52 | OneWire oneWire(d18b20PIN); 53 | 54 | // Pass our oneWire reference to Dallas Temperature. 55 | DallasTemperature d18b20(&oneWire); 56 | 57 | WS2812FX ws2812fx = WS2812FX(); 58 | 59 | 60 | TickerScheduler ts(5); 61 | 62 | boolean secTest = true; 63 | StringCommand sCmd; // The demo StringCommand object 64 | String command = ""; 65 | 66 | String Lang = ""; // файлы языка web интерфейса 67 | String chipID = ""; 68 | String configJson = "{}"; // Здесь все статусы 69 | String configOptions = "{}"; // Здесь опции для всех страниц 70 | String configSetup = "{}"; // Здесь данные для setup 71 | String configLive = "{}"; // Здесь внутренние данные обмен пинами и тд 72 | String ssdpList = "{}"; 73 | String regCommands = "{}"; 74 | String jsonTimer = "{}"; 75 | String previousSetup; 76 | String Scenary; 77 | String Timerset = ""; 78 | String modules = "{\"ip\":\"\",\"SSDP\":\"\",\"space\":\"\",\"module\":[]}"; 79 | String addressList = "{\"ssdpList\":[]}"; 80 | String sensorsList = "{}"; 81 | String prefix = "/IoTmanager"; 82 | boolean flag = false; 83 | boolean thenOk; 84 | 85 | 86 | void setup() { 87 | 88 | //Serial.begin(115200); 89 | //delay(100); 90 | TickerScheduler(1); 91 | initCMD(); 92 | chipID = String( ESP.getChipId() ) + "-" + String( ESP.getFlashChipId() ); 93 | FS_init(); // Включаем работу с файловой системой 94 | // ----------------- начинаем загрузку 95 | configSetup = readFile("config.save.json", 4096); 96 | 97 | //previousSetup = configSetup; 98 | //configSetup ="{}"; 99 | //Serial.println(configSetup); 100 | //savePrevious(); 101 | 102 | 103 | 104 | 105 | configSetup = jsonWrite(configSetup, "time", "00:00:00"); 106 | //configJson = jsonWrite(configJson, "setIndex", jsonRead(configSetup, "setIndex")); 107 | configOptions = jsonWrite(configOptions, "lang", jsonRead(configSetup, "lang")); 108 | configOptions = jsonWrite(configOptions, "SSDP", jsonRead(configSetup, "SSDP")); 109 | configOptions = jsonWrite(configOptions, "space", jsonRead(configSetup, "space")); 110 | configOptions = jsonWrite(configOptions, "spiffsData", jsonRead(configSetup, "spiffsData")); 111 | configOptions = jsonWrite(configOptions, "buildData", jsonRead(configSetup, "buildData")); 112 | String configs = jsonRead(configSetup, "configs"); 113 | configs.toLowerCase(); 114 | // ----------- Грузим конфигурацию устройства 115 | String test = readFile("configs/"+configs+".txt", 4096); 116 | test.replace("\r\n", "\n"); 117 | test +="\n"; 118 | // ----------- запускаем необходимые всегда модули 119 | sCmd.readStr("wifi 12"); 120 | sCmd.readStr("Upgrade"); 121 | sCmd.readStr("SSDP"); 122 | sCmd.readStr("HTTP"); 123 | // ----------- Выполняем запуск кофигурации 124 | goCommands(test); 125 | test = ""; 126 | configSetup = jsonWrite(configSetup, "mac", WiFi.macAddress().c_str()); 127 | configSetup = jsonWrite(configSetup, "ip", WiFi.localIP().toString()); 128 | 129 | initScenary(); 130 | } 131 | 132 | void loop() { 133 | ts.update(); 134 | sCmd.readStr(command); 135 | command = ""; 136 | dnsServer.processNextRequest(); 137 | HTTPWAN.handleClient(); 138 | yield(); 139 | HTTP.handleClient(); 140 | yield(); 141 | handleUDP(); 142 | handleMQTT(); 143 | ws2812fx.service(); 144 | handleScenary(); 145 | //RCRCreceiv(); 146 | } 147 | -------------------------------------------------------------------------------- /tutorial/breadboard.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/tutorial/breadboard.gif -------------------------------------------------------------------------------- /tutorial/esp8266_12_wiring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/tutorial/esp8266_12_wiring.png -------------------------------------------------------------------------------- /tutorial/esp8266_esp01_horizontal-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/tutorial/esp8266_esp01_horizontal-01.png -------------------------------------------------------------------------------- /tutorial/esp8266_esp12e_horizontal-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/tutorial/esp8266_esp12e_horizontal-01.png -------------------------------------------------------------------------------- /tutorial/esp8266_wiring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/tutorial/esp8266_wiring.png -------------------------------------------------------------------------------- /tutorial/jalousie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/tutorial/jalousie.png -------------------------------------------------------------------------------- /tutorial/nodemcu-flasher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/tutorial/nodemcu-flasher.png -------------------------------------------------------------------------------- /tutorial/question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/tutorial/question.png -------------------------------------------------------------------------------- /tutorial/schematic.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/tutorial/schematic.gif -------------------------------------------------------------------------------- /tutorial/screen1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/tutorial/screen1.png -------------------------------------------------------------------------------- /tutorial/screen2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/tutorial/screen2.png -------------------------------------------------------------------------------- /tutorial/screen3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/tutorial/screen3.png -------------------------------------------------------------------------------- /tutorial/screen4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/tutorial/screen4.png -------------------------------------------------------------------------------- /tutorial/smart-home-icon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/tutorial/smart-home-icon.gif -------------------------------------------------------------------------------- /tutorial/sonoff.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renat2985/rgb/116bd4b5765525ae7860c2a19064089ed76bfd61/tutorial/sonoff.jpg --------------------------------------------------------------------------------