Demostand: различия между версиями

Материал из Wiren Board
(не показано 40 промежуточных версий 6 участников)
Строка 1: Строка 1:
{{DISPLAYTITLE: Демонстрационный стенд автоматизации с оборудованием Wiren Board}}
Страница находится в процессе наполнения
[[Файл:Demostand.jpg|500px|thumb|Демонстрационный стенд, вид спереди]]
 
[[Файл:Demostand-back.jpg|500px|thumb|Демонстрационный стенд, вид сзади]]
==Общая информация==
==Общая информация==
Демонстрационный стенд можно посмотреть в нашем офисе.
Демонстрационный стенд находится в нашем офисе в переговорной. Управление стендом возможно, как физически (находясь у нас в офисе), так и через веб-интерфейс (доступен удалённо) Для того, чтобы можно было наблюдать за происходящем на стенде, над ним закреплена IP-камера. При удалённом управлении следует учитывать, что IP-камера даёт задержку около 3х секунд.
[[Файл:Demostand.png|700px|center|Внешний вид демонстрационного стенда.]]


==Подключённые устройства==
==Подключённые устройства==
<gallery mode="packed" heights="150px">
Image: Demostand Devices RS485.jpg | Устройства на шине RS-485
Image: Demostand Devices WB6 + IO Modules.jpg | Контроллер с боковыми модулями ввода/вывода
Image: Demostand Devices Peripherals.jpg | Устройства для взаимодействия и датчики
</gallery>
{| class="wikitable"
{| class="wikitable"
! colspan="2" |Modbus устройства
! colspan="2" |Modbus устройства
|-
|-
|[[WB-MR6C v.2 Modbus Relay Modules|WB-MR6C]]
|Модель
|6-канальный релейный модуль. Входы типа «Сухой контакт»
|Описание
|-
|WB-MR6HV/I
|Мощный 6-ти канальный релейный модуль. Входы 220В. [[WB-MR3xV and WB-MR6xV Modbus Relay Modules|Подробнее.]]
|-
|WB-MR3LV/I
|Мощный 3-х канальный релейный модуль. Входы вида "Сухой контакт" [[WB-MR3xV and WB-MR6xV Modbus Relay Modules|Подробнее.]]
|-
|-
|[[WB-MRWL3_Modbus_Relay_Module|WB-MRWL3]]
|WB-MD2
|Очень мощный 3-канальный релейный модуль. Входы вида «Сухой контакт»
|Диммер ламп (как накаливания, так и светодиодных).
Номинальная мощность до 400Вт. [[WB-MD2 230V Dimmer|Подробнее.]]
|-
|-
|[[WB-MDM3 230V Modbus Dimmer|WB-MDM3]]
|WB-MRGBW-D
|3-канальный диммер светодиодных ламп и ламп накаливания 230 В
|Диммер RGB-лент. Допустимый ток 3А на канал.
Отдельный канал для управления белыми лентами. [[WB-MRGBW-D|Подробнее.]]
|-
|-
|[[WB-MRGBW-D Modbus LED Dimmer|WB-MRGBW-D]]
|WB-MAP6S
|4-канальный диммер светодиодных лент (на дин-рейку). Допустимый ток 3А на канал.
|6-ти канальный счётчик электроэнергии.  
Отдельный канал для управления белыми лентами.
[[Power Meter WB-MAP6S|Подробнее.]]
|-
|-
|[[Power_Meter_WB-MAP12H| WB-MAP12H]]
|WB-MRM2mini/no
|Многоканальный счётчик электроэнергии.
|2-х канальный релейный модуль в миниатюрном корпусе. [[WB-MRM2-mini|Подробнее.]]
|-
|-
|[[WB-MIR v2 - Modbus IR Remote Control| WB-MIR v.2]]
|WB-MIR
|Модуль для управления устройствами посредством ИК сигналов, оснащён входом для температурного датчика.
|Модуль для управления устройствами посредством ИК сигналов (также, оснащён входом для температурного датчика). [[WB-MIR v.2 - Modbus IR Remote Control|Подробнее.]]
|-
|-
! colspan="2" |Датчики
! colspan="2" |Датчики
|-
|-
|[[WB-MSW v.3 Modbus Sensor|WB-MSW v.3]]
|WB-MSW2
|Универсальный настенный датчик.
|Универсальный датчик в элегантном корпусе. (Доступно измерение температуры, влажности, освещённости и звукового давления + подача звукового сигнала). [[WB-MSW2 Modbus Sensor|Подробнее.]]
|-
|-
|WB-MS/THLS
|WB-MS/THLS
|Цифровой датчик температуры, влажности, освещённости и звукового давления с двумя входами для подключения 1-Wire датчиков.
|Цифровой датчик температуры, влажности, освещённости и звукового давления с двумя входами для подключения 1-Wire датчиков. [[WB-MS Modbus Sensor|Подробнее.]]
 
|-
|-
|[[Датчик газа WB-MSGR | WB-MSGR ]]
|WB-MSGR
|Комбинированный электрохимический датчик газов со встроенным реле.
|Комбинированный электрохимический датчик газов со встроенным реле. [[Датчик газа WB-MSGR|Подробнее.]]
|-
|-
|[[WB-M1W2 1-Wire to Modbus Temperature Measurement Module|WB-M1W2 ]]
|WB-M1W2
|Модуль для заведения двух 1-Wire датчиков в шину RS-485 и их опроса по протоколу Modbus.  
|Модуль для заведения двух 1-Wire датчиков в шину RS-485 и их опроса посредством Modbus. [[WB-M1W2 1-Wire to Modbus Temperature Measurement Module|Подробнее.]]
|-
|-
! colspan="2" |Боковые модули ввода/вывода
! colspan="2" |Пристыковочные модули
|-
|-
|[[WBIO-DO-R10A-8 Relay Module | WBIO-DO-R10A-8]]
|WBIO-R10A8
|Релейный модуль. До 7А/230В на канал. Идеален для управления освещением/контакторами/моторами.  
|Релейный модуль. До 7А/230В на канал. Идеален для
управления освещением/контакторами/моторами. [[Модуль релейных выходов 10A (WBIO-DO-R10A-8)|Подробнее.]]
|-
|-
|[[WBIO-DO-HS-8 Discrete Outputs | WBIO-DO-HS-8]]
|WBIO-HS-8
|Модуль с 8 выходами вида "High Side Switch"
|Модуль с 8 выходами вида "High Side Switch"
[[Модуль дискретных выходов (WBIO-DO-HS-8)|Подробнее.]]
|-
|-
|[[WBIO-DI-WD-14 Discrete Inputs | WBIO-DI-WD-14]]
|WBIO-R1G16
|Универсальный модуль дискретных входов
|Релейный модуль с 16-ю выходами и общим каналом.
[[WBIO-DO-R1G-16 I/O Module|Подробнее.]]
|-
|-
|[[WBIO-DI-HVD-16 16-Channel 230V Detector Module | WBIO-DI-HVD-16]]
|WBIO-DI-DR8
|Модуль содержит 8 входов вида "Сухой контакт"
[[WBIO-DI-DR-8 I/O Module|Подробнее.]]
|-
|WBIO-DI-HVD16
|Модуль содержит 16 входов для детектирования высокого напряжения (220В).
|Модуль содержит 16 входов для детектирования высокого напряжения (220В).
[[Модуль наличия 220В (WBIO-DI-HVD-16)|Подробнее.]]
|-
|WBE2-DI-DR-3
|Модуль расширения на 3 входа вида "Cухой кнтакт"
Вставляются внутрь корпуса Wiren Board [[Wiren Board 6: Модуль расширенияWBE-DI-DR-3|Подробнее.]]
|}
|}


==Правила==
==Правила==
При написании своих правил через движок WB-Rules, важно помнить, что код в правилах выполняется '''асинхронно'''.
При написании своих правил через движок WB-Rules, важно помнить, что код в правилах выполняется ''асинхронно''. Если, в привычном понимании, выполнение кода идёт сверху-вниз, то в данном случае, выполнением управляет событийная модель: когда происходит то или иное событие (изменение показаний датчика/срабатывание таймера/нажатие на кнопку), то выполняется соответствующий кусок кода, отвечающий за обработку этого события. Подробнее о работе движка правил и типовых конструкциях обработки событий можно узнать из [[движок правил wb-rules|соответствующей статьи.]]
 
Для управления стендом как физически (путём нажатия на кнопки), так и удалённо через демонстрационный веб-интерфейс, были созданы виртуальные устройства. Логика управления стендом выглядт следующим образом: нажатие на кнопку/переключение в веб-интерфейсе => срабатывание виртуального устройства => выполнение правила.  
Если, в привычном понимании, выполнение кода идёт сверху-вниз, то в данном случае, выполнением управляет событийная модель: когда происходит то или иное событие (изменение показаний датчика/срабатывание таймера/нажатие на кнопку), то выполняется соответствующий кусок кода, отвечающий за обработку этого события. Подробнее о работе движка правил и типовых конструкциях обработки событий можно узнать из [[движок правил wb-rules|соответствующей статьи.]]
====Датчик движения====
 
[[File:Movement_widget.png|150px|thumb|Датчик движения в веб-интерфейсе]]
Для управления стендом были созданы виртуальные устройства. Логика управления стендом выглядят следующим образом: нажатие на кнопку/переключение в веб-интерфейсе срабатывание виртуального устройства выполнение правила.
При срабатывании загорается сигнализирующая лампа. Датчик имеет выход типа "Сухой контакт" и умеет сигнализировать либо наличие движения, либо его отсутствие. Если использовать такой датчик, например, для автоматического включения света, то нужно добавить задержку перед срабатыванием (для защиты от ложных срабатываний). Это можно легко сделать с помощью движка правил wb-rules (см. правило под спойлером). Выход датчика подключён к WBIO-DI-DR14, а сигнализационная лампа управляется через WBIO-R10-A8.
 
<div class="mw-collapsible mw-collapsed">
==Схема подключения==
Показать код
 
<div class="mw-collapsible-content">
Цвета соединений на схеме условные и не совпадают с цветами проводов в устройстве.
<syntaxhighlight lang="ecmascript">
<gallery mode="traditional " widths ="500px" heights="350px">
    defineAlias("movement_lamp", "wb-gpio/EXT1_R3A2");
Image: Demo stand left.png|| Схема подключения устройств на демонстрационном стенде: левая сторон
    defineAlias("movement_virtual_switch", "movement_sensor_control/Иммитация движения");
Image: Demo stand right.png| Схема подключения устройств на демонстрационном стенде: правая сторона
    defineAlias("movement_timeout_before", "movement_sensor_control/Задержка после начала движения");
</gallery>
    defineAlias("movement_timeout_after", "movement_sensor_control/Задержка после прекращения движения");
   
    var motion_timer_before = null;
    var motion_timer_after = null;
   
    defineVirtualDevice("movement_sensor_control", {
        title: "Датчик движения",
        cells: {
            "Иммитация движения": {
                type: "switch",
                value: false
            },
            "Задержка после начала движения": {
                type: "range",
                value: 2,
                min: 1,
                max: 10
            },
            "Задержка после прекращения движения": {
                type: "range",
                value: 2,
                min: 1,
                max: 10
            }
   
   
        }
    });
   
    defineRule("physical_movement_to_virtual_switch", {
        whenChanged: "wb-gpio/EXT5_DR8",
        then: function(newValue, devName, cellName) {
            movement_virtual_switch = newValue;
   
        }
    });
   
   
    defineRule("movement_handler", {
        whenChanged: "movement_sensor_control/Иммитация движения",
        then: function(newValue, devName, cellName) {
            if (newValue == true) {
                if (motion_timer_before) {
                    clearTimeout(motion_timer_before);
                }
                motion_timer_before = setTimeout(function() {
                    movement_lamp = 1;
                    motion_timer_before = null;
                }, movement_timeout_before * 1000);
            } else {
                if (motion_timer_after) {
                    clearTimeout(motion_timer_after);
                }
                motion_timer_after = setTimeout(function() {
                    movement_lamp = 0;
                    motion_timer_after = null;
                }, movement_timeout_after * 1000);
            }
        }
    });
</syntaxhighlight>
</div></div>


==SVG Дашборд==
====Управление освещением====
В веб-интерфейсе контроллера Wiren Board можно создавать [[SVG-Dashboards | SVG-дашбрды]], это позволяет создать интерактивную мнемосхему.
[[File:Illuminance_widget.png|200px|thumb|Управление из веб-интерфейса]]
Автоматически включает свет в зависимости от показаний датчика освещённости. Если показания датчика ниже некоторого порогового значения, то свет включается; если показания выше - свет выключается. Возможности движка правил позволяют гибко отображать информацию (показания датчика) и вручную задавать пороговое значение срабатывания. Уровень освещённости измеряется с помощью WB-MS-THLS, а освещение (лампа) управляется через WBIO-R1G16. Переключатель "Принудительное освещение датчика" нужен для имитации высокого уровня освещённости (управляет кусочком RGB-ленты, направленным на датчик освещения).
<div class="mw-collapsible mw-collapsed">
Код правила
<div class="mw-collapsible-content">
<syntaxhighlight lang="ecmascript">
        defineAlias("small_light_switcher", "wb-msgr_9/Relay");
        defineAlias("lamp1_switcher", "wb-gpio/EXT2_K1");
       
        var FORCE_ILLUMINANCE_FLAG = false;
        var FORCE_LAMP_FLAG = false;
       
       
        defineVirtualDevice("switch_small_light", {
            title: "Управление освещением",
            cells: {
                "Принудительное освещение датчика": {
                    type: "switch",
                    value: false
                },
                "Включить освещение вручную": {
                    type: "switch",
                    value: false
                },
                "Уровень освещения днём": {
                    type: "range",
                    value: 500,
                    max: 1000
                }
       
            }
        });
       
       
        defineRule("small_light_control", {
            whenChanged: "switch_small_light/Принудительное освещение датчика",
            then: function(newValue, devName, cellName) {
                if (newValue == true) {
                    small_light_switcher = 1;
                    FORCE_ILLUMINANCE_FLAG = true;
                    dev["switch_small_light/Включить освещение вручную"] = false
                } else {
                    small_light_switcher = 0;
                    FORCE_ILLUMINANCE_FLAG = false;
                }
            }
        });
       
       
        defineRule("manual_light_control", {
            whenChanged: "switch_small_light/Включить освещение вручную",
            then: function(newValue, devName, cellName) {
                if (MANUAL_SWITCHER_1_FLAG == false) {
                if (newValue == true) {
                    lamp1_switcher = 1;
                    FORCE_LAMP_FLAG = true;
                    dev["switch_small_light/Принудительное освещение датчика"] = false
                } else {
                    lamp1_switcher = 0;
                    FORCE_LAMP_FLAG = false;
            }
                }
            }
        });
       
       
       
       
        defineRule("illuminance_ms_thls", {
            whenChanged: "wb-ms-thls-v2_8/Illuminance",
            then: function(newValue, devName, cellName) {
                if (MANUAL_SWITCHER_1_FLAG == false) {
                if (FORCE_ILLUMINANCE_FLAG == false && FORCE_LAMP_FLAG == false) {
                    if (newValue < dev["switch_small_light"]["Уровень освещения днём"]) {
                        lamp1_switcher = 1;
                    } else {
                        if (newValue > dev["switch_small_light"]["Уровень освещения днём"]) {
       
                            lamp1_switcher = 0;
                }
                        }
                    }
                }
            }
        });
</syntaxhighlight>
</div></div>


В веб-интерфейсе демонстрационного стенда в режиме реального времени видно положение автоматов, реле, контакторов и нагрузок на стенде. Так же есть возможность переключать реле нажатием на интерактивные области (подсвечены фиолетовым).
====Ручное управление лампами====
[[Файл:Mnemo.png|1280px|thumb|center|SVG мнемосхема]]
Помимо веб-интерфейса, лампочками можно управлять и вручную, физически нажав на соответствующий лампе выключатель. Правило обрабатывает нажатие на выключатель и управляет устройством, через которое подключена нужная лампа. Выключатели подключены к модулю WBIO-DI-DR14.
<div class="mw-collapsible mw-collapsed">
Код правила
<div class="mw-collapsible-content">
<syntaxhighlight lang="ecmascript">
    defineAlias("lamp1_switcher_control", "wb-gpio/EXT2_K1");
    defineAlias("lamp2_switcher_control", "wb-mdm2_2/Channel 1");
    defineAlias("lamp3_switcher_control", "wb-mr3_3/K1");
   
    var MANUAL_SWITCHER_1_FLAG = false;
    var MANUAL_SWITCHER_2_FLAG = false;
    var MANUAL_SWITCHER_3_FLAG = false;
       
   
    defineRule("switcher_1", {
        whenChanged: "wb-gpio/EXT5_DR1",
        then: function(newValue, devName, cellName) {
        if (newValue == true) {
            MANUAL_SWITCHER_1_FLAG = true;
          lamp1_switcher_control = 1;
        }
        else {
        MANUAL_SWITCHER_1_FLAG = false;
        lamp1_switcher_control = 0;
        }
        }
    });
   
   
   
    defineRule("switcher_2", {
        whenChanged: "wb-gpio/EXT5_DR2",
        then: function(newValue, devName, cellName) {
        if (newValue == true) {
            MANUAL_SWITCHER_2_FLAG = true;
          lamp2_switcher_control = 100;
        }
        else {
        MANUAL_SWITCHER_2_FLAG = false;
        lamp2_switcher_control = 0;
        }
        }
    });
   
   
   
    defineRule("switcher_3", {
        whenChanged: "wb-gpio/EXT5_DR3",
        then: function(newValue, devName, cellName) {
        if (newValue == true) {
            MANUAL_SWITCHER_3_FLAG = true;
          lamp3_switcher_control = 1;
        }
        else {
        MANUAL_SWITCHER_3_FLAG = false;
        lamp3_switcher_control = 0;
        }
        }
    });
</syntaxhighlight>
</div></div>


==Файлы для скачивания==
====Имитация управления кондиционером====
По ссылкам ниже вы можете скачать схему подключения в форматах <br>
[[File:Conditioner.png|200px|thumb|Управление из веб-интерфейса]]
'''Corel Draw 2018:''' [[Media:Demostand.cdr.zip|Demostand.cdr.zip]]
Демонстрирует возможность управления кондиционером, в зависимости от температуры в помещении. Температура измеряется с помощью 1-Wire датчика, а команды на кондиционер посылаются с помощью WB-MIRv2. Пользователь выбирает оптимальную для него температуру и границы диапазона, в которых температура в помещении считается приемлемой. Если показания датчика температуры выходят за границы допустимого диапазона, с помощью WB-MIR посылаются команды по управлению кондиционером (можно увидеть на примере светодиодной ленты).
<div class="mw-collapsible mw-collapsed">
Код правила
<div class="mw-collapsible-content">
<syntaxhighlight lang="ecmascript">
  defineAlias("virtual_dimmer", "climate_system_control/Диммирование нагревателя");
  defineAlias("physical_dimmer", "wb-mdm2_2/Channel 1");
  defineAlias("temperature_sensor", "wb-m1w2_7/External Sensor 2")
  defineAlias("optimal_temp_value", "climate_system_control/Оптимальная температура");
  defineAlias("temp_range", "climate_system_control/Границы диапазона");
 
  defineAlias("turn_on_red", "wb-mir-simple_10/Play from ROM1");
  defineAlias("turn_on_green", "wb-mir-simple_10/Play from ROM3");
  defineAlias("turn_on_blue", "wb-mir-simple_10/Play from ROM2");
 
  defineVirtualDevice("climate_system_control", {
      title: "Управление климатом",
      cells: {
          "Диммирование нагревателя": {
              type: "range",
              value: 20,
              min: 1,
              max: 100
          },
          "Оптимальная температура": {
              type: "range",
              value: 24,
              min: 1,
              max: 35
          },
          "Границы диапазона": {
              type: "range",
              value: 28,
              min: 1,
              max: 5
          }
 
 
 
 
      }
  });
 
 
 
  defineRule("virtual_dimmer_to_physical", {
      whenChanged: "climate_system_control/Диммирование нагревателя",
      then: function(newValue, devName, cellName) {
          if (MANUAL_SWITCHER_2_FLAG == false) {
              physical_dimmer = newValue;
          }
      }
  });
 
 
 
  defineRule("indicate_temp", {
      whenChanged: "temperature_sensor",
      then: function(newValue, devName, cellName) {
          if (newValue <= optimal_temp_value - temp_range) {
              turn_on_blue = 1;
              log("Low");
          }
 
          if ((newValue > optimal_temp_value - temp_range) && (newValue < optimal_temp_value + temp_range)) {
              turn_on_green = 1;
              log("normal");
          }
 
          if (newValue >= optimal_temp_value + temp_range) {
              turn_on_red = 1;
              log("High");
          }
      }
  });
</syntaxhighlight>
</div></div>


'''Corel Draw PDF:''' [[Media:Demo stand.pdf|Demostand.pdf]]
====Управление вентилятором и миниреле====
Доступно на виджете "Показания в комнате". Основная идея управления - создание виртуального устройства, а затем, при физическом нажатии на кнопку, переключается виртуальное устройство, которое, в свою очередь, уже переключает реле или вентилятор. Это сделано для дублирования управления как удалённо, так и физически. Нажатие физических кнопок отслеживает WBIO-DI-DR14, а подсветка кнопок реализована через WBIO-DO-HS8.
<div class="mw-collapsible mw-collapsed">
Код правила
<div class="mw-collapsible-content">
<syntaxhighlight lang="ecmascript">
    defineAlias("relay1_control", "wb-mrm2_11/Relay 1");
    defineAlias("relay1_button", "wb-gpio/EXT5_DR9");
    defineAlias("relay_button_lamp", "wb-gpio/EXT3_HS4");
    defineAlias("virtual_mrm2_mini_switch", "virtual_mrm2_mini/Включить вручную");
   
    defineAlias("fan_control", "wb-gpio/EXT3_HS5");
    defineAlias("fan_button", "wb-gpio/EXT5_DR7");
    defineAlias("fan_button_lamp", "wb-gpio/EXT3_HS6");
    defineAlias("virtual_fan_switch", "virtual_fan/Включить вручную");
   
    defineVirtualDevice("virtual_fan", {
        title: "Управление вентилятором",
        cells: {
            "Включить вручную": {
                type: "switch",
                value: false
            }
        }
    });
   
    defineVirtualDevice("virtual_mrm2_mini", {
        title: "Управление миниреле",
        cells: {
            "Включить вручную": {
                type: "switch",
                value: false
            }
        }
    });
   
   
    defineRule("fan_virtual_to_physical", {
        whenChanged: "virtual_fan/Включить вручную",
        then: function(newValue, devName, cellName) {
            fan_control = newValue;
            fan_button_lamp = newValue;
   
        }
    });
   
   
    defineRule("mrm2_mini_virtual_to_physical", {
        whenChanged: "virtual_mrm2_mini/Включить вручную",
        then: function(newValue, devName, cellName) {
            relay1_control = newValue;
            relay_button_lamp = newValue;
   
        }
    });
   
   
   
    defineRule("fan_manual_turn_on", {
        whenChanged: "wb-gpio/EXT5_DR7",
        then: function(newValue, devName, cellName) {
            if (newValue == true) {
                virtual_fan_switch = !virtual_fan_switch;
   
            }
        }
    });
   
   
   
    defineRule("mini_relay_manual_turnon", {
        whenChanged: "wb-gpio/EXT5_DR9",
        then: function(newValue, devName, cellName) {
            if (newValue == true) {
                virtual_mrm2_mini_switch = !virtual_mrm2_mini_switch;
   
            }
        }
    });
</syntaxhighlight>
</div></div>


'''SVG мнемосхема:''' [[Media:Demo stand.svg.zip|Demostand.svg.zip]]
====Ручное управление розетками====
Для наглядности, обработка нажатий на кнопки под розетками вынесена в отдельное правило. При нажатии на кнопку, загорается световой индикатор вокруг неё и включается соответствующая розетка. Физическое нажатие на кнопку переключает виртуальное устройство, на переключение которого уже и завязаны все действия.
<div class="mw-collapsible mw-collapsed">
Код правила
<div class="mw-collapsible-content">
<syntaxhighlight lang="ecmascript">
    defineAlias("rozetka1_control", "wb-mr6c_1/K1");
    defineAlias("rozetka1_button", "wb-gpio/EXT5_DR5");
    defineAlias("rozetka2_control", "wb-mr6c_1/K2");
    defineAlias("rozetka2_button", "wb-gpio/EXT5_DR4");
    defineAlias("rozetka1_virtual_control", "rozetkas_controls/Включить розетку 1");
    defineAlias("rozetka2_virtual_control", "rozetkas_controls/Включить розетку 2");
   
   
   
    defineRule("rozetka1_manual_turn_on", {
        whenChanged: "rozetka1_button",
        then: function(newValue, devName, cellName) {
            if (newValue == true) {
                rozetka1_virtual_control = !rozetka1_virtual_control;
   
            }
        }
    });
   
   
   
    defineRule("rozetka2_manual_turn_on", {
        whenChanged: "rozetka2_button",
        then: function(newValue, devName, cellName) {
            if (newValue == true) {
                rozetka2_virtual_control = !rozetka2_virtual_control;
   
            }
        }
    });
</syntaxhighlight>
</div></div>


==Таблицы MQTT Топиков==
====Управление нагревателем====
{| class="wikitable"
[[File:Temperature_control.png|200px|thumb|Управление из веб-интерфейса]]
! colspan="2" |WBIO-DO-R10A-8
Поддерживает температуру в помещении между двумя заданными пороговыми значениями. Если температура в помещении ниже нижнего порога, то включается нагреватель. Если температура превышает верхний порог, то нагреватель отключается. Температура измеряется датчиком 1-Wire, а в роли нагревателя выступает лампа накаливания, расположенная рядом с ним. Для большей наглядности процесса, был добавлен маленький вентилятор, охлаждающий датчик. Поэтому, финальный алгоритм работы выглядит так: температура превышает верхний порог => выключается нагреватель и включается вентилятор; температура опускается за нижний порог => включается нагреватель и выключается вентилятор. Цифровой датчик 1-Wire подключён с помощью модуля WB-M1W2, нагреватель управляется с помощью WB-MR3LV/I, а вентилятором управляет WB-MRM2mini.
|-
<div class="mw-collapsible mw-collapsed">
|wb-gpio/EXT1_R3A1
Код правила
|Контактор NO: Лампы, Вентиляция, Индикаторы
<div class="mw-collapsible-content">
|-
<syntaxhighlight lang="ecmascript">
|wb-gpio/EXT1_R3A2
    defineAlias("temperature_sensor_value", "wb-mir-simple_10/External Temperature Sensor");
|Контактор NC: Розетки
    defineAlias("small_fan_switcher", "wb-mrm2_11/Relay 2");
|-
    defineAlias("lamp3_switcher", "wb-mr3_3/K1");
|wb-gpio/EXT1_R3A3
    defineAlias("fan_virtual_switcher", "lamp3_manual/Включить вентилятор вручную");
|Индикатор 1 (Розетка 1)
    defineAlias("lamp3_virtual_switcher", "lamp3_manual/Включить вручную");
|-
   
|wb-gpio/EXT1_R3A4
    var MANUAL_FAN_FLAG;
|Индикатор 2 (Розетка 2)
    var MANUAL_LAMP3_FLAG;
|-
   
|wb-gpio/EXT1_R3A5
   
|Индикатор 3
    defineVirtualDevice("lamp3_manual", {
|-
        title: "Управление нагревателем",
|wb-gpio/EXT1_R3A6
        cells: {
|Индикатор 4
            "Включить вручную": {
|-
                type: "switch",
|wb-gpio/EXT1_R3A7
                value: false
|Индикатор 5
            },
|-
            "Включить вентилятор вручную": {
|wb-gpio/EXT1_R3A8
                type: "switch",
|Вентилятор
                value: false
|}
            },
            "Верхний порог температуры": {
                type: "range",
                value: 26,
                max: 40
            },
            "Нижний порог температуры": {
                type: "range",
                value: 23,
                max: 40
            }
        }
    });
   
   
    defineRule("manual_lamp3_control", {
        whenChanged: "lamp3_manual/Включить вручную",
        then: function(newValue, devName, cellName) {
            if (MANUAL_SWITCHER_3_FLAG == false) {
                if (newValue == true) {
                    lamp3_switcher = 1;
                    //dev["lamp3_manual/Включить вентилятор вручную"] = false;
                    //MANUAL_LAMP3_FLAG = true;
                } else {
                    //MANUAL_LAMP3_FLAG = false;
                    lamp3_switcher = 0;
                }
            }
        }
    });
   
   
    defineRule("manual_fan_control", {
        whenChanged: "lamp3_manual/Включить вентилятор вручную",
        then: function(newValue, devName, cellName) {
            if (newValue == true) {
                small_fan_switcher = 1;
                //dev["lamp3_manual/Включить вручную"] = false;
                //MANUAL_FAN_FLAG = true;
            } else {
                small_fan_switcher = 0;
                //MANUAL_FAN_FLAG = false;
            }
        }
    });
   
   
   
   
    defineRule("heater_hysteresis", {
        whenChanged: "wb-mir-simple_10/External Temperature Sensor",
        then: function(newValue, devName, cellName) {
            if (MANUAL_SWITCHER_3_FLAG == false) {
                    if (newValue > dev["lamp3_manual"]["Верхний порог температуры"]) {
                        fan_virtual_switcher = 1;
                        lamp3_virtual_switcher = 0;
                    } else {
                        if (newValue < dev["lamp3_manual"]["Нижний порог температуры"]) {
                            fan_virtual_switcher = 0;
                            lamp3_virtual_switcher = 1;
                        }
                }
            }
        }
    });
</syntaxhighlight>
</div></div>


{| class="wikitable"
====Управление розетками====
! colspan="2" |WBIO-DO-HS-8
[[File:Protechka_widget.png|200px|thumb|Управление из веб-интерфейса]]
|-
Позволяет включать и выключать розетки как вручную с помощью кнопок под ними, так и через веб-интерфейс. Если розетка включена, вокруг соответствующей ей кнопки горит зелёный индикатор. Если напряжение, поступающее в розетку, пропадает, розетка запоминает своё состояние (была включена или нет) и переходит в режим аварии, о чём свидетельствует мигание соответствующего ей индикатора. При возврате напряжения, розетка принимает своё исходное состояние. Рядом с розетками установлен датчик протечки типа "Сухой контакт". Если на датчик попала вода (можно имитировать переключателем "Воздействие водой на датчик протечки"), то обе розетки переходят в режим аварии, а большая RGB-лента, сигнализирующая статус работы, меняет цвет на красный. Напряжение на розетках коммутируется через WB-MR6HV/I, датчик протечки подключён через внутренний модуль расширения WBE2-DI-DR3, нажатия кнопок детектирует модуль WBIO-DI-DR14, а световыми индикаторами вокруг кнопок управляет WBIO-DO-HS8.
|wb-gpio/EXT2_HS1
<div class="mw-collapsible mw-collapsed">
|Подсветка кнопки 1 (Розетка 1)
Код правила
|-
<div class="mw-collapsible-content">
|wb-gpio/EXT2_HS2
<syntaxhighlight lang="ecmascript">
|Подсветка кнопки 2 (Розетка 2)
    defineAlias("light_under_rozetka_1", "wb-gpio/EXT3_HS2");
|-
    defineAlias("light_under_rozetka_2", "wb-gpio/EXT3_HS1");
|wb-gpio/EXT2_HS3
   
|Подсветка кнопки 3
    defineAlias("light_upper_rozetka_1", "wb-mr6c_1/K1");
|-
    defineAlias("light_upper_rozetka_2", "wb-mr6c_1/K2");
|wb-gpio/EXT2_HS4
   
|Подсветка кнопки 4
    defineAlias("rozetka1_control", "wb-mr6c_1/K1");
|-
    defineAlias("rozetka2_control", "wb-mr6c_1/K2");
|wb-gpio/EXT2_HS5
   
|Подсветка кнопки 5
    defineAlias("rozetka1_virtual_control", "rozetkas_controls/Включить розетку 1");
|}
    defineAlias("rozetka2_virtual_control", "rozetkas_controls/Включить розетку 2");
 
   
{| class="wikitable"
    defineAlias("rozetka1_input", "wb-mr6c_1/Input 1");
! colspan="2" |WBIO-DI-HVD-16
    defineAlias("rozetka2_input", "wb-mr6c_1/Input 2");
|-
   
|wb-gpio/EXT3_IN1
    defineAlias("leak_sensor_input", "wb-gpio/MOD2_IN1");
|Автомат: Розетка 1
    defineAlias("alarm_button", "wb-gpio/EXT5_DR6");
|-
    defineAlias("light_under_alarm_button", "wb-gpio/EXT3_HS3");
|wb-gpio/EXT3_IN2
    defineAlias("light_upper_leak_sensor", "wb-gpio/EXT1_R3A1");
|Автомат: Контроллер, Контакторы
   
|-
    var ROZETKA1_FORCE_FLAG = false;
|wb-gpio/EXT3_IN3
    var ROZETKA2_FORCE_FLAG = false;
|Контактор NO: Лампы, Вентиляция, Индикаторы
   
|-
    var ROZETKA1_BLINKING_FLAG = false;
|wb-gpio/EXT3_IN4
    var ROZETKA2_BLINKING_FLAG = false;
|Автомат: Ввод
   
|-
    var ZATOPLENIE_FLAG = false;
|wb-gpio/EXT3_IN5
   
|Автомат 3\3: Индикаторы
    defineVirtualDevice("rozetkas_controls", {
|-
        title: "Управление розетками",
|wb-gpio/EXT3_IN6
        cells: {
|Автомат 1\3: Лампы
            "Включить розетку 1": {
|-
                type: "switch",
|wb-gpio/EXT3_IN7
                value: false
|Автомат 2\3: Вентиляция
            },
|-
            "Включить розетку 2": {
|wb-gpio/EXT3_IN8
                type: "switch",
|Автомат: Розетка 2
                value: false
|-
            },
|wb-gpio/EXT3_IN9
            "Иммитация протечки": {
|Напряжение на розетке 2
                type: "switch",
|-
                value: false
|wb-gpio/EXT3_IN10
            },
|Напряжение на розетке 1
            "Частота индикации при аварии": {
|}
                type: "range",
 
                value: 700,
{| class="wikitable"
                min: 600,
! colspan="2" |WBIO-DI-WD-14
                max: 2500
|-
            }
|wb-gpio/EXT4_IN1
   
|Кнопка 1
        }
|-
    });
|wb-gpio/EXT4_IN2
   
|Кнопка 2
   
|-
    defineRule("rozetka1_turn_on", {
|wb-gpio/EXT4_IN3
        whenChanged: "rozetkas_controls/Включить розетку 1",
|Кнопка 3
        then: function(newValue, devName, cellName) {
|-
            if (dev["rozetkas_controls/Иммитация протечки"] == false) {
|wb-gpio/EXT4_IN4
                if (ROZETKA1_FORCE_FLAG == false) {
|Кнопка 4
                    log("Force flag is false on rozetka 1");
|-
                    rozetka1_control = newValue;
|wb-gpio/EXT4_IN5
                }
|Кнопка 5
                if (ROZETKA1_FORCE_FLAG == true) {
|-
                    log("Not working");
|wb-gpio/EXT4_IN6
                }
|Выключатель 1
            }
|-
        }
|wb-gpio/EXT4_IN7
    });
|Выключатель 2
   
|-
   
|wb-gpio/EXT4_IN8
   
|Выключатель 3
    defineRule("rozetka1_turnonlight", {
|-
        whenChanged: "wb-mr6c_1/K1",
|wb-gpio/EXT4_IN9
        then: function(newValue, devName, cellName) {
|Датчик движения
   
|}
            light_under_rozetka_1 = newValue;
 
   
{| class="wikitable"
   
! colspan="2" |WB-MRWL3
        }
|-
    });
|wb-mr3_29/K1
   
|Реле Розетки 1
   
|-
   
|wb-mr3_29/K2
   
|Реле Розетки 2
    defineRule("Input1_handler", {
|}
        whenChanged: "wb-mr6c_1/Input 1",
 
        then: function(newValue, devName, cellName) {
{| class="wikitable"
            if (newValue == false) {
! colspan="2" |WB-MDM3
                ROZETKA1_FORCE_FLAG = true;
|-
                rozetka1_initial_state = rozetka1_virtual_control;
|wb-mdm2_2/Channel 1
                rozetka1_control = false;
|Лампа 1
                log(rozetka1_control);
|-
                rozetka1_virtual_control = false;
|wb-mdm2_2/Channel 2
                ROZETKA1_BLINKING_FLAG = true;
|Лампа 2
                startTicker("button_blinking_timer", dev["rozetkas_controls/Частота индикации при аварии"])
|}
                log("Rozetka 1 was ", rozetka1_initial_state, "before poweroff")
 
            }
{| class="wikitable"
            if (newValue == true) {
! colspan="2" |WB-MR6C
                log("Power on rozetka 1 is turned on!");
|-
                ROZETKA1_BLINKING_FLAG = false;
|wb-m6с_3/K1
                ROZETKA1_FORCE_FLAG = false;
|Лампа 3
   
|}
                rozetka1_virtual_control = rozetka1_initial_state;
 
            }
{| class="wikitable"
        }
! colspan="2" |WB-MAP12H
    });
|-
   
|wb-map12h_42/Ch 1 L1
   
|Автомат: Контроллер, Контакторы
    defineRule("rozetka2_turn_on", {
|-
        whenChanged: "rozetkas_controls/Включить розетку 2",
|wb-map12h_42/Ch 1 L2
        then: function(newValue, devName, cellName) {
|Автомат 1\3: Лампы
            if (dev["rozetkas_controls/Иммитация протечки"] == false) {
|-
                if (ROZETKA2_FORCE_FLAG == false) {
|wb-map12h_42/Ch 1 L3
                    log("Force flag is false on rozetka 2");
|Автомат 2\3: Вентиляция
                    rozetka2_control = newValue;
|-
                }
|wb-map12h_42/Ch 2 L1
                if (ROZETKA2_FORCE_FLAG == true) {
|Автомат 3\3: Индикаторы
                    log("Not working");
|-
                }
|wb-map12h_42/Ch 2 L2
            }
|Автомат: Розетка 1
        }
|-
    });
|wb-map12h_42/Ch 2 L3
   
|Автомат: Розетка 2
   
|}
   
 
    defineRule("rozetka2_turnonlight", {
{| class="wikitable"
        whenChanged: "wb-mr6c_1/K2",
! colspan="2" |WB-M1W2
        then: function(newValue, devName, cellName) {
|-
   
|wb-m1w2_72/External Sensor 1
            light_under_rozetka_2 = newValue;
|1-wire 2
   
|-
        }
|wb-m1w2_72/External Sensor 2
    });
|1-wire 1
   
|}
   
 
   
{| class="wikitable"
   
! colspan="2" |WB-MIR v.2
    defineRule("Input2_handler", {
|-
        whenChanged: "wb-mr6c_1/Input 2",
|wb-mir_10/External Temperature Sensor
        then: function(newValue, devName, cellName) {
|1-wire 3
            if (newValue == false) {
|}
                ROZETKA2_FORCE_FLAG = true;
                rozetka2_initial_state = rozetka2_virtual_control;
                rozetka2_control = false;
                log(rozetka2_control);
                rozetka2_virtual_control = false;
                log("Rozetka 2 was ", rozetka2_initial_state, "before poweroff")
                ROZETKA2_BLINKING_FLAG = true;
                startTicker("button_blinking_timer", dev["rozetkas_controls/Частота индикации при аварии"])
            }
            if (newValue == true) {
                log("Power on rozetka 2 is turned on!");
                ROZETKA2_FORCE_FLAG = false;
                ROZETKA2_BLINKING_FLAG = false;
   
                rozetka2_virtual_control = rozetka2_initial_state;
            }
        }
    });
   
   
   
    defineRule("leak_sensor_wrapper", {
        whenChanged: "wb-gpio/MOD2_IN1",
        then: function(newValue, devName, cellName) {
   
            if (newValue == true) {
                dev["rozetkas_controls/Иммитация протечки"] = 1;
                light_upper_leak_sensor = 1;
            } else {
                light_upper_leak_sensor = 0;
            }
   
        }
    });
   
   
   
    defineRule("set_alarm_off", {
        whenChanged: "wb-gpio/EXT5_DR6",
        then: function(newValue, devName, cellName) {
   
            if (newValue == true) {
                dev["rozetkas_controls/Иммитация протечки"] = 0;
            }
   
        }
    });
   
   
   
    defineRule("protechka_handler", {
        whenChanged: "rozetkas_controls/Иммитация протечки",
        then: function(newValue, devName, cellName) {
            if (newValue == true) {
                light_under_alarm_button = 1;
   
                ZATOPLENIE_FLAG = true;
                dev["wb-mrgb_4/RGB"] = "255;0;0";
                log(dev["wb-mrgb_4/RGB"]);
                dev["wb-gpio/EXT2_K2"] = true;
                startTicker("button_blinking_timer", dev["rozetkas_controls/Частота индикации при аварии"])
            } else {
   
                light_under_alarm_button = 0;
                dev["wb-gpio/EXT2_K2"] = false;
                ZATOPLENIE_FLAG = false;
                dev["wb-mrgb_4/RGB"] = "0;255;0";
            }
        }
    });
   
    defineRule("blink_buttons", {
        when: function() {
            return timers.button_blinking_timer.firing;
        },
        then: function() {
            if (ZATOPLENIE_FLAG == true) {
                log("Firing!");
                light_under_rozetka_1 = !light_under_rozetka_1;
                light_under_rozetka_2 = !light_under_rozetka_2;
            }
   
            if (ROZETKA2_BLINKING_FLAG == true) {
                light_under_rozetka_2 = !light_under_rozetka_2;
            }
   
            if (ROZETKA1_BLINKING_FLAG == true) {
                light_under_rozetka_1 = !light_under_rozetka_1;
            }
   
            if (ZATOPLENIE_FLAG == false && ROZETKA1_BLINKING_FLAG == false && ROZETKA2_BLINKING_FLAG == false) {
                timers.button_blinking_timer.stop();
            }
        }
    });
</syntaxhighlight>
</div></div>

Версия 17:54, 3 декабря 2018

Страница находится в процессе наполнения

Общая информация

Демонстрационный стенд находится в нашем офисе в переговорной. Управление стендом возможно, как физически (находясь у нас в офисе), так и через веб-интерфейс (доступен удалённо) Для того, чтобы можно было наблюдать за происходящем на стенде, над ним закреплена IP-камера. При удалённом управлении следует учитывать, что IP-камера даёт задержку около 3х секунд.

Внешний вид демонстрационного стенда.

Подключённые устройства

Modbus устройства
Модель Описание
WB-MR6HV/I Мощный 6-ти канальный релейный модуль. Входы 220В. Подробнее.
WB-MR3LV/I Мощный 3-х канальный релейный модуль. Входы вида "Сухой контакт" Подробнее.
WB-MD2 Диммер ламп (как накаливания, так и светодиодных).

Номинальная мощность до 400Вт. Подробнее.

WB-MRGBW-D Диммер RGB-лент. Допустимый ток 3А на канал.

Отдельный канал для управления белыми лентами. Подробнее.

WB-MAP6S 6-ти канальный счётчик электроэнергии.

Подробнее.

WB-MRM2mini/no 2-х канальный релейный модуль в миниатюрном корпусе. Подробнее.
WB-MIR Модуль для управления устройствами посредством ИК сигналов (также, оснащён входом для температурного датчика). Подробнее.
Датчики
WB-MSW2 Универсальный датчик в элегантном корпусе. (Доступно измерение температуры, влажности, освещённости и звукового давления + подача звукового сигнала). Подробнее.
WB-MS/THLS Цифровой датчик температуры, влажности, освещённости и звукового давления с двумя входами для подключения 1-Wire датчиков. Подробнее.
WB-MSGR Комбинированный электрохимический датчик газов со встроенным реле. Подробнее.
WB-M1W2 Модуль для заведения двух 1-Wire датчиков в шину RS-485 и их опроса посредством Modbus. Подробнее.
Пристыковочные модули
WBIO-R10A8 Релейный модуль. До 7А/230В на канал. Идеален для

управления освещением/контакторами/моторами. Подробнее.

WBIO-HS-8 Модуль с 8 выходами вида "High Side Switch"

Подробнее.

WBIO-R1G16 Релейный модуль с 16-ю выходами и общим каналом.

Подробнее.

WBIO-DI-DR8 Модуль содержит 8 входов вида "Сухой контакт"

Подробнее.

WBIO-DI-HVD16 Модуль содержит 16 входов для детектирования высокого напряжения (220В).

Подробнее.

WBE2-DI-DR-3 Модуль расширения на 3 входа вида "Cухой кнтакт"

Вставляются внутрь корпуса Wiren Board Подробнее.

Правила

При написании своих правил через движок WB-Rules, важно помнить, что код в правилах выполняется асинхронно. Если, в привычном понимании, выполнение кода идёт сверху-вниз, то в данном случае, выполнением управляет событийная модель: когда происходит то или иное событие (изменение показаний датчика/срабатывание таймера/нажатие на кнопку), то выполняется соответствующий кусок кода, отвечающий за обработку этого события. Подробнее о работе движка правил и типовых конструкциях обработки событий можно узнать из соответствующей статьи. Для управления стендом как физически (путём нажатия на кнопки), так и удалённо через демонстрационный веб-интерфейс, были созданы виртуальные устройства. Логика управления стендом выглядт следующим образом: нажатие на кнопку/переключение в веб-интерфейсе => срабатывание виртуального устройства => выполнение правила.

Датчик движения

Датчик движения в веб-интерфейсе

При срабатывании загорается сигнализирующая лампа. Датчик имеет выход типа "Сухой контакт" и умеет сигнализировать либо наличие движения, либо его отсутствие. Если использовать такой датчик, например, для автоматического включения света, то нужно добавить задержку перед срабатыванием (для защиты от ложных срабатываний). Это можно легко сделать с помощью движка правил wb-rules (см. правило под спойлером). Выход датчика подключён к WBIO-DI-DR14, а сигнализационная лампа управляется через WBIO-R10-A8.

Показать код

    defineAlias("movement_lamp", "wb-gpio/EXT1_R3A2");
    defineAlias("movement_virtual_switch", "movement_sensor_control/Иммитация движения");
    defineAlias("movement_timeout_before", "movement_sensor_control/Задержка после начала движения");
    defineAlias("movement_timeout_after", "movement_sensor_control/Задержка после прекращения движения");
    
    var motion_timer_before = null;
    var motion_timer_after = null;
    
    defineVirtualDevice("movement_sensor_control", {
        title: "Датчик движения",
        cells: {
            "Иммитация движения": {
                type: "switch",
                value: false
            },
            "Задержка после начала движения": {
                type: "range",
                value: 2,
                min: 1,
                max: 10
            },
            "Задержка после прекращения движения": {
                type: "range",
                value: 2,
                min: 1,
                max: 10
            }
    
    
        }
    });
    
    defineRule("physical_movement_to_virtual_switch", {
        whenChanged: "wb-gpio/EXT5_DR8",
        then: function(newValue, devName, cellName) {
            movement_virtual_switch = newValue;
    
        }
    });
    
    
    defineRule("movement_handler", {
        whenChanged: "movement_sensor_control/Иммитация движения",
        then: function(newValue, devName, cellName) {
            if (newValue == true) {
                if (motion_timer_before) {
                    clearTimeout(motion_timer_before);
                }
                motion_timer_before = setTimeout(function() {
                    movement_lamp = 1;
                    motion_timer_before = null;
                }, movement_timeout_before * 1000);
            } else {
                if (motion_timer_after) {
                    clearTimeout(motion_timer_after);
                }
                motion_timer_after = setTimeout(function() {
                    movement_lamp = 0;
                    motion_timer_after = null;
                }, movement_timeout_after * 1000);
            }
        }
    });

Управление освещением

Управление из веб-интерфейса

Автоматически включает свет в зависимости от показаний датчика освещённости. Если показания датчика ниже некоторого порогового значения, то свет включается; если показания выше - свет выключается. Возможности движка правил позволяют гибко отображать информацию (показания датчика) и вручную задавать пороговое значение срабатывания. Уровень освещённости измеряется с помощью WB-MS-THLS, а освещение (лампа) управляется через WBIO-R1G16. Переключатель "Принудительное освещение датчика" нужен для имитации высокого уровня освещённости (управляет кусочком RGB-ленты, направленным на датчик освещения).

Код правила

        defineAlias("small_light_switcher", "wb-msgr_9/Relay");
        defineAlias("lamp1_switcher", "wb-gpio/EXT2_K1");
        
        var FORCE_ILLUMINANCE_FLAG = false;
        var FORCE_LAMP_FLAG = false;
        
        
        defineVirtualDevice("switch_small_light", {
            title: "Управление освещением",
            cells: {
                "Принудительное освещение датчика": {
                    type: "switch",
                    value: false
                },
                "Включить освещение вручную": {
                    type: "switch",
                    value: false
                },
                "Уровень освещения днём": {
                    type: "range",
                    value: 500,
                    max: 1000
                }
        
            }
        });
        
        
        defineRule("small_light_control", {
            whenChanged: "switch_small_light/Принудительное освещение датчика",
            then: function(newValue, devName, cellName) {
                if (newValue == true) {
                    small_light_switcher = 1;
                    FORCE_ILLUMINANCE_FLAG = true;
                    dev["switch_small_light/Включить освещение вручную"] = false
                } else {
                    small_light_switcher = 0;
                    FORCE_ILLUMINANCE_FLAG = false;
                }
            }
        });
        
        
        defineRule("manual_light_control", {
            whenChanged: "switch_small_light/Включить освещение вручную",
            then: function(newValue, devName, cellName) {
                if (MANUAL_SWITCHER_1_FLAG == false) {
                if (newValue == true) {
                    lamp1_switcher = 1;
                    FORCE_LAMP_FLAG = true;
                    dev["switch_small_light/Принудительное освещение датчика"] = false
                } else {
                    lamp1_switcher = 0;
                    FORCE_LAMP_FLAG = false;
            }
                }
            }
        });
        
        
        
        
        defineRule("illuminance_ms_thls", {
            whenChanged: "wb-ms-thls-v2_8/Illuminance",
            then: function(newValue, devName, cellName) {
                if (MANUAL_SWITCHER_1_FLAG == false) {
                if (FORCE_ILLUMINANCE_FLAG == false && FORCE_LAMP_FLAG == false) {
                    if (newValue < dev["switch_small_light"]["Уровень освещения днём"]) {
                        lamp1_switcher = 1;
                    } else {
                        if (newValue > dev["switch_small_light"]["Уровень освещения днём"]) {
        
                            lamp1_switcher = 0;
                }
                        }
                    }
                }
            }
        });

Ручное управление лампами

Помимо веб-интерфейса, лампочками можно управлять и вручную, физически нажав на соответствующий лампе выключатель. Правило обрабатывает нажатие на выключатель и управляет устройством, через которое подключена нужная лампа. Выключатели подключены к модулю WBIO-DI-DR14.

Код правила

    defineAlias("lamp1_switcher_control", "wb-gpio/EXT2_K1");
    defineAlias("lamp2_switcher_control", "wb-mdm2_2/Channel 1");
    defineAlias("lamp3_switcher_control", "wb-mr3_3/K1");
    
    var MANUAL_SWITCHER_1_FLAG = false;
    var MANUAL_SWITCHER_2_FLAG = false;
    var MANUAL_SWITCHER_3_FLAG = false;
        
    
    defineRule("switcher_1", {
        whenChanged: "wb-gpio/EXT5_DR1",
        then: function(newValue, devName, cellName) {
         if (newValue == true) {
            MANUAL_SWITCHER_1_FLAG = true;
          lamp1_switcher_control = 1;
         }
         else {
         MANUAL_SWITCHER_1_FLAG = false;
         lamp1_switcher_control = 0;
         }
        }
    });
    
    
    
    defineRule("switcher_2", {
        whenChanged: "wb-gpio/EXT5_DR2",
        then: function(newValue, devName, cellName) {
         if (newValue == true) {
            MANUAL_SWITCHER_2_FLAG = true;
          lamp2_switcher_control = 100;
         }
         else {
         MANUAL_SWITCHER_2_FLAG = false;
         lamp2_switcher_control = 0;
         }
        }
    });
    
    
    
    defineRule("switcher_3", {
        whenChanged: "wb-gpio/EXT5_DR3",
        then: function(newValue, devName, cellName) {
         if (newValue == true) {
            MANUAL_SWITCHER_3_FLAG = true;
          lamp3_switcher_control = 1;
         }
         else {
         MANUAL_SWITCHER_3_FLAG = false;
         lamp3_switcher_control = 0;
         }
        }
    });

Имитация управления кондиционером

Управление из веб-интерфейса

Демонстрирует возможность управления кондиционером, в зависимости от температуры в помещении. Температура измеряется с помощью 1-Wire датчика, а команды на кондиционер посылаются с помощью WB-MIRv2. Пользователь выбирает оптимальную для него температуру и границы диапазона, в которых температура в помещении считается приемлемой. Если показания датчика температуры выходят за границы допустимого диапазона, с помощью WB-MIR посылаются команды по управлению кондиционером (можно увидеть на примере светодиодной ленты).

Код правила

   defineAlias("virtual_dimmer", "climate_system_control/Диммирование нагревателя");
   defineAlias("physical_dimmer", "wb-mdm2_2/Channel 1");
   defineAlias("temperature_sensor", "wb-m1w2_7/External Sensor 2")
   defineAlias("optimal_temp_value", "climate_system_control/Оптимальная температура");
   defineAlias("temp_range", "climate_system_control/Границы диапазона");
   
   defineAlias("turn_on_red", "wb-mir-simple_10/Play from ROM1");
   defineAlias("turn_on_green", "wb-mir-simple_10/Play from ROM3");
   defineAlias("turn_on_blue", "wb-mir-simple_10/Play from ROM2");
   
   defineVirtualDevice("climate_system_control", {
       title: "Управление климатом",
       cells: {
           "Диммирование нагревателя": {
               type: "range",
               value: 20,
               min: 1,
               max: 100
           },
           "Оптимальная температура": {
               type: "range",
               value: 24,
               min: 1,
               max: 35
           },
           "Границы диапазона": {
               type: "range",
               value: 28,
               min: 1,
               max: 5
           }
   
   
   
   
       }
   });
   
   
   
   defineRule("virtual_dimmer_to_physical", {
       whenChanged: "climate_system_control/Диммирование нагревателя",
       then: function(newValue, devName, cellName) {
           if (MANUAL_SWITCHER_2_FLAG == false) {
               physical_dimmer = newValue;
           }
       }
   });
   
   
   
   defineRule("indicate_temp", {
       whenChanged: "temperature_sensor",
       then: function(newValue, devName, cellName) {
           if (newValue <= optimal_temp_value - temp_range) {
               turn_on_blue = 1;
               log("Low");
           }
   
           if ((newValue > optimal_temp_value - temp_range) && (newValue < optimal_temp_value + temp_range)) {
               turn_on_green = 1;
               log("normal");
           }
   
           if (newValue >= optimal_temp_value + temp_range) {
               turn_on_red = 1;
               log("High");
           }
       }
   });

Управление вентилятором и миниреле

Доступно на виджете "Показания в комнате". Основная идея управления - создание виртуального устройства, а затем, при физическом нажатии на кнопку, переключается виртуальное устройство, которое, в свою очередь, уже переключает реле или вентилятор. Это сделано для дублирования управления как удалённо, так и физически. Нажатие физических кнопок отслеживает WBIO-DI-DR14, а подсветка кнопок реализована через WBIO-DO-HS8.

Код правила

    defineAlias("relay1_control", "wb-mrm2_11/Relay 1");
    defineAlias("relay1_button", "wb-gpio/EXT5_DR9");
    defineAlias("relay_button_lamp", "wb-gpio/EXT3_HS4");
    defineAlias("virtual_mrm2_mini_switch", "virtual_mrm2_mini/Включить вручную");
    
    defineAlias("fan_control", "wb-gpio/EXT3_HS5");
    defineAlias("fan_button", "wb-gpio/EXT5_DR7");
    defineAlias("fan_button_lamp", "wb-gpio/EXT3_HS6");
    defineAlias("virtual_fan_switch", "virtual_fan/Включить вручную");
    
    defineVirtualDevice("virtual_fan", {
        title: "Управление вентилятором",
        cells: {
            "Включить вручную": {
                type: "switch",
                value: false
            }
        }
    });
    
    defineVirtualDevice("virtual_mrm2_mini", {
        title: "Управление миниреле",
        cells: {
            "Включить вручную": {
                type: "switch",
                value: false
            }
        }
    });
    
    
    defineRule("fan_virtual_to_physical", {
        whenChanged: "virtual_fan/Включить вручную",
        then: function(newValue, devName, cellName) {
            fan_control = newValue;
            fan_button_lamp = newValue;
    
        }
    });
    
    
    defineRule("mrm2_mini_virtual_to_physical", {
        whenChanged: "virtual_mrm2_mini/Включить вручную",
        then: function(newValue, devName, cellName) {
            relay1_control = newValue;
            relay_button_lamp = newValue;
    
        }
    });
    
    
    
    defineRule("fan_manual_turn_on", {
        whenChanged: "wb-gpio/EXT5_DR7",
        then: function(newValue, devName, cellName) {
            if (newValue == true) {
                virtual_fan_switch = !virtual_fan_switch;
    
            }
        }
    });
    
    
    
    defineRule("mini_relay_manual_turnon", {
        whenChanged: "wb-gpio/EXT5_DR9",
        then: function(newValue, devName, cellName) {
            if (newValue == true) {
                virtual_mrm2_mini_switch = !virtual_mrm2_mini_switch;
    
            }
        }
    });

Ручное управление розетками

Для наглядности, обработка нажатий на кнопки под розетками вынесена в отдельное правило. При нажатии на кнопку, загорается световой индикатор вокруг неё и включается соответствующая розетка. Физическое нажатие на кнопку переключает виртуальное устройство, на переключение которого уже и завязаны все действия.

Код правила

    defineAlias("rozetka1_control", "wb-mr6c_1/K1");
    defineAlias("rozetka1_button", "wb-gpio/EXT5_DR5");
    defineAlias("rozetka2_control", "wb-mr6c_1/K2");
    defineAlias("rozetka2_button", "wb-gpio/EXT5_DR4");
    defineAlias("rozetka1_virtual_control", "rozetkas_controls/Включить розетку 1");
    defineAlias("rozetka2_virtual_control", "rozetkas_controls/Включить розетку 2");
    
    
    
    defineRule("rozetka1_manual_turn_on", {
        whenChanged: "rozetka1_button",
        then: function(newValue, devName, cellName) {
            if (newValue == true) {
                rozetka1_virtual_control = !rozetka1_virtual_control;
    
            }
        }
    });
    
    
    
    defineRule("rozetka2_manual_turn_on", {
        whenChanged: "rozetka2_button",
        then: function(newValue, devName, cellName) {
            if (newValue == true) {
                rozetka2_virtual_control = !rozetka2_virtual_control;
    
            }
        }
    });

Управление нагревателем

Управление из веб-интерфейса

Поддерживает температуру в помещении между двумя заданными пороговыми значениями. Если температура в помещении ниже нижнего порога, то включается нагреватель. Если температура превышает верхний порог, то нагреватель отключается. Температура измеряется датчиком 1-Wire, а в роли нагревателя выступает лампа накаливания, расположенная рядом с ним. Для большей наглядности процесса, был добавлен маленький вентилятор, охлаждающий датчик. Поэтому, финальный алгоритм работы выглядит так: температура превышает верхний порог => выключается нагреватель и включается вентилятор; температура опускается за нижний порог => включается нагреватель и выключается вентилятор. Цифровой датчик 1-Wire подключён с помощью модуля WB-M1W2, нагреватель управляется с помощью WB-MR3LV/I, а вентилятором управляет WB-MRM2mini.

Код правила

    defineAlias("temperature_sensor_value", "wb-mir-simple_10/External Temperature Sensor");
    defineAlias("small_fan_switcher", "wb-mrm2_11/Relay 2");
    defineAlias("lamp3_switcher", "wb-mr3_3/K1");
    defineAlias("fan_virtual_switcher", "lamp3_manual/Включить вентилятор вручную");
    defineAlias("lamp3_virtual_switcher", "lamp3_manual/Включить вручную");
    
    var MANUAL_FAN_FLAG;
    var MANUAL_LAMP3_FLAG;
    
    
    defineVirtualDevice("lamp3_manual", {
        title: "Управление нагревателем",
        cells: {
            "Включить вручную": {
                type: "switch",
                value: false
            },
            "Включить вентилятор вручную": {
                type: "switch",
                value: false
            },
            "Верхний порог температуры": {
                type: "range",
                value: 26,
                max: 40
            },
            "Нижний порог температуры": {
                type: "range",
                value: 23,
                max: 40
            }
        }
    });
    
    
    defineRule("manual_lamp3_control", {
        whenChanged: "lamp3_manual/Включить вручную",
        then: function(newValue, devName, cellName) {
            if (MANUAL_SWITCHER_3_FLAG == false) {
                if (newValue == true) {
                    lamp3_switcher = 1;
                    //dev["lamp3_manual/Включить вентилятор вручную"] = false;
                    //MANUAL_LAMP3_FLAG = true;
                } else {
                    //MANUAL_LAMP3_FLAG = false;
                    lamp3_switcher = 0;
                }
            }
        }
    });
    
    
    defineRule("manual_fan_control", {
        whenChanged: "lamp3_manual/Включить вентилятор вручную",
        then: function(newValue, devName, cellName) {
            if (newValue == true) {
                small_fan_switcher = 1;
                //dev["lamp3_manual/Включить вручную"] = false;
                //MANUAL_FAN_FLAG = true;
            } else {
                small_fan_switcher = 0;
                //MANUAL_FAN_FLAG = false;
            }
        }
    });
    
    
    
    
    defineRule("heater_hysteresis", {
        whenChanged: "wb-mir-simple_10/External Temperature Sensor",
        then: function(newValue, devName, cellName) {
            if (MANUAL_SWITCHER_3_FLAG == false) {
                    if (newValue > dev["lamp3_manual"]["Верхний порог температуры"]) {
                        fan_virtual_switcher = 1;
                        lamp3_virtual_switcher = 0;
                    } else {
                        if (newValue < dev["lamp3_manual"]["Нижний порог температуры"]) {
                            fan_virtual_switcher = 0;
                            lamp3_virtual_switcher = 1;
                        }
                }
            }
        }
    });

Управление розетками

Управление из веб-интерфейса

Позволяет включать и выключать розетки как вручную с помощью кнопок под ними, так и через веб-интерфейс. Если розетка включена, вокруг соответствующей ей кнопки горит зелёный индикатор. Если напряжение, поступающее в розетку, пропадает, розетка запоминает своё состояние (была включена или нет) и переходит в режим аварии, о чём свидетельствует мигание соответствующего ей индикатора. При возврате напряжения, розетка принимает своё исходное состояние. Рядом с розетками установлен датчик протечки типа "Сухой контакт". Если на датчик попала вода (можно имитировать переключателем "Воздействие водой на датчик протечки"), то обе розетки переходят в режим аварии, а большая RGB-лента, сигнализирующая статус работы, меняет цвет на красный. Напряжение на розетках коммутируется через WB-MR6HV/I, датчик протечки подключён через внутренний модуль расширения WBE2-DI-DR3, нажатия кнопок детектирует модуль WBIO-DI-DR14, а световыми индикаторами вокруг кнопок управляет WBIO-DO-HS8.

Код правила

    defineAlias("light_under_rozetka_1", "wb-gpio/EXT3_HS2");
    defineAlias("light_under_rozetka_2", "wb-gpio/EXT3_HS1");
    
    defineAlias("light_upper_rozetka_1", "wb-mr6c_1/K1");
    defineAlias("light_upper_rozetka_2", "wb-mr6c_1/K2");
    
    defineAlias("rozetka1_control", "wb-mr6c_1/K1");
    defineAlias("rozetka2_control", "wb-mr6c_1/K2");
    
    defineAlias("rozetka1_virtual_control", "rozetkas_controls/Включить розетку 1");
    defineAlias("rozetka2_virtual_control", "rozetkas_controls/Включить розетку 2");
    
    defineAlias("rozetka1_input", "wb-mr6c_1/Input 1");
    defineAlias("rozetka2_input", "wb-mr6c_1/Input 2");
    
    defineAlias("leak_sensor_input", "wb-gpio/MOD2_IN1");
    defineAlias("alarm_button", "wb-gpio/EXT5_DR6");
    defineAlias("light_under_alarm_button", "wb-gpio/EXT3_HS3");
    defineAlias("light_upper_leak_sensor", "wb-gpio/EXT1_R3A1");
    
    var ROZETKA1_FORCE_FLAG = false;
    var ROZETKA2_FORCE_FLAG = false;
    
    var ROZETKA1_BLINKING_FLAG = false;
    var ROZETKA2_BLINKING_FLAG = false;
    
    var ZATOPLENIE_FLAG = false;
    
    defineVirtualDevice("rozetkas_controls", {
        title: "Управление розетками",
        cells: {
            "Включить розетку 1": {
                type: "switch",
                value: false
            },
            "Включить розетку 2": {
                type: "switch",
                value: false
            },
            "Иммитация протечки": {
                type: "switch",
                value: false
            },
            "Частота индикации при аварии": {
                type: "range",
                value: 700,
                min: 600,
                max: 2500
            }
    
        }
    });
    
    
    defineRule("rozetka1_turn_on", {
        whenChanged: "rozetkas_controls/Включить розетку 1",
        then: function(newValue, devName, cellName) {
            if (dev["rozetkas_controls/Иммитация протечки"] == false) {
                if (ROZETKA1_FORCE_FLAG == false) {
                    log("Force flag is false on rozetka 1");
                    rozetka1_control = newValue;
                }
                if (ROZETKA1_FORCE_FLAG == true) {
                    log("Not working");
                }
            }
        }
    });
    
    
    
    defineRule("rozetka1_turnonlight", {
        whenChanged: "wb-mr6c_1/K1",
        then: function(newValue, devName, cellName) {
    
            light_under_rozetka_1 = newValue;
    
    
        }
    });
    
    
    
    
    defineRule("Input1_handler", {
        whenChanged: "wb-mr6c_1/Input 1",
        then: function(newValue, devName, cellName) {
            if (newValue == false) {
                ROZETKA1_FORCE_FLAG = true;
                rozetka1_initial_state = rozetka1_virtual_control;
                rozetka1_control = false;
                log(rozetka1_control);
                rozetka1_virtual_control = false;
                ROZETKA1_BLINKING_FLAG = true;
                startTicker("button_blinking_timer", dev["rozetkas_controls/Частота индикации при аварии"])
                log("Rozetka 1 was ", rozetka1_initial_state, "before poweroff")
            }
            if (newValue == true) {
                log("Power on rozetka 1 is turned on!");
                ROZETKA1_BLINKING_FLAG = false;
                ROZETKA1_FORCE_FLAG = false;
    
                rozetka1_virtual_control = rozetka1_initial_state;
            }
        }
    });
    
    
    defineRule("rozetka2_turn_on", {
        whenChanged: "rozetkas_controls/Включить розетку 2",
        then: function(newValue, devName, cellName) {
            if (dev["rozetkas_controls/Иммитация протечки"] == false) {
                if (ROZETKA2_FORCE_FLAG == false) {
                    log("Force flag is false on rozetka 2");
                    rozetka2_control = newValue;
                }
                if (ROZETKA2_FORCE_FLAG == true) {
                    log("Not working");
                }
            }
        }
    });
    
    
    
    defineRule("rozetka2_turnonlight", {
        whenChanged: "wb-mr6c_1/K2",
        then: function(newValue, devName, cellName) {
    
            light_under_rozetka_2 = newValue;
    
        }
    });
    
    
    
    
    defineRule("Input2_handler", {
        whenChanged: "wb-mr6c_1/Input 2",
        then: function(newValue, devName, cellName) {
            if (newValue == false) {
                ROZETKA2_FORCE_FLAG = true;
                rozetka2_initial_state = rozetka2_virtual_control;
                rozetka2_control = false;
                log(rozetka2_control);
                rozetka2_virtual_control = false;
                log("Rozetka 2 was ", rozetka2_initial_state, "before poweroff")
                ROZETKA2_BLINKING_FLAG = true;
                startTicker("button_blinking_timer", dev["rozetkas_controls/Частота индикации при аварии"])
            }
            if (newValue == true) {
                log("Power on rozetka 2 is turned on!");
                ROZETKA2_FORCE_FLAG = false;
                ROZETKA2_BLINKING_FLAG = false;
    
                rozetka2_virtual_control = rozetka2_initial_state;
            }
        }
    });
    
    
    
    defineRule("leak_sensor_wrapper", {
        whenChanged: "wb-gpio/MOD2_IN1",
        then: function(newValue, devName, cellName) {
    
            if (newValue == true) {
                dev["rozetkas_controls/Иммитация протечки"] = 1;
                light_upper_leak_sensor = 1;
            } else {
                light_upper_leak_sensor = 0;
            }
    
        }
    });
    
    
    
    defineRule("set_alarm_off", {
        whenChanged: "wb-gpio/EXT5_DR6",
        then: function(newValue, devName, cellName) {
    
            if (newValue == true) {
                dev["rozetkas_controls/Иммитация протечки"] = 0;
            }
    
        }
    });
    
    
    
    defineRule("protechka_handler", {
        whenChanged: "rozetkas_controls/Иммитация протечки",
        then: function(newValue, devName, cellName) {
            if (newValue == true) {
                light_under_alarm_button = 1;
    
                ZATOPLENIE_FLAG = true;
                dev["wb-mrgb_4/RGB"] = "255;0;0";
                log(dev["wb-mrgb_4/RGB"]);
                dev["wb-gpio/EXT2_K2"] = true;
                startTicker("button_blinking_timer", dev["rozetkas_controls/Частота индикации при аварии"])
            } else {
    
                light_under_alarm_button = 0;
                dev["wb-gpio/EXT2_K2"] = false;
                ZATOPLENIE_FLAG = false;
                dev["wb-mrgb_4/RGB"] = "0;255;0";
            }
        }
    });
    
    defineRule("blink_buttons", {
        when: function() {
            return timers.button_blinking_timer.firing;
        },
        then: function() {
            if (ZATOPLENIE_FLAG == true) {
                log("Firing!");
                light_under_rozetka_1 = !light_under_rozetka_1;
                light_under_rozetka_2 = !light_under_rozetka_2;
            }
    
            if (ROZETKA2_BLINKING_FLAG == true) {
                light_under_rozetka_2 = !light_under_rozetka_2;
            }
    
            if (ROZETKA1_BLINKING_FLAG == true) {
                light_under_rozetka_1 = !light_under_rozetka_1;
            }
    
            if (ZATOPLENIE_FLAG == false && ROZETKA1_BLINKING_FLAG == false && ROZETKA2_BLINKING_FLAG == false) {
                timers.button_blinking_timer.stop();
            }
        }
    });