***
![](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    





      