diff --git a/data/conf.csv b/data/conf.csv index 40b35ae1..2d2f8d1d 100644 --- a/data/conf.csv +++ b/data/conf.csv @@ -1 +1 @@ -Удалить;Тип элемента;Id;Виджет;Имя вкладки;Имя виджета;Позиция виджета \ No newline at end of file +Тип элемента;Id;Виджет;Имя вкладки;Имя виджета;Позиция виджета \ No newline at end of file diff --git a/data/css/build.css.gz b/data/css/build.css.gz index 4bf6e060..b62ceaf0 100644 Binary files a/data/css/build.css.gz and b/data/css/build.css.gz differ diff --git a/data/index.htm.gz b/data/index.htm.gz index 139f0040..073ff4ab 100644 Binary files a/data/index.htm.gz and b/data/index.htm.gz differ diff --git a/data/index.json.gz b/data/index.json.gz new file mode 100644 index 00000000..52c4df62 Binary files /dev/null and b/data/index.json.gz differ diff --git a/data/items/button-in.txt b/data/items/button-in.txt index d01c6f0b..5b6c3d66 100644 --- a/data/items/button-in.txt +++ b/data/items/button-in.txt @@ -1 +1 @@ -0;button-in;switch1;toggle;Кнопки;Свет;1;pin[2];db[20] \ No newline at end of file +button-in;id;toggle;Кнопки;Освещение;order;pin[2];db[20] \ No newline at end of file diff --git a/data/items/button-out-i.txt b/data/items/button-out-i.txt index 3db63e7f..31098078 100644 --- a/data/items/button-out-i.txt +++ b/data/items/button-out-i.txt @@ -1 +1 @@ -0;button-out;light1;toggle;Кнопки;Свет;1;pin[12];inv[1];st[1] \ No newline at end of file +button-out;id;toggle;Кнопки;Освещение;order;pin[12];inv[1];st[1] \ No newline at end of file diff --git a/data/items/button-out.txt b/data/items/button-out.txt index 3c6ba8c0..bc0b4148 100644 --- a/data/items/button-out.txt +++ b/data/items/button-out.txt @@ -1 +1 @@ -0;button-out;light1;toggle;Кнопки;Свет;1;pin[12];st[0] \ No newline at end of file +button-out;id;toggle;Кнопки;Освещение;order;pin[12];st[0] \ No newline at end of file diff --git a/data/items/pwm-out.txt b/data/items/pwm-out.txt index 41eec52d..cdb96ec0 100644 --- a/data/items/pwm-out.txt +++ b/data/items/pwm-out.txt @@ -1 +1 @@ -0;pwm-out;volume;range;Кнопки;Свет;1;pin[12];st[500] \ No newline at end of file +pwm-out;id;range;Ползунки;Яркость;order;pin[12];st[500] \ No newline at end of file diff --git a/data/js/build.chart.js.gz b/data/js/build.chart.js.gz index ac021668..654707fd 100644 Binary files a/data/js/build.chart.js.gz and b/data/js/build.chart.js.gz differ diff --git a/data/js/function.js.gz b/data/js/function.js.gz index 443fbca2..10c9953a 100644 Binary files a/data/js/function.js.gz and b/data/js/function.js.gz differ diff --git a/data/setn.device.json b/data/setn.device.json index e400db6c..e494cab8 100644 --- a/data/setn.device.json +++ b/data/setn.device.json @@ -40,7 +40,6 @@ { "type": "csv", "title": [ - "checkbox", "html", "text", "text", @@ -50,12 +49,9 @@ ], "state": "conf.csv", "style": "width:100%;", - "action": "/set?delete", + "action": "/set?save", "class": "btn btn-block btn-default" }, - { - "type": "hr" - }, { "type": "link", "title": "Удалить все", diff --git a/doc/1.txt b/doc/1.txt new file mode 100644 index 00000000..d08be432 --- /dev/null +++ b/doc/1.txt @@ -0,0 +1,566 @@ +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) + +## Возможности + + - Объединение различных по типу и назначению устройств: управление, получение данных, и настройка параметров - всё в одном приложении + + - Взаимодействие с устройствами осуществляется через "облачный" сервис с использованием протокола mqtt, позволит контролировать их из любой точки Мира (при наличии доступа в Интернет) + + - Поддержка нескольких профилей и их переключение "на лету", дает возможность объединить устройства в группы + + +Настройка (после "прошивки") производится через веб-интерфейс, чтобы получить к нему доступ необходимо соединиться с WiFi AP устройства и набрать в адресной строке браузера http://192.168.4.1. +Далее выбрать типовой шаблон автоматизации, произвести настройку под свои требования и задачи. +Основные разделы интерфейса: конфигурация и сценарии. +В окне конфигурации задаются "объекты", "элементы управления" устройства (dashboard) - им устройство будет представлено в приложении компаньоне проекта. В окне сценариев задаются реакции на события и изменения в параметрах работы системы. + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) + +## Команды, назначение и применение + +Команды служат для настройки и управления устройством и его взаимодействия + +**`buttonSet 1 1`** Изменит состояние "кнопки" №1, установит его в значение 1 + +**`pinSet 13 0`** Установит GPIO 13 состояние 0 + +**`pinChange 13`** Состояние GPIO 13 будет изменено на противоположное + +**`pwmSet 1 500`** Настройка pwm №1 будет использовано значение 500 + +**`timeSet 1 08-00-00`** Установит для элемента ввода времени - inputTime значение 08:00:00 + +**`digitSet 1 56`** Элемент №1 (для цифровых параметров) отобразит число 56 + +**`stepperSet 1 100 1`** Шаговый двигатель №1 - вращение 100 "шагов" по часовой стрелке (для движения в обратную сторону используются отрицательные значения параметра) + +**`servoSet 1 180`** Сервопривод №1 принять положение 180° + +**`timerStart 1 60 sec`** Установить для таймера №1 обратный отсчёт в 60 секунд + +**`timerStop 1`** Остановить таймер №1 + +**`textSet 1 Привет`** Установить для элемента текстовое поле №1 - "привет" + +**`push Внимание Протечка`** Отправить push-уведомление с темой "внимание" и содержанием "протечка" + +**`firmwareUpdate`** Обновить прошивку устройства "по воздуху" + +**`firmwareVersion Версия прошивки Системные 1`** Узнать версию прошивки устройстве + +## Сценарии + +Элементарный блок в сценарии состоит из набора команд и триггера - условия для их выполнения + +**temp > 60** +digitSet 1 60 +stepperSet 1 100 1 +textSet 1 Перегрев +**end** + +Условие: когда температура превысит 60° +Запустит: команда шаговому двигателю, в приложение отправить сообщение и цифровое значение температуры. + +В сценарии может быть несколько блоков, при необходимости из приложения есть возможность "выключать" часть из них. +Неактивные блоки сценария будут проигнорированы. + +Для взаимодействия устройств между собой предусмотрены команды mqtt и http + +**temp > 60** +mqtt 154348-134 digitSet_1_56 +mqtt 154348-136 stepperSet _1_100_1 +http 192.168.1.10 textSet_1_Перегрев +**end** + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) +## 1.1 Объект "кнопка" + +(эти строки мы пишем в "конфигурации устройства") + +### a) кнопка управляющая выходом (пином). Пины нумеруются по системе нумирации gpio для esp контроллеров. + +`button 1 13 кухня освещение 0 1` + +**"button"** это объект создающий кнопку в приложении +**"1"** это номер этой кнопки (необходимый для ее аутентификации) +**"13"** это номер пина которым будет управлять данная кнопка +**"кухня"** это название кнопки в приложении +**"освещение"** это название вкладки в приложении на которой появится данная кнопка +**"0"** это начальное состояние кнопки при старте модуля (выкд 0, вкл 1) +**"1"** это уникальный номер и номер сортировки данной кнопки. Этот номер должен быть уникален для каждого объекта + + +### б) виртуальная кнопка - кнопка реакцию на которую можно задать в сценариях: + +`button 1 na запустить таймеры 0 1` + +**"button"** это объект создающий кнопку в приложении +**"1"** это номер этой кнопки (необходимый для ее аутентификации) +**"na"** абривиатура not available означающая что эта кнопка виртуальная и что пин не установлен +**"запустить"** это название кнопки в приложении +**"таймеры"** это название вкладки в приложении на которой появится данная кнопка +**"0"** это начальное состояние кнопки при старте модуля (выкд 0, вкл 1) +**"1"** это уникальный номер и номер сортировки данной кнопки. Этот номер должен быть уникален для каждого объекта + +### в) кнопка включающая и выключающая все сценарии: + +`button 1 scenario запустить таймеры 0 1` + +**"button"** это объект создающий кнопку в приложении +**"1"** это номер этой кнопки (необходимый для ее аутентификации) +**"scenario"** слово означающее что эта кнопка для управления сценариями +**"запустить"** это название кнопки в приложении +**"таймеры"** это название вкладки в приложении на которой появится данная кнопка +**"0"** это начальное состояние кнопки при старте модуля (выкд 0, вкл 1) +**"1"** это уникальный номер и номер сортировки данной кнопки. Этот номер должен быть уникален для каждого объекта + + +### г) кнопка включающая выключающая определенные блоки сценариев: + +`button 1 line1,line3, Включить#отправку#push Оповещение 0 1` + +**"button"** это объект создающий кнопку в приложении +**"1"** это номер этой кнопки (необходимый для ее аутентификации) +**"line1,line3,"** это блоки сценариев нумирация сверху вниз. Блоком считается выражение от начала до слова end +**"Включить#отправку#push"** это название кнопки в приложении +**"Оповещение"** это название вкладки в приложении на которой появится данная кнопка +**"0"** это начальное состояние кнопки при старте модуля (выкд 0, вкл 1) +**"1"** это уникальный номер и номер сортировки данной кнопки. Этот номер должен быть уникален для каждого объекта + +## 1.2 Команды управления объектом "кнопка" + +(эти строки мы пишем в "сценариях") + + ### а) Команда включения выключения кнопки по ее номеру + +`buttonSet 1 1` + +**"buttonSet"** команда управления объектом button +**"1"** номер кнопки которой будем управлять +**"1"** состояние включено, 0 - выключено + +### б) Команда изменения состояния кнопки на противоположное + +`buttonChange 1` + +**"buttonChange"** команда управления объектом button +**"1"** номер кнопки которой будем управлять + +## 1.3 Вызов событий объектом "кнопока" + +(эти строки мы пишем в "сценариях") + +объект button может быть равен либо 0 либо 1 + +`button1 = 1` +`button2 = 0` + +Пример использования: + +`button1 = 1` +`buttonSet 2 1` +`buttonSet 3 0` +`end` + + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) +## 2.1 Объект "физическая кнопка" + +`switch 1 0 10` + +**switch** это объект создающий физическую кнопку +**1** номер кнопки +**0** пин кнопки (при подключении необходим подтягивающий резистор) +**10** задержка для избавления от дребезга с мили секундах + +## 2.2 Вызов событий объектом "физическая кнопка" + +`switch1` может быть равна нулю или единицы, ноль - событие отбрасывания кнопки, единица - событие нажатия + +`switch1 = 1` +`buttonChange 1` +`end` + + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) +## 3.1 Объект "широтноимпульсная модуляция" + +`pwm 1 12 яркость освещение 1023 1` + +**"pwm"** это объект создающий управление шим в приложении в виде ползунка +**"1"** это номер этого объекта +**"12"** это номер пина на котором будет генерироваться шим заданной в приложении величены +**"Яркость"** это название кнопки в приложении +**"Оповещение"** это название вкладки в приложении на которой появится данная кнопка +**"1023"** это начальное значение шим сигнала и ползунка (изменяется от 0 до 1023) +**"1"** это уникальный номер и номер сортировки данной кнопки. Этот номер должен быть уникален для каждого объекта + +## 3.2 Команда управления объектом "широтноимпульсная модуляция" + +`pwmSet 1 500` + +**"pwmSet"** команда управления объектом +**"1"** номер объекта, которым будем управлять +**"500"** значение которое установится после выполнения команды (от 0 до 1023) + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) +## 4.1 Объект "окно ввода времени" + +`inputTime time1 Во#сколько#включить? Таймеры 20-30-00 1` + +**inputTime** это объект создающий окно ввода в приложении +**time1** переменная в которую будет записано время введенное в окно +**Во#сколько#включить?** это название окна в приложении +**Таймеры** это название вкладки в приложении +**20-30-00** начальное значение времени после загрузки устройства +**1** это уникальный номер и номер сортировки. Этот номер должен быть уникален для каждого объекта + +## 4.2 Управление объектом "окно ввода времени" + +`timeSet 1 08-00-00` + +**"timeSet"** команда управления объектом +**"1"** номер объекта, которым будем управлять в данном случае окном ввода с `time1` +**"08-00-00"** время которое хотим установить + +В окно ввода можно вводить время в приложении но если необходимо изменить время автоматически +по какому нибудь событию то можно использовать команду выше - **timeSet**. + +## 4.3 Вызов событий объектом "окно ввода времени" + +`timenow = time1` +`buttonSet 1 1` +`end` + +`timenow` всегда хранит в себе текущее время, и поэтому исходя из данного сценария кнопка номер 1 включится в то время которое будет введено в окно ввода `time1` + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) +## 5.1 Объект "окно ввода цифры" + +`inputDigit digit1 Через#сколько#секунд#выключить? Таймеры 5 2` + +**inputDigit** это объект создающий окно ввода в приложении +**digit1** переменная в которую будет записана цифра, введенная в окно +**Через#сколько#секунд#выключить?** это название окна в приложении +**Таймеры** это название вкладки в приложении +**5** цифра по умолчанию, после загрузки модуля +**2** это уникальный номер и номер сортировки. Этот номер должен быть уникален для каждого объекта + +## 5.2 Управление объектом "окно ввода цифры": + +`digitSet 1 56` + +**"digitSet"** команда управления объектом +**"1"** номер объекта, которым будем управлять в данном случае окном ввода с `digit1` +**"56"** цифра которую хотим установить + +В окно ввода можно вводить цифры в приложении, но если необходимо изменить цифру автоматически +по какому нибудь событию, то можно использовать команду выше - **digitSet**. + +## 5.3 Вызов событий объектом "окно ввода цифры" + +`dallas > digit1` +`buttonSet 1 0` +`end` + +`button1 = 1` +`timerStart 1 digit1 sec` +`end` + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) +## 6.1 Объект "dallas" (сенсор температуры ds18b20) + +`dallas temp1 2 123456 Водонагреватель,#t°C Термостат any-data 1` + +**dallas** это объект чтения датчика температуры +**2** пин датчика температуры +**Водонагреватель,#t°C** это название виджета в приложении +**Датчики** название вкладки в приложении +**any-data** или **progress-round** или **progress-line** три разных варианта виджета отображения +**1** это уникальный номер и номер сортировки. Этот номер должен быть уникален для каждого объекта + +## 6.2 Вызов событий объектом "dallas" + +В сценариях dallas можно сравнивать с переменной окна ввода `digit1` (>,<,>=,<=,=): + +`dallas > digit1` +`buttonSet 1 0` +`end` + +Или можно сравнивать с постоянной цифрой (>,<,>=,<=,=): + +`dallas > 60` +`buttonSet 1 0` +`end` + + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) +## 7.1 Объект "analog" (аналоговый вход контроллера) + +`analog adc 0 Аналоговый#вход,#% Датчики progress-round 310 620 1 100 1` + +**analog** это объект чтения аналогового входа +**adc** это переменная +**0** пин аналогового входа (для esp8266 всегда 0, для esp32 пока что не доделал читаться будет всегда пин 34) +**Аналоговый#вход,#%** это название виджета в приложении +**Датчики** название вкладки в приложении +**any-data** или **progress-round** или **progress-line** три разных варианта виджета отображения +**310** начальная величина читаемого диапазона +**620** конечная величина читаемого диапазона +**1** начальная величина выводимого диапазона +**100** конечная величина выводимого диапазона +**1** это уникальный номер и номер сортировки. Этот номер должен быть уникален для каждого объекта + +## 7.2 Вызов событий объектом "analog" + +В сценариях analog можно сравнивать с переменной окна ввода `digit1` (>,<,>=,<=,=): + +`analog > digit1` +`buttonSet 1 0` +`end` + +Или можно сравнивать с постоянной цифрой (>,<,>=,<=,=): + +`analog > 50` +`buttonSet 1 0` +`end` + + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) +## 8.1 Объект "level" (ультразвуковой дальномер JSN-SR04T, HC-SR04, HY-SRF05) + +`level Вода#в#баке,#% Датчики any-data 125 20 1` + +**level** это объект чтения датчика расстояния +**Вода#в#баке** это название виджета в приложении +**Датчики** название вкладки в приложении +**any-data** или **progress-round** или **progress-line** три разных варианта отображения виджета +**125** расстояние от датчика до дна бака в сантиметрах +**20** расстояние от датчика до поверхности воды, когда бак полный, в сантиметрах +**1** это уникальный номер и номер сортировки. Этот номер должен быть уникален для каждого объекта + +Подключать дальномер нужно: + +| | trig | echo | +| :-: | :-: | :-: | +| wemos | D5 | D6 | +| esp | 14 | 12 | + +## 8.2 Вызов событий объектом "level" + +В сценариях level можно сравнивать с переменной окна ввода `digit1` (>,<,>=,<=,=): + +`level > digit1` +`buttonSet 1 0` +`end` + +Или можно сравнивать с постоянной цифрой (>,<,>=,<=,=): + +`level > 95` +`buttonSet 1 0` +`end` + + + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) +## 9.1 Объект "dht" (Сенсоры DHT11, DHT22, DHT33, DHT44, AM2302, RHT03) + +dhtT DHT11 2 Температура#DHT,#t°C Датчики any-data 1 +dhtH DHT11 2 Влажность#DHT,#% Датчики any-data 2 +dhtComfort Степень#комфорта: Датчики 3 +dhtPerception Восприятие: Датчики 4 +dhtDewpoint Точка#росы: Датчики 5 + +**dhtT** или **dhtH** температура или влажность +**DHT11** или **DHT22** чтение DHT11 или DHT22, DHT33, DHT44, AM2302, RHT03 соответственно +**2** пин датчика +**Температура#DHT,#t°C** это название виджета в приложении +**Датчики** название вкладки в приложении +**any-data** или **progress-round** или **progress-line** три разных варианта отображения виджета +**1** это уникальный номер и номер сортировки. Этот номер должен быть уникален для каждого объекта + +## 9.2 Вызов событий объектом "dhtT" или "dhtH" + +В сценариях "dhtT" или "dhtH" можно сравнивать с переменной окна ввода `digit1` (>,<,>=,<=,=): + +`dhtT > digit1` +`buttonSet 1 0` +`end` + +`dhtH > digit1` +`buttonSet 1 0` +`end` + +Или можно сравнивать с постоянной цифрой (>,<,>=,<=,=): + +`dhtT > 50` +`buttonSet 1 0` +`end` + +`dhtH < 40` +`buttonSet 1 0` +`end` + + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) +## 10.1 Объект "stepper" (Драйвер шагового двигателя A4988) + +stepper 1 12 4 +stepper 2 13 5 + +**stepper** объект создающий шаговый двигатель +**1** номер шаговика +**12** номер пина количества шагов +**4** номер пина направления + +## 10.2 управление объектом "stepper" + +`stepperSet 1 200 1` + +**stepperSet** команда управления шаговым двигателем +**1** номер шагового двигателя (их может быть не более двух) +**200** количество шагов (обратное направление отрицательное значение параметра) +**1** интервал между шагами (мс) + +`button1 = 1` +`stepperSet 1 200 1` +`end` +`button1 = 0` +`stepperSet 1 -200 1` +`end` + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) +## 11.1 Объект "обратный таймер" + +Прежде чем читать этот раздел запустите пресет №3 на устройстве. +Нажав на кнопку "Выберите во что вы хотите превратить esp" + +Можно использовать цифры из окон ввода: + +`timerStart 1 digit1 sec` + +Можно писать цифры прям в объект: + +`timerStart 1 10 sec` + +Можно установить часы минуты или секунды: + +`timerStart 1 10 sec` +`timerStart 1 10 min` +`timerStart 1 10 hours` + +Используем это объект в сценариях вот так: + +`button1 = 1` +`timerStart 1 digit1 sec` +`end` + +Смысл в том что при нажатии на кнопку один запуститься обратный отчет, на величину digit1 секунд. Если напишем например: + +`dallas < 60` +`timerStart 1 digit1 sec` +`end` + +то такой же отчет запустится когда значение температуры вырастит больше 60 градусов. Таким образом обратный отчет можно запустить реакцией на любое событие. Итак теперь обратный отчет запущен, обратный таймер уменьшается, и нам надо назначить действие на тот момент когда он обнулится. Для этого я придумал выражение: `timer1 = 0` + +Используем его и в общем получаем вот такой сценарий: + +`button1 = 1` +`timerStart 1 digit1 sec` +`end` +`timer1 = 0` +`buttonSet 1 0` +`end` + +Когда таймер закончит отсчёт, кнопка станет "неактивной". Используйте преет №3, как пример подобного сценария +Например: + +`dallas < 60` +`buttonSet 1 0` +`buttonSet 2 0` +`pwmSet 1 1023` +`mqtt 2653450020 buttonChange_1` +`mqtt 2653450020 pinSet_13_1` +`http 192.168.1.32 pinSet_14_1` +`end` + +Вот что может произойти на разных устройствах по одному событию повышения температуры... + + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) +## 12 Журнал (лог) данных + + +`logging analog 1 100 slow Аналоговый#вход Датчики 7` + +**logging** объект для логирования +**analog** или **dhtT** или **dhtH** какой сенсор будем логировать, можно указать любой +**1** период между точками в минутах +**100** количество точек (старые точки будут удаляться по мере добавления новых) +**slow** или **fast** метод выгрузки графика в приложение, slow - выгружает график по одной точке (меньше расходуется оперативка, лучше использовать для esp8266), fast - выгрузка графика сразу (больше расход оперативки, подходит для esp32) +**Аналоговый#вход** название графика в приложении +**Датчики** название вкладки в приложении +**7** это уникальный номер и номер сортировки. Этот номер должен быть уникален для каждого объекта + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) +## 13 Взаимодействие устройств между собой + +Устройства могут между собой обмениваться командами. Команды можно отправлять по http или по mqtt. +По событию на одном устройстве можно вызвать действие на другом. Например на esp01 стоит датчик температуры, реле стоит на esp02. + +Настройки esp01: + +`dhtT temp 2 dht11 Температура#DHT,#t°C Датчики any-data 1` + +`temp < 40` +`http 192.168.10.25 buttonSet_1_1` +`end` + +Настройки esp02: + +`button 1 13 Включить#реле Реле 0 1` + +И теперь когда температура датчика на esp01 станет меньше 40 градусов то на esp02 будет отправлена команда на включение кнопки: buttonSet_1_1 + +Если вы хотите отправить команду через mqtt то сценарий будет выглядеть следующим образом: + +`temp < 40` +`mqtt 12343442-12413131 buttonSet_1_1` +`end` + +где `12343442-12413131` id esp02 той на которую отправляем команду. Id можно взять в веб интерфейсе на странице конфигурация устройства. Или в списке устройств в сети. + +Теперь рассмотрим вариант внешнего управления esp с помощью get запросов. + +`http://192.168.88.239/cmd?command=buttonSet%201%201` + +Разберем эту строку. Сама команда в ней выглядит вот так: buttonSet%201%201. `%20` заменяют пробел. + +То есть что бы составить get запрос на изменение например pwm нужно: + +Взять команду `pwmSet 1 500` +Заменить в ней пробелы на `%20` получится так: `pwmSet%201%20500` +И добавить ее в конец строки `http://192.168.88.239/cmd?command=` где указывается ip адрес устройства + +В итоге получится http://192.168.88.239/cmd?command=pwmSet%201%20500 + + + + + + \ No newline at end of file diff --git a/doc/2.txt b/doc/2.txt new file mode 100644 index 00000000..529f22bb --- /dev/null +++ b/doc/2.txt @@ -0,0 +1,85 @@ +# В этой инструкции будет описано как с esp отправлять email и push + +# Часть 1. Привязать email и pushbullet к сайту pushingbox + +### 1. Необходимо перейти на сайт: [pushingbox](https://www.pushingbox.com/) +### 2. Войти с помощью google +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_1.png) +### 3. Перейти в мои сервисы и добавить новый сервис +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_2.png) +### 4. Нас интересуют два сервиса email и pushbullet +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_4%2B.png) +### 5. Выбираем сначало сервис для отправки email. В окно `Name of your email configuration` - вводим слово "email". В окно `Email address` - вводим ваш email адрес. жмем submit +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_5.png) +manager_modules_firmware/blob/master/push_instruction/Screenshot_6.png) +### 6.1 Привязываем pushbullet. Переходим на сайт [pushbullet.com](https://www.pushbullet.com/) +### 6.2 Входим с гуглом или фейсбуком +### 6.3 Идем в настройки +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_7.png) +### 6.4 Создаем токен +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_8.png) +### 6.5 Идем опять в сервисы и теперь выбираем сервис pushbullet [pushingbox.com/services](https://www.pushingbox.com/services.php) нажимаем add service +### Берем токен, и вставляем его в окно Access token. +### Окно Device token (optional) оставляем пустым. +### В окно Name of your Pushbullet configuration пишем слово "push". +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_6.png) + +### 7. Теперь наш email и pushbullet привязаны к pushingbox. Далее можно скачать приложение pushbullet на телефон и войти с гуглом или фейсбуком сответственно с пунктом 6.3 этой инструкции +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_9.png) + +# Часть 2. Создание сценариев отправки email + +### 8.1. Сценарий для отправки email. Заходим в My Scenarios: +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_10.png) + +### 8.2 Пишем слово email (это имя сценария отправки email) жмем add: +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_12.png) +### 8.3 Нажимаем add an action +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_14.png) +### 8.4 Выбираем наш email который мы зарегестрировали ранее и нажимаем Add an action with this service +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_11.png) +### 8.5 Делаем все как на скриншоте и жмем submit +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_15.png) +### 8.6 Возвращаемся на мои сценарии +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_17.png) +### 8.7 Вставляем токен в веб интерфейс esp +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_18.png) + +# Часть 3. Создание сценариев отправки push + +### 9.1. Сценарий для отправки push. Заходим в My Scenarios: +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_10.png) + +### 9.2 Пишем слово push (это имя сценария отправки email) жмем add: +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_19.png) +### 9.3 Нажимаем add an action +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_20.png) +### 9.4 Выбираем наш pushbullet который мы зарегестрировали ранее и нажимаем Add an action with this service +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_11.png) +### 9.5 Делаем все как на скриншоте и жмем submit +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_15.png) +### 9.6 Возвращаемся на мои сценарии +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_21.png) +### 9.7 Вставляем токен в веб интерфейс esp +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_18.png) + +# Часть 4. Итог + +При создании такой конфигурации как на картинке: + +`button 1 na Отправить#push Push 0 1` + + +`button1 = 1` +`push внимание кнопка#нажата` +`end` + +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_22.png) + +Если мы введем токен для email то будут приходить email +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_17.png) + +Если для push то будут приходить push в pushbullet +![](https://github.com/IoTManagerProject/Wiki/tree/master/pictures/push_instruction/Screenshot_21.png) + +Способ описанный в данной инструкции более сложный в настройке но зато очень надежный. \ No newline at end of file diff --git a/doc/3.txt b/doc/3.txt new file mode 100644 index 00000000..31226847 --- /dev/null +++ b/doc/3.txt @@ -0,0 +1,32 @@ +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) + +### 1. Скачать архив из [релизов](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/releases) или из закрепленного сообщения группы телеграм с последней версией прошивки + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) + + +### 2. Для ESP8266 c 4 и больше мб памяти (все сделать как на скриншотах) + +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/esp8266_1.png) + +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/esp8266_2.png) + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) + +### 2. Для ESP8266 c 1 мб памяти (все сделать как на скриншотах) + +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/esp8266_1mb_1.png) + +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/esp8266_1mb_2.png) + +*** +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/1.png?raw=true) + +### 2. Для ESP32 (все сделать как на скриншотах) + +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/esp32_1.png) + +![](https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/blob/master/pictures/esp32_2.png) \ No newline at end of file diff --git a/doc/orders.xlsm b/doc/orders.xlsm new file mode 100644 index 00000000..4a23ac94 Binary files /dev/null and b/doc/orders.xlsm differ diff --git a/include/Consts.h b/include/Consts.h index ea94ed68..0f8fd7e0 100644 --- a/include/Consts.h +++ b/include/Consts.h @@ -10,7 +10,7 @@ #define TELEMETRY_UPDATE_INTERVAL 7200000 -#define DEVICE_CONFIG_FILE "dev_conf.txt" +#define DEVICE_CONFIG_FILE "conf.csv" #define DEVICE_SCENARIO_FILE "dev_scen.txt" #define DEFAULT_PRESET 100 #define DEFAULT_SCENARIO 100 diff --git a/include/DeviceList.h b/include/DeviceList.h index 4096fdf6..124f55d2 100644 --- a/include/DeviceList.h +++ b/include/DeviceList.h @@ -5,5 +5,6 @@ extern void addElement(String name); extern void delAllElement(); -extern void delElement(); +extern int getNewElementNumber(String file); +extern void delElement(String itemsFile, String itemsLine); extern void do_delElement(); \ No newline at end of file diff --git a/include/Global.h b/include/Global.h index 921ab1fb..0f951e05 100644 --- a/include/Global.h +++ b/include/Global.h @@ -79,6 +79,9 @@ extern String all_widgets; extern String scenario; extern String order_loop; +extern String itemsFile; +extern String itemsLine; + extern String analog_value_names_list; extern int enter_to_analog_counter; diff --git a/src/Cmd.cpp b/src/Cmd.cpp index 3d1dfd1b..b158d0aa 100644 --- a/src/Cmd.cpp +++ b/src/Cmd.cpp @@ -463,14 +463,17 @@ void fileExecute(const String &filename) { stringExecute(cmdStr); } -void stringExecute(String &cmdStr) { +void stringExecute(String &cmdStr) { + cmdStr.replace("x;",""); + cmdStr.replace(";"," "); cmdStr += "\r\n"; cmdStr.replace("\r\n", "\n"); cmdStr.replace("\r", "\n"); - + int count = 0; while (cmdStr.length()) { String buf = selectToMarker(cmdStr, "\n"); - sCmd.readStr(buf); + count++; + if (count > 1)sCmd.readStr(buf); cmdStr = deleteBeforeDelimiter(cmdStr, "\n"); } } diff --git a/src/DeviceList.cpp b/src/DeviceList.cpp index a65c292b..68b05d3d 100644 --- a/src/DeviceList.cpp +++ b/src/DeviceList.cpp @@ -1,9 +1,13 @@ #include "DeviceList.h" -static const char* firstLine PROGMEM = "Удалить;Тип элемента;Id;Виджет;Имя вкладки;Имя виджета;Позиция виджета"; +static const char* firstLine PROGMEM = "Тип элемента;Id;Виджет;Имя вкладки;Имя виджета;Позиция виджета"; void addElement(String name) { String item = readFile("items/" + name + ".txt", 1024); + + item.replace("id", "id" + String(getNewElementNumber("id.txt"))); + item.replace("order", String(getNewElementNumber("order.txt"))); + item.replace("\r\n", ""); item.replace("\r", ""); item.replace("\n", ""); @@ -13,29 +17,52 @@ void addElement(String name) { void delAllElement() { removeFile("conf.csv"); addFile("conf.csv", String(firstLine)); + removeFile("id.txt"); + removeFile("order.txt"); +} + + +int getNewElementNumber(String file) { + int number = readFile(file, 100).toInt(); + number++; + removeFile(file); + addFile(file, String(number)); + return number; } void do_delElement() { if (delElementFlag) { delElementFlag = false; - delElement(); + delElement(itemsFile, itemsLine); } } -void delElement() { - File configFile = LittleFS.open("/conf.csv", "r"); +void delElement(String _itemsFile, String _itemsLine) { + File configFile = LittleFS.open("/" + _itemsFile, "r"); if (!configFile) { return; } - configFile.seek(0, SeekSet); //поставим курсор в начало файла + configFile.seek(0, SeekSet); String finalConf; + int count = -1; while (configFile.position() != configFile.size()) { + count++; String item = configFile.readStringUntil('\n'); - if (selectToMarker(item, ";") == "0") { - finalConf += "\n" + item; + Serial.print(_itemsLine); + Serial.print(" "); + Serial.println(count); + if (count != _itemsLine.toInt()) { + if (count == 0) { + finalConf += item; + } else { + finalConf += "\n" + item; + } } } - removeFile("conf.csv"); - addFile("conf.csv", String(firstLine) + "\n" + finalConf); + removeFile(_itemsFile); + addFile(_itemsFile, finalConf); + Serial.println(finalConf); + itemsFile = ""; + itemsLine = ""; configFile.close(); -} +} \ No newline at end of file diff --git a/src/Global.cpp b/src/Global.cpp index 4d6178e7..89237a46 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -39,6 +39,9 @@ String all_widgets = ""; String scenario = ""; String order_loop = ""; +String itemsFile = ""; +String itemsLine = ""; + // Sensors String analog_value_names_list; int enter_to_analog_counter; diff --git a/src/Init.cpp b/src/Init.cpp index b5e79442..99c1d98b 100644 --- a/src/Init.cpp +++ b/src/Init.cpp @@ -62,6 +62,7 @@ void Device_init() { removeFile(String("layout.txt")); #endif + fileExecute(String(DEVICE_CONFIG_FILE)); //outcoming_date(); } diff --git a/src/Web.cpp b/src/Web.cpp index 5cc4c119..fe9942df 100644 --- a/src/Web.cpp +++ b/src/Web.cpp @@ -38,20 +38,22 @@ void web_init() { request->redirect("/?set.device"); } - //-------------------------------------------------------------------------------- + //==============================list of items===================================================== if (request->hasArg("element")) { String name = request->getParam("element")->value(); addElement(name); + Device_init(); request->redirect("/?setn.device"); } if (request->hasArg("cleanconf")) { delAllElement(); + Device_init(); request->redirect("/?setn.device"); } - if (request->hasArg("delete")) { - delElementFlag = true; + if (request->hasArg("save")) { + Device_init(); request->redirect("/?setn.device"); } @@ -235,6 +237,19 @@ void web_init() { } }); + //==============================list of items===================================================== + //server.on("/del", HTTP_GET, [](AsyncWebServerRequest* request) { + // if (request->hasArg("file")) { + // itemsFile = request->getParam("file")->value(); + // } + // if (request->hasArg("line")) { + // itemsLine = request->getParam("line")->value(); + // } + // delElementFlag = true; + // Device_init(); + // request->redirect("/?setn.device"); + //}); + /* * Check */