Навигация

    Forum

    • Зарегистрироваться
    • Войти
    • Поиск
    • Категории
    • Последние
    • Метки
    • Популярные
    • intraHouse Site
    1. Главная
    2. intrapro
    3. Лучшие сообщения
    I
    • Профиль
    • Подписки
    • Подписчики
    • Темы
    • Сообщения
    • Лучшие сообщения
    • Группы

    Лучшие сообщения intrapro

    • RE: Сценарии - новая версия API

      Участник @homa написал

      И следом вопрос корректно ли объявлять одно и тоже свойство для одного и того же устройства в разных сценариях, или есть какие-то другие варианты обращения к ранее объявленным свойствам

      идея в том, чтобы изменять из разных сценариев одно свойство... выходит не выходит)

      Почему не выходит? Без проблем можно обращаться к одному свойству устройства из нескольких сценариев. При этом достаточно объявить свойство в одном сценарии, в других можно и не объявлять. При объявлении это свойство создается на уровне устройства. Проблема отсутствия свойства может быть только при первом запуске и после перезагрузки.

      написал в Сценарии
      I
      intrapro
    • RE: Подключение DHT22 на RASPBERRY PI 4 GPIO

      @alexeyalvl, если порядок меняться не будет, то можно сделать так:

      Для считывания температуры (первый элемент):

      let value;
      if (!error && stdout) {
           value = parseFloat( stdout.split(' ').shift().split('=').pop() );
      }
      

      Для считывания влажности (второй элемент):

      let value;
      if (!error && stdout) {
           value = parseFloat( stdout.split(' ').pop().split('=').pop() );
      }
      

      Что тут делается:

      • stdout.split(' ') - строка разбивается на элементы, разделенные пробелом:
        [ 'Temp=24.3*', 'Humidity=48.6%' ]
      • shift() - берется первый элемент
        'Temp=24.3*'
      • split('=') - этот элемент разбивается на элементы, разделенные знаком =
        [ 'Temp', '24.3*' ]
      • pop() - берется последний элемент, то есть число
        '24.3*'
      • Результат обрабатывается функцией parseFloat, результат - 24.3

      Второе значение обрабатывается аналогично, только на втором шаге берется не первый элемент - shift(), а последний - pop()

      написал в Примеры сниппетов
      I
      intrapro
    • RE: Плагин MegaD

      Участник @Alex_Jet написал в Плагин MegaD:

      @intrapro, подключил ленту WS2818 к контроллеру, в канале плагина вписал команду управления /%pwd%/?pt=%adr%&ws=%value%&chip=151. Все работает, однако братья китайцы где-то напутали и поменяли местами R и G... как итог лента не RGB, а GRB... стандартными средствами плагина можно выйти из положения?

      Попробуйте в канале на вкладке Обработка прописать:
      Формула расчета выходного значения для актуаторов: [ value[1],value[0],value[2] ]

      Ну и входное тоже нужно так же:
      Формула расчета входного значения: [ value[1],value[0],value[2] ]

      Еще момент по уровню яркости. Если установить какой-нибудь цвет, то слайдер L по умолчанию переходит в значение 50. Если его двигать в сторону 0, то яркость выбранного цвета уменьшается, однако если двигать к 100, то яркость увеличивается, но и цвет плывет причем на 100 получается просто белый цвет. Это явно не верный алгоритм.

      Это вопрос спорный. Сейчас нужно ориентироваться, что трушный цвет при L=50

      А еще поработать бы с самим устройством. По идее индикатор 1 - это RGB параметры, а индикатор 2 - это уровень яркости. Однако сейчас индикатор 2 отображает, например, "0,255,0", хотя при настройке устройства на мнемосхеме отображается уровень в виде "100". При нажатии на устройство - ничего не меняется - (картинки одинаковые), уровень остается тот же.

      Да, с индикаторами не очень 😞 Сейчас наверху выводится текущее значение массива, внизу должно быть дефолтное значение (для команды on) Cостояния on/off должны переключаться. Попробуйте нажать кнопку Выключить в боковом меню. Должны уйти нули, а устройство перейти в состояние выключено. Ну а картинку для активного состояния сами раскрасьте 🙂

      написал в Плагины
      I
      intrapro
    • RE: Свет по датчику движения с дополнительными условиями.

      Участник @Erik написал

      И еще вопрос.

      Как при включенном по датчику движения свете по повторному срабатыванию датчика движения обнулять таймер?

      При условии if ((SAF.value === 0) && (sw.value === 0) && (lamp.value == 1)) проверить, что таймер запущен, и обнулить его (тот же самый таймер).

      Для этого нужно добавить внутрь сценария "слушателя событий"

      script({
          start() {
            if ((SAF.value === 0) && (sw.value === 0) && (lamp.value === 0)) {
               lamp.on();
               // взводим таймер, чтобы отключить 
               this.startTimer("T1", 180, "turnOff");       
              
              // Добавляем слушателей - следим за датчиком движения и светильником
              this.addListener(motion, "onMotion");
              this.addListener(lamp, "onLamp");
            }
          },
          
          onMotion() {
            // Если движение возобновилось - сбрасываем таймер
            if (motion.isOn() )  {
              this.stopTimer("T1");
            }  
             // Если движение прекратилось - взводим таймер (после повторных движений)
            if (motion.isOff() && this.timer.T1 == "off")  {
              this.startTimer("T1",  180, "turnOff");
            }  
          },
          
           onLamp() {
            // Светильник выключили другим способом - выходим
             if (lamp.isOff()) this.exit();
           },
           
          // Функция, которая сработает, когда таймер досчитает - отключаем и выходим
          turnOff() {
            lamp.off();
            this.exit(); // Здесь exit нужен, так как есть активные слушатели и сценарий сам не завершится
          }
      });
      

      Более подробно про механизм работы сценариев - https://ih-systems.com/ru/about-scenes/
      Если коротко:

      • Если внутри сценария просто последовательность действий, он отработает и сразу завершится (станет не активным). При следующем запуске он опять начнется со start(). Большая часть сценариев работает именно так и 99,9% времени находятся в неактивном состоянии.

      • Если сценарий взводит таймеры и/или устанавливает слушателя событий устройства, то он остается активным, следит за своими таймерами и устройствами «изнутри» и выполняет действия как реакцию на отслеживаемые события. Стартовое событие не работает, так как сценарий уже активен.. В рабочих сценариях в левом столбце у сценариев, активных в данный момент, стоит зеленая галочка.
        Чтобы завершить такой сценарий, нужно выполнить команду this.exit().
        При завершении сценария все его таймеры и слушатели удаляются. При следующем запуске опять выполнится start()

      написал в Сценарии
      I
      intrapro
    • RE: Вопросы по работе системы

      Пользователь @regabriel написал в Вопросы по работе системы:

      Здравствуйте. Не пойму ошибка или нет.
      Создаю устройство - виртуальный датчик температуры, чтобы в нем выводить среднюю температуру с нескольких других датчиков.
      Соответственно делаю мульти скриптик(так как таких средних будет несколько)
      в котором прописываю:

      const temp_room = Device("SensorA","Средняя температура комнаты"); 
      
      ....
      script({
          start() {
               temp_room.setValue(15);
      

      Так вот не работает x.setValue(15);
      Для "ActorA" работает.
      Это ошибка или так и должно быть?

      Добрый день. Да, все верно, датчику значение таким образом присвоить нельзя.
      Идея в том, что x.setValue задействует канал на запись, по которому значение записывается на железо. Датчик сам значение записать не может, его value только для чтения.
      Для реализации виртуального датчика есть команда this.assign( имя устр-ва, имя свойства, значение)

      this.assign(temp_room,"value",42);
      

      В настройках-> дополнительно ставлю метод определения состояния "вычисляется сценарием".

      Не совсем. У датчика есть value - значение и state - состояние, которое грубо говоря определяет картинку.
      Этот пункт относится к state, Вы же сценарием хотите присвоить value.
      Если нужно, чтобы средняя пересчитывалась динамически при изменении любого датчика, получится примерно так:

      const temp1 = Device("SensorA","Датчик 1"); 
      const temp2 = Device("SensorA","Датчик 2"); 
      const temp3 = Device("SensorA","Датчик 3"); 
      const temp4 = Device("SensorA","Датчик 4"); 
      const temp_room = Device("SensorA","Средняя температура комнаты"); 
      
      startOnChange([ temp1, temp2, temp3, temp4 ]); 
      
      script({
          start() {
              const average = (temp1.value+temp2.value+temp3.value+temp4.value)/4;
              this.assign(temp_room,"value", average);
        }
      })
      

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

      И второй вопрос: при создании устройства выбор - актуатор бинарный(т.е. 2 состояния)
      При этом в мультисценарии ActorD — дискретный актуатор.

      Дискретный актуатор - имеется в виду актуатор с конечным числом состояний.
      По умолчанию создается бинарный. Но можно расширить число состояний

      Можно ли сделать более 2 состояний у актуатора и датчика и как? Где посмотреть примеры или описания?

      Да, можно. Раздел Состояния устройств на странице https://ih-systems.com/ru/devices/

      По состояниям:

      • у дискретных датчиков и актуаторов обычно делают value=state,
        метод определения состояния "Стандартный"

      • у аналоговых можно использовать "Метод интервалов", то есть состояние расчитывается исходя из value, по нарастанию значения (более подробно см в док-и)

      метод определения состояния "вычисляется сценарием" после перехода на v4 не используется

      Также обратите внимание на 2 момента:

      1. Состояния должны нумероваться строго подряд, начиная с 0
      2. Если устройство уже стоит на мнемосхеме, после изменения числа состояний его нужно удалить и заново поставить. На мнемосхеме можно менять визуальное представление каждого состояния, причем каждое редактируется отдельно
      написал в intraHouse V4 Cherry
      I
      intrapro
    • RE: Плагин HTTP-Client

      @alesle пожалуйста 🙂
      Вот вариант еще короче

      data.onew_temp.find(item => item.name=="S6").t
      

      Современный javascript мощный и гибкий язык, особенно если использовать синтаксис ES6 (или ES2015, что одно и то же) , в данном случае стрелочные функции.
      Магия этих выражений раскрывается в 2 шага

      1. Массивы в JS имеют встроенные методы для поиска по заданному критерию, в частности filter, find

        • find - ищет первый элемент массива, возвращает найденный объект
        • filter - сюрприз 🙂 - фильтрует входной массив и возвращает все найденные элементы (learn.javascript.ru/array-methods)
      2. Методу нужно передать критерий отбора - функцию для обработки элемента массива.

        Если писать, используя синтаксис классических функций, то получится так:

         arr.filter( function (item) {
           return item.name == 'S6';  
        });
        

        Функция вызывается по очереди для каждого элемента массива (item), если возвращает true, то элемент берется в новый массив

        С введением в ES6 стрелочных функций все стало компактнее:

         function (item) {return item.name == 'S6';} 
        

        можно заменить на

         (item)  => item.name == 'S6' 
        

        Что произошло

      • убрали function
      • грубо говоря return заменили на =>
      • если входной аргумент ровно один - то и скобки можно не ставить

      Подробнее https://learn.javascript.ru/arrow-functions
      Получаем:

       arr.filter( item => item.name == 'S6' );
      

      Ну и надо иметь в виду, что возвращает метод массива.
      Если результат - массив, то берем свойство его первого элемента

      data.onew_temp.filter(item => item.name=="S6")[0].t
      

      Если результат - объект, то просто берем свойство t

      data.onew_temp.find(item => item.name=="S6").t
      
      написал в Плагины
      I
      intrapro
    • RE: Сценарии - новая версия API

      @Alex_Jet, Добрый день! @Erik прав - нужен актуатор, который можно переключать как угодно - интерактивно, сценарием, по расписанию...

      Сценарий гирлянды запускается при включении этого актуатора.

      Состояния в php скрипте меняются случайным образом, поэтому логика еще проще:

      1. Добавить слушателя для актуатора-триггера
      2. Генерировать строку цветов случайным образом
      3. Передать команду на MegaD
      4. Взвести таймер 1 сек

      По таймеру - повторить пункты 1-3
      При выключении триггера - завершить сценарий

      написал в Сценарии
      I
      intrapro
    • RE: Установка значений каналов через REST API

      Добрый день! В канал плагина установить данные через REST API не получится. Можно записать значение в свойство устройства минуя канал. Для этого нужно сгенерировать событие 'received:device:data'. Такое же событие генерируется при получении данных с плагина для привязанных к каналам устройств.
      Объект события: {<device1 ID>:{<prop1>:val1,...}, <device2 ID>:{<prop2>:val2,...} }
      Пример 1. Передается ID устройства, имя свойства и значение

      /**
       * Обработчик запроса REST API
       * /restapi/device/set?did=d0021&prop=setpoint&value=42
       *    => {d0021:{setpoint:42}}
       */
      module.exports = async (req, res, holder, debug) => { 
        try {
          const did =  req.query.did;
          const prop =  req.query.prop;
          const val =  req.query.value || 0;
          holder.emit('received:device:data', {[did]: {[prop]: val} });
          res.json({ res: 1});
        } catch (e) {
          res.json({ res: 0, message: e.message });
          debug(e.message)
        }
      };
      

      Пример 2. Передается dn (device name) устройства, по нему сначала нужно определить device ID

      /**
       * Обработчик запроса REST API
       * /restapi/device/set?dn=DT101&prop=setpoint&value=42
       *    => {d0021:{setpoint:42}}
       */
      module.exports = async (req, res, holder, debug) => { 
        try {
          const dn =  req.query.dn;
          const prop =  req.query.prop;
          const val =  req.query.value || 0;
          const dobj = holder.dnSet[dn];
          if (!dobj) throw {message:'Not found device '+dn};
          
          const did = dobj._id;
          holder.emit('received:device:data', {[did]: {[prop]: val} });
          res.json({ res: 1});
        } catch (e) {
          res.json({ res: 0, message: e.message });
          debug(e.message)
        }
      };
      

      Конечно, аналогично можно передать POST запрос с множеством значений

      написал в IntraSCADA V5
      I
      intrapro
    • RE: Плагин MegaD

      Пользователь @regabriel написал в Плагин MegaD:

      Здравствуйте. Разбираюсь с системой и возникает множество вопросов))

      1. Как настраивается в плагине в канале"Функция обработки значения"?
        в каком виде можно писать?
        Например датчик температуры, если он показывает меньше -40, либо ровно 0, либо больше 100 значит он неисправен, как это записать?

      Добрый день.
      Настройку интервала допустимых значений можно настроить прямо на устройстве (min-max) . Там же можно определить, что делать, если произошел выход из диапазона:

      • "Не принимать значение вне диапазона" - значение не будет присвоено
      • "Установить ошибку при выходе из диапазона"

      Можно эти флаги устанавливать независимо. Также можно контролировать поступление данных - "Установить ошибку если нет данных в течение (сек)"

      device_setting.png

      Функция обработки в канале используется, если нужна сложная предварительная обработка. Например, от контроллера получаем 5 значений, сортируем, откидываем минимальное и максимальное и вычисляем среднее. И именно вычисленное значение отдаем ядру системы.
      Пример такой функции для плагина MegaD приведен в описании плагина (в конце страницы):
      https://ih-systems.com/ru/product/plugin-megad/

      1. Где вообще можно посмотреть хорошее описание API по intraHouse? Например по работе с БД?

      Пользовательские SQL запросы к БД на уровне ядра в версии 4 не поддерживаются. Можно писать и читать из сценария с помощью функций this.dbread(), this.dbwrite().
      Если нужно напрямую работать с БД, есть возможность написать отдельный плагин. Документации на эту тему нет 😞 , но есть примеры реализации.

      1. Как проверять работу сложного скрипта? Как посмотреть результаты работы consol.log('') или использовать какие либо аналоги ?

      Для отладки скрипта есть "Отладчик" в нижнем окне сценария. Там выводится трассировка при выполнении команд, таймеров, проверки условий.
      Вместо console.log в скрипте используйте. this.log(''), сообщение будет выведено в этом же окне

      написал в Плагины
      I
      intrapro
    • RE: Сценарии - новая версия API

      @Alex_Jet
      Совершенно верно, параметры в сценарии напрямую не доступны, нужно использовать getParam("имя параметра") / setParam("имя параметра", значение).

      Просто dt.setpoint - это значение уставки. Для уставки есть специальная команда setSetpoint (да, довольно коряво 😞 )
      Другой вариант - любое свойство можно присвоить с помощью setParam.
      Таким образом, есть два варианта:

      dt.setSetpoint( dt.getParam("nightTemp") )
      

      или

      dt.setParam( "setpoint", dt.getParam("nightTemp") )
      
      написал в Сценарии
      I
      intrapro
    • RE: Установка значений каналов через REST API

      Добрый день, Александр! Очень изобретательно 🙂
      Но теперь понимаю, что задача у вас - организовать через API управление (запись на железо).
      Конечно, система должна предоставить для этого прямой способ.

      В версии 5.9 это к сожалению не работает, сейчас выполняем унификацию API для разных скриптов системы (скрипты визуализации, сценарии, REST API).

      В 5.10 (релиз выйдет в начале следующей недели) можно будет выполнять команды устройства напрямую:

      const dev = holder.getDevice('VENT1');             
      dev.setValue('setpoint', 22);        
      dev.on();          
      
      
      написал в IntraSCADA V5
      I
      intrapro
    • RE: Плагин MegaD

      Пользователь @Alex_Jet написал в Плагин MegaD:

      Пользователь @intrapro написал в Плагин MegaD:
      Помнится мне, что парсинг ON/OFF, temp/hum и прочее происходил "по умолчанию" только у каналов, у которых ID=0...37, либо X_1/X_2? А вот если канал имеет какое-нибудь отличное от числа значение, то этот парсинг не выполняется? Или это было с чем-то другим связано?

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

      Или уже нет смысла переписывать код плагина поскольку в версии 5 все будет совсем по другому?

      Планируется, что все плагины и сценарии из v4 будут работать в v5

      Вообще, код плагина MegaD просто ужасен... по мне так легче все заново написать. Было бы время и знания по API iH....

      С прагматичной точки зрения, код плохой, если:

      • программа работает нестабильно: зависает или вылетает, игнорирует ошибки
      • требует постоянной поддержки, так как нестандартные ситуации не обрабатывает или реагирует неадекватно
      • хорошо работает на компьютере разработчика, но при установке в мало-мальски другое окружение нужны ритульные пляски и сакральные знания
      • при необходимости доработки нужно не забыть внести изменения в несколько мест (искать всюду 37 канал, например 🙂

      Про плагин MegaD ничего такого сказать нельзя. Он работает стабильно, надежно уже несколько лет.
      Вопросы от пользователей и доработки связаны с расширением функционала - (MCP, _A и _B,.. Плюс эпопеи с контроллером, но это другая история)
      Есть также плюс, который не очевиден для людей, любящих покодить - порог вхождения при использовании плагина MegaD очень низкий, простой функционал настраивается очень просто.

      Также можно рассмотреть вариант, предлагаемый во многих системах - нет плагина MegaD, вот вам http-клиент, дальше сами.
      Эта возможность в IH тоже есть, даже 2 варианта:

      • создавать сниппеты для каждого устройства и запускать их периодически;
      • использовать плагин http

      Для чтения CNT, кстати, это тоже решение (но не забыть при этом обрабатывать ошибки связи, если хочется сделать не поделку, которая работает при демонстрации, а реально работающий проект). И если на MegaD идет одновременно очень много независимых запросов, помнится, тоже были проблемы. Ну и по поводу CNT для счетчика - просто интересно, как решается вопрос, когда контроллер при потере питания сбрасывает значение?
      Если порт заявляется как счетчик, он IMHO должен хранить значение при отключении питания. Например в оборудовании KernelChip счетчик - это счетчик, ему можно доверять.

      С позиции чистого искусства - да, соглашусь, код выглядит несовременно и не очень консистентно, API v4 работы с плагинами не используется. Также выглядит не очень понятно работа с входящими сообщениями.

      Хорошо бы все переписать на ES6 и с применением API. И придумать понятный механизм. И чтобы любая новинка MegaD сразу была реализована 🙂 И чтобы этим занимался специалист по MegaD.
      В v5 мы планируем предложить сообществу активнее разрабатывать плагины. Со стороны системы будет обеспечено:

      • открытое API для создания плагинов;
      • возможность декларативного описания настройки каналов и свойств, в том числе древовидные структуры
      • простой механизм подключения плагина к системе и отладка;
      • продвижение плагинов сторонних разработчиков через портал

      И пусть каждый желающий напишет плагин своей мечты 🙂

      написал в Плагины
      I
      intrapro
    • RE: Сниппеты на каждую функцию устройства.

      Участник @homa написал в Сниппеты на каждую функцию устройства.:

      А для сниппетов работаю интервалы? Что-то не получается...

      Проверили, должно работать.
      Если у вас аналоговый датчик, нужно, чтобы на вкладке Дополнительно в списке Метод определения состояния было выбрано Аналоговое значение - интервалы.
      Если сниппет возвращает значения подряд (0,1,...x), то можно сделать еще проще: взять дискретный датчик, у него добавить состояния 0,1,...x, метод переключать не надо, т к для дискретных датчиков состояние=значение

      В любом случае, если устройство уже стояло на мнемосхеме, а потом были добавлены состояния, то нужно устройство удалить и заново разместить, иначе будет ошибка Bad device

      написал в Сниппеты
      I
      intrapro
    • RE: Сценарии - новая версия API

      Пользователь @alesle написал в Сценарии - новая версия API:

      Таймер - суть локальная для сценария?

      Да, верно. Сценарии друг от друга изолированы, таймеры существуют только внутри конкретного сценария

      Т.е можно ли из одного сценария сбросить таймер запущеный в другом сценарии?

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

      Вариант 1. Вместе с основным таймером запустить короткий таймер (1 сек, 0.5 сек), который проверяет какое-то условие, и если нужно - сбрасывает основной таймер (или завершает сценарий)

         start() {
                // что-то делаем   
                // взводим основной таймер на минуту 
                this.startTimer("T1", 60, "onT1");   
               
               // взводим доп таймер на секунду 
               this.startTimer("T2", 1, "onT2");      
        },
      
        onT2() {
             // Что-то проверяем - например общую (глобальную) переменную, которую взведет другой сценарий
            if (global.myFlag)  {
              this.exit();  // Выходим, при этом все таймеры этого сценария сбрасываются
            } else {     
               this.startTimer("T2", 1, "onT2"); // иначе взводим доп таймер заново 
            }      
        },
        onT1() {
               // Основной таймер продержался - что-то делаем....
              this.exit(); // завершаем сценарий
         }      
      }
      

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

      Вариант 3. Если доп. устройство добавлять не хочется, можно добавить дополнительный параметр существующему устройству, слушать события этого устройства, в слушателе проверять, что изменился именно этот параметр:

      if (this.isChanged(dev1, 'myflag', 1)  {
          this.stopTimer("T1");
          //  Не забывать завершать сценарий, так как при наличии слушателя сам он не завершится
          this.exit();
      }
      
      написал в Сценарии
      I
      intrapro
    • RE: Плагин MQTT

      @div115, добрый день
      При запуске сценария при получении топика функция start автоматически получает объект {topic, message} как входящий аргумент:

      script({
          start({topic, message}) {
              this.log('Topic '+topic+' message='+message);
          }
      
      написал в Плагины
      I
      intrapro
    • RE: Сниппеты

      @Alex_Jet Если работает, то по старому анекдоту про программиста и солнце, лучше и не трогать 🙂

      А серьезно (так понимаю, ожидается вещественное число), обработку результата можно сделать так:

      res.on('end', () => {
            const value = parseFloat(rawData);   
            callback(isNaN(value) ? "Не числовое значение "+rawData : "", value); 
      });
      

      Если придет не число, то в журнале устройства будет сообщение об ошибке

      написал в Сниппеты
      I
      intrapro
    • RE: Сценарии - новая версия API

      @Alex_Jet, скобочки в значениях ломают парсинг.
      Так будет работать:

       "note":"Гистерезис для управления, %"
      
      написал в Сценарии
      I
      intrapro
    • RE: Сценарии - новая версия API

      Пользователь @Alex_Jet написал в Сценарии - новая версия API:

      Только если ответите по поводу оптимальности такого кода)

      Код на мой взгляд хороший, с литералами работа происходит быстро.
      Это всегда дилемма - универсальность или скорость/простота.

      Если по синтаксису - массив можно заполнить проще:

         const obj = []; // Объявляем пустой массив obj. push добавляет элементы-объекты
         obj.push({ip:"192.168.11.11", login:"admin", password:"admin"});
         obj.push({ip:"192.168.11.12", login:"admin", password:"admin"});
      

      А можно в сценарии каким-нибудь образом брать данные по камерам из плагина?

      Нет, в Cherry такой возможности нет

      И да - у плагина CCTV будет древовидная структура в 5-й версии iH?

      Да, в V5 деревья будут почти везде 🙂

      написал в Сценарии
      I
      intrapro