Материал из Module developer
Перейти к: навигация, поиск
(Новая страница: «Remote is created like a Widget. The only difference is to select "Remote" when you click "Add Popup Page" in the "Device Type" property.»)
(Новая страница: «Interface design standard»)
Строка 129: Строка 129:
 
   
 
   
 
Remote is created like a Widget. The only difference is to select "Remote" when you click "Add Popup Page" in the "Device Type" property.  
 
Remote is created like a Widget. The only difference is to select "Remote" when you click "Add Popup Page" in the "Device Type" property.  
==Стандарт проектирования интерфейса==
+
==Interface design standard==
 
Для удобства проектирования интерфейса был разработан стандарт, в котором следует разрабатывать графические окна в модуле, чтобы модули разных разработчиков выглядели единообразно в рамках одного проекта.
 
Для удобства проектирования интерфейса был разработан стандарт, в котором следует разрабатывать графические окна в модуле, чтобы модули разных разработчиков выглядели единообразно в рамках одного проекта.
 
===Основные принципы===
 
===Основные принципы===

Версия 18:26, 3 апреля 2017

Другие языки:
English • ‎русский

Module development guide

Definitions

Module - is a component that allows you to control one type of equipment by its unique ID. The module is located in the store of modules.

Control panel (mobile device) - is a device from which the project i3 lite is launched (tablet, smartphone).

Store of modules - is a cloud server for uploading ready-made modules. The module store is available from the i3 lite application or on oursite

iRidium Studio - is a editor that allows to create the module to control device for i3 lite application. You need to use a special editor build for module developers to develop the module

i3 lite - is an application to create, set and use i3 lite projects.

i3 lite project – is an automation project made up of ready equipment control modules. i3 lite projects differ from i2 Control projects: i3 lite projects can be edited dynamically without prior editing in iRidium Studio. i3 lite project consists of several small parts that can be put together into a single whole in i3 lite app with the help of the built-in constructor. It can also be easily edited in the app. As a result, a big number of intermediate processes are no longer necessary, such as installing software on PC, uploading projects on contol panels. All is done in one place - a control panel.

SubDevice - This is a virtual representation of the working area of the physical device. If we take as an example a 6-channel dimmer it has 6 sub-devices, because each independent device requires a separate control interface and connects to one channel.

Room (in i3 lite) - The visual part of i3 lite containing hardware management widgets. The project in i3 lite consists of rooms located on the floors

Widget - is a visual module component located in the room. It has limitations in size and fixed position in the room interface. It contains the main module functionality. For additional functions Remote is used.

Remote - is a visual module component which is hidden by default. It opens only when clicking on the corresponding item of the widget. It does not have size limitations (not more than the panel display size) and can be located in any part of the room interface (it is usually located in the middle of the panel display). It contains additional functionality of the module.

Macros - is a sequence of commands of various modules, which is activated by pressing. Contains "Action" and "Condition". For example, the macros "turn off all the lights in the house" will send the shutdown command to all devices responsible for lighting.

Routine - is a sequence of commands of various modules, which is activated automatically when a certain event occurs. Contains "Event", "Action" and "Condition". For example, "turn on the light if the motion sensor is triggered"

Event - is a routine component that describes the control command and the value range. If the value is sent in the indicated range, the routine is executed. For example, the event "Motion appeared" is activated if the motion sensor is triggered.

Action - is a component of macros and routines. It describes the control command and value that must be sent to the command. For example, "turn on the light". There are 2 types of Action: Simple Action and Advanced Action.

Simple Action - Simple Action is used when the command and Action value are known in advance.

Advanced Action - Advanced Action is used when the command is known but the value is unknown. The value is set dynamically when Action is used in i3 lite (but not when creating in iRidium studio).

Condition - is a component of macros and scenes. It describes the control command and value range. When a value from the value range is sent Action is executed.

Scanner - is a software part, that analyzes any bus looking for connected devices. Found connected devices are displayed in a list. Modules for the found devices are downloaded from iRidium store and the devices become available to control in i3 lite.

Module concept

The module is an independent subroutine of the i3 lite application which is built in the project and has an independent interface, driver and logic. Modules are developed in the iRidium Studio editor and located in the module store iRidium Store. Integrator downloads the module from the module store for each individual project.

ModuleInScheme.png

There are two types of modules:

  • Control module - module for hardware control
  • Scanner - module for searching hardware in the local network and loading modules for found devices

How to start developing the module


Before starting your work, it is recommended to read iRidium documentation. It describes the basics of working with iRidium. The i3 lite documentation describes how to develop modules for the i3 lite platform for users, who already know iRidium. If you want to write script use i3 lite API.


The module life cycle consists of:

  • Developing the graphic part in iRidium studio
  • Developing the driver part (scripts, devices)
  • Testing
  • Publishing in iRidium store
  • Using (module download via the i3 lite application from the cloud and adding to automation projects)


Module structure

Each module must consist of subdevices. The subdevice is a virtual representation of the working area of ​​a physical device. Many devices support multiple workgroups with the same functionality. Each workgroup may be in a separate zone. To fully control the zone, you need to create a subdevice for each workgroup of the device. For example, a 6-channel HDL dimmer contains 6 dimmable channels, through which 6 working groups can be controlled. Therefore, it is advisable to select in the module 6 subdevices for the possibility of creating actions, events and conditions for each workgroup separately. The presence of subdevice in the i3 lite module is obligatory. The number of sub-devices can be from one to many. Usually the number of subdevice is equal to the number of channels of the controller, the number of its work areas or logical devices.

Subdevice consists of:

  • Conditions
  • Actions
  • Events
  • Widgets

Conditions, actions and events are logical elements of the subdevice, on their basis macros and routines are created. Widget is a graphical element, through which the user will control subdevice. Usually one subdevice contains one widget, but the number of conditions, actions and events varies (from zero to many). The number of subdevices in the module can be either fixed or not. For example, you can develop a module only for a 6-channel dimmer, and you can make a module that will request the hardware for the number of subdevices and create the required number of subdevices.

ModuleStruct.png

Creating the module interface

The interface part of the midule consists of:

  • widgets - interface part of the subdevice, which is located in the rooms and has basic control functions
  • Remote - interface part of the module, which has a set of device functions and opens to the full screen, when you click on the widget button
  • Authorization window - Authorization is required to work with some devices. To do this, the developer can create a special authorization window that is available in the module settings

картинка кнопки авторизации и окна авторизации

  • The module settings window is a window where you need to enter the parameters for the module operation

картинка окна настроек модуля и кнопки открытия

The whole graphic part is drawn in the graphical interface of the iRidium studio editor. In contradistinction to i3 pro, the module's interface should be made up of ready-made graphic components located in the gallery.

Widget

Widget is a visual component of the module, a kind of Popup that will be displayed in the room. The main task of the widget is to display the basic controls of the subdevice and to provide a module transition to the Remote control of the subdevice. For example, to control a media player, you can place a volume slider or Mute button for quick access to adjusting the volume. The weather widget can display the current weather, and the control panel will contain the weather forecast for all 5 days.
The module does not make sense without widget, because it will not have a graphical representation in the i3 lite project.

Widget has a limited size

  1. Width 640
  2. Height can not exceed 1200
Рис. Widget example


To create a widget, click the Add pop-up button in the Project overview panel and in the appeared menu select popup type: "Widget", set the name and properties:

ПанельПопап.png


Properties of a created widget can be changed with the help of Object Properties.
Graphic items are assigned to channels like in popups:

Рис. Связывание канала команды и графического элемента

Widget will be displayed:

  • In the room when a client uses the project
В комнате при использовании пользователем проекта.png
  • In the module settings when it is added to the project:
И в настройках модуля при добавлении его в проект.png

Remote and other graphic windows

Remote (a remote control) is a graphical area to control SubDevices. Unlike wigets, it can have free size and position. And it is displayed on call. Remote is displayed when a button to go to the remote control is pressed on a widget. Items to control equipment are placed on Remote (buttons, lists, switches, levels). There can be from 0 to several remote controls. Example of Remote:

Пульт управления.png

Remote is created like a Widget. The only difference is to select "Remote" when you click "Add Popup Page" in the "Device Type" property.

Interface design standard

Для удобства проектирования интерфейса был разработан стандарт, в котором следует разрабатывать графические окна в модуле, чтобы модули разных разработчиков выглядели единообразно в рамках одного проекта.

Основные принципы

GeneralUI.png

Виджет состоит из «Header» и дополнительных модулей основного функционала.
«Header» — верхний модуль виджета.
«Header» содержит:
- наименование виджета; - наименование устройства, которым
управляет виджет;
- иконка категории устройства.

Дополнительные модули содержат элементы управления устройством.

Модульная сетка и блоки

Setka1.png

Модульная сетка виджета представляет собой блоки 640 pt в ширину и 120 pt в высоту. Каждый блок имеет сетку 8х8 pt. Скругления углов равно 12,5 ut. (Circle 25)

Setka2.png

Принцип построения блока виджета представляет собой конструктор из элементов управления (кнопок, свитчей, лэйблов) от меньшего к большему.

Setka3.png

Элементы управления комбинируются и объединяются в блок, а блоки объединяются в панель управления.

Кнопки

Toggle

Toggle.png

Кнопка изменения значения «вкл/выкл». Применяется как в случаях с неизвестным состоянием работы устройства, так и для управления функционалом устройства.

Switch

Switch.png

Кнопка изменения значения «вкл/выкл». Применяется только в случаях с известным состоянием работы устройства.

Multistate

Multistate.png

Кнопка изменения значения предустановленного состояния устройства применяется только в случаях с известным cостоянием работы устройства.

Кнопка-стрелка

Arrow1.png
Arrow2.png

Действие кнопки
При нажатии на кнопку происходит вызов «PopUp».
Содержимое «PopUp»
«Input field», «Single selection», «Multiple selection».

Слайдеры

Standart

StandartSlider.png

Value

ValueSlider.png

Progress

ProgressSlider.png

Описание

Description.png

Иконки

Icons1.png

Все иконки делятся по сферам применения, и их главное различие — размеры

Icons2.png

Виджет «header»

WidgetHeader.png

Расположение кнопок

Форм фактор: 128х120 pt

FormFactor.png

Все кнопки имеют два состояния — покой и активность.

OFFicon.png
ONicon.png

В состоянии покоя цвет кнопки всегда # 848484 или RGB 132

Активным состояние кнопки считается только тогда, когда действие получило обратную связь является кратковременным или мгновенным (например: «Play» в медиаплеере) или действие, которое находится в состоянии активности продолжительное время и требует дополнительного воздействия для отключения состояния активности (например: «Repeat» в медиаплеере).

Основы работы со скриптами

После проектирования интерфейса и добавления драйвера, вам понадобится разработать логику работы модуля в скриптах. Скриптовая часть при разработке i3 lite модуля имеет некоторые особенности. Перед разработкой скриптовой части lite модуля рекомендуем ознакомиться с iRidium Pro API и i3 lite API.

Модуль может содержать неограниченное количество скриптов. Существуют разные типы скриптов для модуля:

  • Driver - в скриптовых файлах данного типа должны содержаться скрипты, отвечающие за работу с драйвером
  • GUI - В этих скриптовых файлах содержатся скрипты, отвечающие за работу с графикой
  • Common - в данных скриптовых файлах должны содержаться скрипты общего характера, тут может быть набор дополнительных функций или описание классов второстепенного назначения
  • Setup - это специальный скриптовой файл, в нем содержиться информация о настройке модуля. а именно - список полей, обязательных для заполнения, типы этих полей и функции проверки правильности введенных данных.


Разделение на типы необходимо для правильной обработки модуля на сервере. На сервере работает только логика и драверная часть модулей, но сервер ничего не знает о графической части. Поэтому разработчику модуля требуется разбивать скрипты по типам. Сервер игнорирует файлы для работы с графической частью.

При разработке модуля следует использовать простраство имен module вместо IR. Таким образом слушатель будет иметь вид module.AddListener(…

Каждый скриптовой файл должен начинаться со слушателя

module.AddListener(IR.EVENT_MODULE_START, 0, function(){});

Это новый вид события, предназначенный специально для разработки модуля. При разработке модуля следует учитывать что скриптовой файл стал закрыт для других скриптовых файлов. Это хзначить что теперь можно использовать одноименные переменные и названия функций в разных скриптовых файлах и они не будут перезаписываться, но это накладывает ограничение: нельзя получить доступ к функции из другого скриптового файла простым способом. Для получения доступа к функции из другого скриптового файла, следует импортировать скриптовый файл с помощью команды module.Import("FileName.js").
Пример:

//Name_1.js - первый js файл
this.Text = "Hello, world!"; //Указатель на текстовую переменную
//Name_2.js - второй js файл
var Text = module.Import("Name_1.js").Text; //Импортируем из первого js файла объект с указателем на текстовую переменную
IR.Log(Text); //"Hello, world!" //выводим в лог переменную Text

Создание подустройств

Основой любого модуля служат подустройства и задачей разработчика модуля является определить сколько подустройств будет в модуле и разработать логику работы подустройств. В состав каждого подустройства может входить виджет, пульт управления, собственный набор действий, событий и состояний. Все составляющие подустройства необходимо указать при его создании. Содержимое подустройства не может меняться в ходе работы модуля. Для создания подустройства используется команда:

module.AddSubDevice(SystemName, [Device], [System], [Type], [Tags], [Name], [Callback]);

,где
SystemName - системное имя подустройства
Device - драйвер, к которому будет привязано подустройство
System - устаревший параметр, следует использовать false
Type - тип smart устройства. Параметр в разработке
Tags - Массив объектов виртуальных тегов
Name - имя подустройства, которое отображается пользователю
Callback function(){do somethings} - функция, которая выполняется до наступления события IR.EVENT_ADD_SUBDEVICE
В ответ функция вернет ссылку на подустройство, по которой к нему можно обратиться.
Пример создания подустройств для HDL Relay устройств. Скрипт проверяет количество устройств в шине и в цикле создает подустройства

for (var count = 1; count <= COUNT_CHANNEL; count++) {      
      // Создаем подустройство
      l_oSubDevice = module.AddSubDevice("Relay " + count, HDL_SERVER, false, IR.SUB_DEVICE_TYPE_THROUGH_RELAY);       
      // Создаем команду StatusOnStart
      if (count == 1) 
         l_oSubDevice.AddChannel("Relay:statusOnStart", [ChannelData]);      
      var l_sChannelName = "Relay:channel" + count;       
      // Добавляем каналы
      l_oSubDevice.AddChannel(l_sChannelName, [ChannelData]);
      l_oSubDevice.AddTag(l_sChannelName, [ChannelData]);      
      // Добавляем виртуальный тег
      l_oSubDevice.AddVirtualTag("Power", 0, false, IR.SUB_DEVICE_TAG_POWER, true); 
   };

Таким способом можно добавить в подустройство все необходимые сущности. Также, при создании подустройства, активируется событие

module.AddListener(IR.EVENT_ADD_SUBDEVICE, 0, function, [pointer]);

В функцию передается ссылка на только что созданное подустройство. В данном событии можно добавлять к подустройству различные компоненты(действия, события, состояния, виджеты, каналы, теги). Например:

module.AddListener(IR.EVENT_ADD_SUBDEVICE, 0, function(in_oSubDevice){           
      Создаем действия
	  in_oSubDevice.AddAction("On", false, in_oSubDevice.SystemName + "_Power", lightID + "_1", IR.SUB_DEVICE_COMMAND_POWER_ON);                                                                                                     
      in_oSubDevice.AddAction("Off", false, in_oSubDevice.SystemName + "_Power", lightID + "_0", IR.SUB_DEVICE_COMMAND_POWER_OFF);
      Создаем события
      in_oSubDevice.AddEvent("On", "Drivers.PhilipsHue." + in_oSubDevice.SystemName + "_Power", false, "==", "1");
      in_oSubDevice.AddEvent("Off", "Drivers.PhilipsHue." + in_oSubDevice.SystemName + "_Power", false, "==", "0");         
      Создаем состояния
      in_oSubDevice.AddCondition("On", "Drivers.PhilipsHue." + in_oSubDevice.SystemName + "_Power", false, "==", "1");
      in_oSubDevice.AddCondition("Off", "Drivers.PhilipsHue." + in_oSubDevice.SystemName + "_Power", false, "==", "0");
   });

Таким образом разработчик может создавать нужное количество подустройств при установке модуля или ручном добавлении новых подустройств

Добавление виджетов к подустройству

Полсе создания интерфейсов в редакторе и добавления функции добавления подустройств, вам потребуется создавать для каждого поустройства свой экземпляр виджета и привязывать его к подустройству. Для привязки виджета к подустройству используется метод

SubDevice.addWidget(in_Widget)

Входным параметром метода является: in_Widget - объект - виджет, заранее созданный в редакторе.
Выходным параметром метода является: успешно или нет (True, False).
К примеру у нас 3 лампочки и для того, чтобы не создавать для каждой лампочки отдельный виджет, мы воспользуемся уже готовым примером нашего окна и просто будем клонировать его. Напишем пример создания виджета с помощью кода по уже существующему образцу.

Метод Clone позволяет клонировать уже существующее всплывающее окно.

Module.ClonePopup (in_Popup, in_Name)

Входные параметры метода:

  • in_Name - имя нового виджета.
  • in_Popup - ссылка на всплывающее окно.

Выходным параметром метода является: успешно или нет (True, False).

module.AddListener(IR.EVENT_ADD_SUBDEVICE, 0, function(in_oSubDevice){
 var popup = module.GetPopup("Dimmer"); // Обращаемся к виджету который собираемся скопировать
 // Создаем виджет методом клонирования
 var widget = in_oSubDevice.addWidget(module.ClonePopup(popup, "Dimmer"+ in_oSubDevice.Name));
 });


Имена новых виджетов не должны повторяться.


При открытии полноценного пульта управления из виджета, необходимо помнить о том что пользователь будет запускать модуль как на планшета, так и на телефоне. Из-за разницы в величине экранов, разработчик модуля должен разработать 2 вида окон. Вид под телефонную версию модуля и вид под планшетную версию. При этом надо добавить в скрипт метод, который будет спрашивать у системы вид устройства, на котором запущен модуль, и открывать соответствующее окно

 if (IR.DisplayType == IR.DISPLAY_TYPE_PHONE) { //Если модуль открыт на телефоне
    var l_oPopupScanner = module.GetPopup("Phone"); //Показываем попап, отрисованный для телефона
  }
 else {
   var l_oPopupScanner = module.GetPopup("Tablet");//Если планшет, то открываем попап для планшета
 }

Работа с каналами и тегами

После создания подустройства и добавления виджета, вам понадобится добавить к подустройству нужные для работы каналы и теги. Как и в версии i3 Pro, драйвер можно добавить в графическом интерфейсе редактора или в скрипте. Для каждого подустройства потребуется собственный набор каналов и тегов для выбранного драйвера. В ходе работы может потребоваться работать с тремя компонентами:

  • Канал. Для создания канала следует использовать метод
SubDevice.AddChannel(Name, DataArray)
где,

Name - имя канала
DataArray - массив данных, специфичный для каждого драйвера

  • Тег. Для создания тега следует использовать метод
SubDevice.AddTag(Name, DataArray)
где,

Name - имя тега
DataArray - массив данных, специфичный для каждого драйвера

  • Виртуальный тег. Для создания виртуального следует использовать метод
SubDevice.AddVirtualTag(Name, Value, [Edit], [smartID], [Hidden])
где,

Name- имя виртуального тега подустройства
Value - Значение тега
Edit - Разрешение редактирования тега
smartID - Параметр в разработке! Необходимо устанавливать false
Hidden - Признак скрытости тега

Пример создания каналов и тегов при создании подустройства:

l_oSubDevice = module.AddSubDevice("Light " + count, HDL_SERVER, false, IR.SUB_DEVICE_TYPE_THROUGH_DIMMER);
 
// Adding channel StatusOnStart
if (count == 1)
 l_oSubDevice.AddChannel("Dimmer:statusOnStart", [ChannelData]);
 
// Assigned to the variable name of the channel             
var l_sChannelName = "Dimmer:channel" + count; 
 
// Adding channels
l_oSubDevice.AddChannel(l_sChannelName, [ChannelData]);
l_oSubDevice.AddTag(l_sChannelName, [TagData]);
 
// Adding smart virtual tag
l_oSubDevice.AddVirtualTag("Power", 0, false, IR.SUB_DEVICE_COMMAND_POWER, true);
l_oSubDevice.AddVirtualTag("Power On", 0, false, IR.SUB_DEVICE_COMMAND_POWER_ON, true);
l_oSubDevice.AddVirtualTag("Power Off", 0, false, IR.SUB_DEVICE_COMMAND_POWER_OFF, true);
l_oSubDevice.AddVirtualTag("Level", 0, false, IR.SUB_DEVICE_COMMAND_LEVEL, true);

Установка модуля в приложение

Модули хранятся в магазине модулей iRidium Store и могут устанавливаться в приложение двумя способами:

  • С помощью сканера
  • Вручную

Разработка Setup

Для любого варианта необходимо разрабатывать файл Setup. Это специальный скриптовой файл, в котором прописаны поля, необходимые для работы модуля. Такими полями могут выступать ip адрес устройства, порт, название города итд. Для разработки Setup необходимо создать новый скриптовый файл и задать его тип "Setup". Каждое поле является тегом и к нему можно получить доступ из скрипта и получить введенное значение

СетапБонго.png

Файл Setup состоит из 2-ух частей. Первая часть это настройки драйверов. В этих настройках следует запрашивать ip адреса, порты и логины, для подключения драйвера у устройству. Вторая часть файла это общие настройки модуля, такие как количество выходов, ключи доступа. Для установки поля в Setup необходимо настроить следующие поля в скрипте:

  • Тип поля - надо указать какое поле надо показать пользователю(текстовое поле, массив значений итд. Подробнее описано в API)
  • Имя поля - название поля, которое увидит пользователь при настройке модуля
  • Значение по умолчанию - какое значение следует подставлять по умолчанию
  • Функция проверки - функция валидации значения в поле. Здесь требуется написать функцию, которая будет проверять корректность введенных данных.

Например, скрипт "Setup" для модуля HDL выглядит следующим образом:

{
	// Data to connect drivers, created in Project Device Panel
	Drivers: 
	[  
      {
         Name: "HDL-BUS Pro Network (UDP)",
         Properties: 
         [
            {
               Type: "textfield",
               Name: "Host",
               DefaultValue: "255.255.255.255",
               Validation: function(in_sValue) {
                  var l_aValueHost = in_sValue.split(".");
                  if (l_aValueHost.length != 4) {
                     return "Please input correct Host";                 
                  } else 
                     if (parseInt(l_aValueHost[0], 10)>=0 
                        && parseInt(l_aValueHost[0], 10)<=255 
                        && parseInt(l_aValueHost[1], 10)>=0  
                        && parseInt(l_aValueHost[1], 10)<=255 
                        && parseInt(l_aValueHost[2], 10)>=0  
                        && parseInt(l_aValueHost[2], 10)<=255 
                        && parseInt(l_aValueHost[3], 10)>=0  
                        && parseInt(l_aValueHost[3], 10)<=255
                     )
                        return 0
                     else
                        return "Please input correct Host";   
               }
            },
            {
               Type: "textfield",
               Name: "Port",
               DefaultValue: "6000",
               Validation: function(in_sValue) {
                 if(parseInt(in_sValue, 10)>=0)
                     return 0
                  else
                     return "Please input correct Port";
               }
            }
         ]
		}
	],
 
	// General information for the module (driver and generated by script)
	Module: [{
		Name: "Channels Count",
		Validation: function (in_sValue) {
			if (parseInt(in_sValue, 10)>=0)
				return 0;
			else
				return "Please input Count";
         }
      },
		{
         Type: "textfield",
			Name : "SubnetID",
			Validation : function (in_sValue) {
				if (parseInt(in_sValue, 10)>=0)
					return 0;
				else
					return "Please input SubnetID";
			}
		},
      {
         Type: "textfield",
			Name : "DeviceID",
			Validation : function (in_sValue) {
				if (parseInt(in_sValue, 10)>=0)
					return 0;
				else
					return "Please input DeviceID";
			}
		}
 
	] 
}

Для получения данных из полей Setup следует использовать функцию

module.GetProperty("Имя поля")


Помимо стандартных параметров, можно запрашивать любые, необходимые для инициализации модуля, параметры. Параметры драйвера подставляются в драйвер автоматически. Остальные параметры следует запрашивать и использовать вручную
Пример работы с параметрами Setup

var COUNT_CHANNEL = parseInt(module.GetProperty("Channel count")); // Getting count channel
var SubNetID = parseInt(module.GetProperty("SubnetID")); // Getting subnet id
var DeviceID = parseInt(module.GetProperty("DeviceID")); // Getting device id

Установка модуля вручную

Установка модуля с помощью сканера

Ручное добавление подустройств

Авторизация

Смена настроек

Удаление модуля