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



  • @intrapro:

    Почему нет? На сегодня напрямую из расписания можно выполнить только простые и групповые команды on-off-toggle. Все остальное через сценарий.

    Да как-то сложно это - ради переключения switch в нужное положение надо делать 3-5 сценариев, а потом еще кучу заданий по расписанию.

    Ок, в Berry у меня в расписании было 2 записи - в 7.00 включить "День", если был включен "Ночь" и в 17.00 включить "Ночь", если был включен "День". Сделано было для того, что если вручную включен "Эконом", то по расписанию День/Ночь не включать. Как теперь это сделать, предложите варианты?!
    @intrapro:

    Все ведь можно сделать через сценарии, немножно громоздко, но универсально 🙂

    Если честно, то я уже путаюсь в своих сценариях… ранее в предложения писал, что нужно разделение сценариев по системам, например. Как в устройствах - выбрал нужную систему и отобразились устройство только этой системы. И да, нужен поиск устройств - иногда надо найти быстренько, подправить что-нибудь, но не тут-то было если устройств далеко за 200 шт.
    @intrapro:

    Здесь это обычная таблица PM, сортировать можно по любому столбцу 🙂

    Да я понимаю, хочется чтобы зашел и сразу понял что в какой очередности включится. Может я сильно привык к Berry, но там это было удобно!

    PS: прокомментируйте, пожалуйста, в этой ветке еще один мой пост за вчерашний день.



  • Пробую сделать сценарий переключения режимов работы отопления. Хочу делать запись в пользовательский журнал типа "Режим отопления - День", но как мне получить "Название состояния" переключателя (в данном случае - День)?

    И еще - как правильно сравнивать с нулем: this.sumWorkPumps() === 0 или так this.sumWorkPumps() == 0. Во втором случае система ругается на синтаксис.



  • @Alex_Jet:

    Пробую сделать сценарий переключения режимов работы отопления. Хочу делать запись в пользовательский журнал типа "Режим отопления - День", но как мне получить "Название состояния" переключателя (в данном случае - День)?

    this.log(`Режим отопления - ${device.stateName}`) 
    
    

    где device.stateName - название состояния

    Описание возможностей нового API см https://ih-systems.com/ru/command_list/

    @Alex_Jet:

    И еще - как правильно сравнивать с нулем: this.sumWorkPumps() === 0 или так this.sumWorkPumps() == 0. Во втором случае система ругается на синтаксис.

    Ну уж не ругается, просто серый треугольничек показывает: "Use === to compare with 0"

    Потому что x == 0 будет истинно при x=0, x=false, x='', а x===0 - только при x=0.

    Можете использовать любой вариант, нестрогое равенство (==) позволяет не заморачиваться с соответствием типа данных.



  • @Alex_Jet:

    Ок, в Berry у меня в расписании было 2 записи - в 7.00 включить "День", если был включен "Ночь" и в 17.00 включить "Ночь", если был включен "День". Сделано было для того, что если вручную включен "Эконом", то по расписанию День/Ночь не включать. Как теперь это сделать, предложите варианты?!

    Cделать 2 сценария, условие (если НЕ "Эконом") включить в сценарий

    Настройка условия в расписании вызывала вопросы:

    1, Почему не срабатывает? Ответ: потому что есть if

    2. Мне надо условия объединить по или, а не по и

    и т д

    @Alex_Jet:

    Если честно, то я уже путаюсь в своих сценариях… ранее в предложения писал, что нужно разделение сценариев по системам, например. Как в устройствах - выбрал нужную систему и отобразились устройство только этой системы. И да, нужен поиск устройств - иногда надо найти быстренько, подправить что-нибудь, но не тут-то было если устройств далеко за 200 шт.

    Да, группировку сценариев добавим в ближайшее время.

    По поиску устройств в таблице- пока не придумали



  • @Alex_Jet:

    Коллеги, а подскажите почему из "Сценарии" нельзя заблокировать мультисценарий? Иначе приходиться блокировать все, например, 14 шт. вручную из "Рабочие сценарии". Сегодня столкнулся с тем, что сценарии, которые принудительно заблокировал самопроизвольно восстановились!!! Это не есть гуд…

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

    По поводу сброса блокировки сценариев - проверим, исправим.

    @Alex_Jet:

    А еще можно в "Рабочие сценарии" сделать правильную сортировку по числовому значению ID? Чтобы шло не 2, 20-29, 3, 30-39, а 1,2,3,4 и т.д.

    А зачем вам их сортировать по ID? В этом поле может быть как символьная строка - название простого сценария, так и число для рабочих сценариев мультисценария. Это просто уникальный ID в таблице рабочих сценариев, ни о чем не говорящий. Хотели это поле скрыть, но по нему видно сразу - простой это сценарий или мульти.



  • @intrapro:

    > this.log(`Режим отопления - ${device.stateName}`) 
    > 
    

    где device.stateName - название состояния

    Описание возможностей нового API см https://ih-systems.com/ru/command_list/

    Пардон, не увидел это свойство:(
    @intrapro:

    Потому что x == 0 будет истинно при x=0, x=false, x='', а x===0 - только при x=0.

    Можете использовать любой вариант, нестрогое равенство (==) позволяет не заморачиваться с соответствием типа данных.

    Спасибо за разъяснение. Уже подзабыл js.

    @intrapro:

    А зачем вам их сортировать по ID? В этом поле может быть как символьная строка - название простого сценария, так и число для рабочих сценариев мультисценария. Это просто уникальный ID в таблице рабочих сценариев, ни о чем не говорящий. Хотели это поле скрыть, но по нему видно сразу - простой это сценарий или мульти.

    Только сейчас понял, что ID в мультисценарии - это просто ID и диапазон ID непрерывный у одного мультисценария только если все наборы добавлены последовательно в одно время. В общем смысла сортировать нет.

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

    Пытался сделать нужные задачи в расписании… в Berry компоновать включить/выключить/переключить в одной задаче было очень удобно! А тут надо делать дополнительные задачи 😞 мне кажется, что это не удачный вариант!

    И самое главное - очень тяжело отследить что в итоге включаю, что выключаю. LAMP1_03, LAMP1_08 мне мало о чем говорит 😞 Надо добавить название устройства.



  • @Alex_Jet:

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

    Пропадают_строки_Наборов_устройств.png

    Для исправления ошибки выпущена версия 4.4.10.



  • Вопрос по расписанию. Есть два варианта "Включить" и "Включить с сохранением авто". Когда я щелкую вручную по актюатору и вместо А появляются часики - это что за действие? - "Включить" или "Включить с сохранением авто"? У меня задача - в зависимости от заката солнца принудительно включить насос, который работает в АВТО режиме (после ручного включения АВТО восстанавливается спустя 2 часа).



  • @Alex_Jet:

    Вопрос по расписанию. Есть два варианта "Включить" и "Включить с сохранением авто". Когда я щелкую вручную по актюатору и вместо А появляются часики - это что за действие? - "Включить" или "Включить с сохранением авто"? У меня задача - в зависимости от заката солнца принудительно включить насос, который работает в АВТО режиме (после ручного включения АВТО восстанавливается спустя 2 часа).

    Если появляются часики - значит АВТО сброшен, но будет восстановлен через x интервал

    Это происходит при выполнении команд Включить-Выключить

    Команда "Включить с сохранением авто" АВТО не сбрасывает и часики не появляются



  • @intrapro:

    Если появляются часики - значит АВТО сброшен, но будет восстановлен через x интервал

    Это происходит при выполнении команд Включить-Выключить

    Команда "Включить с сохранением авто" АВТО не сбрасывает и часики не появляются

    Значит, у меня задача в расписании как-то не адекватно отработала. Либо есть какая-то проблема с построением очереди при изменении расписания. В 16.05 (закат минус 1 час) должен был включиться актюатор ТП2, но я за 5 минут до этого изменил время включения на 15.05 (закат минус 2 часа). Однако расписание не сработало, актюатор не включился…, кстати в журнал сработка расписания может записываться?

    Другую задачу я перенес с 15.05 на 16.05 (наоборот) в то же время и она сработала 3 раза (см.скриншот журнала)! Поэтому вопрос - как перестраивается очередь при изменении задач по расписанию?
    Расписание_Изменение.png



  • @Alex_Jet:

    Либо есть какая-то проблема с построением очереди при изменении расписания. В 16.05 (закат минус 1 час) должен был включиться актюатор ТП2, но я за 5 минут до этого изменил время включения на 15.05 (закат минус 2 часа). Однако расписание не сработало, актюатор не включился…, кстати в журнал сработка расписания может записываться?

    Другую задачу я перенес с 15.05 на 16.05 (наоборот) в то же время и она сработала 3 раза (см.скриншот журнала)! Поэтому вопрос - как перестраивается очередь при изменении задач по расписанию?

    Расписание_Изменение.png

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

    По записи в журнал - наверно можно это делать опционально. При доработке функционала журнала учтем.



  • Коллеги! Прошу помощи, что называется нужна "помощь друга". Есть два мультисценария - один привожу тут, у другого - другое название и вместо const act, используется const heat (это отдельная история зачем нужно два одинаковых сценария):

    const act = Device("ActorD", "Актюатор ТП", [
      {"name":"hist", "note":"Гистерезис включения/отключения актюатора, °C", "type":"number", "val":0.15}
      ]);
    
    const dt = Device("SensorA", "Датчик температуры");
    
    const script = {
        ust_min: 0,
        ust_max: 0,
    
        check() {
          //Определение уставок
          this.ust_min = dt.defval - act.hist;
          this.ust_max = dt.defval + act.hist/2;
          //Проверка основных условий
          return act.auto && ( !act.dval&&(dt.aval <= this.ust_min) || act.dval&&(dt.aval >= this.ust_max) );
        },
    
        start() {
          let zone = dt.name.replace("Температура в зоне","Зона");
    
          if(!act.dval) {
            this.do(act, "aon");
            this.log(zone+ " (" +dt.aval+ ") <= Ust (" +this.ust_min+ "), Act = " +act.dval); //((act.dval == 1) ? "On" : "Off")
          }
          else {
            this.do(act, "aoff");
            this.log(zone+ " (" +dt.aval+ ") >= Ust (" +this.ust_max+ "), Act = " +act.dval);
          }
    
          this.log(act.name+ " = " + act.dval);
        }
    };
    
    

    В общем на одном сценарии сейчас (код приведен выше) в тестовом режиме работают актюаторы на коллекторах ТП, на другом в реальном времени работают насосы рециркуляции этих коллекторов, которые управляются теми же самыми датчиками температуры… и у меня от лога (см. в конце скрипта this.log) возникает когнитивный диссонанс...:
    Журнал_Когнитивный_диссонанс.png
    Вот подскажите почему во втором случае при "сработке" датчика температуры Heat = 0 (или Насос ТП1 = 0)??? При этом на мнемосхеме насос включается и если проверить состояние насоса отдельным скриптом:

    const motion = Device("PUMP1"); 
    
    script({
        start() {
            if (motion.isOn()) this.log(motion.name+ " = On");
            if (motion.isOff()) this.log(motion.name+ " = Off");
        } 
    });
    
    ````,
    
    то "Насос ТП1 = On"! Как такое может быть? Что я упускаю?


  • @Alex_Jet:

    Коллеги! Прошу помощи, что называется нужна "помощь друга". Есть два мультисценария - один привожу тут, у другого - другое название и вместо const act, используется const heat (это отдельная история зачем нужно два одинаковых сценария):

    > const act = Device("ActorD", "Актюатор ТП", [
    >   {"name":"hist", "note":"Гистерезис включения/отключения актюатора, °C", "type":"number", "val":0.15}
    >   ]);
    >   
    > const dt = Device("SensorA", "Датчик температуры");
    > 
    > const script = {
    >     ust_min: 0,
    >     ust_max: 0,
    >     
    >     check() {
    >       //Определение уставок
    >       this.ust_min = dt.defval - act.hist;
    >       this.ust_max = dt.defval + act.hist/2;
    >       //Проверка основных условий
    >       return act.auto && ( !act.dval&&(dt.aval <= this.ust_min) || act.dval&&(dt.aval >= this.ust_max) );
    >     },
    >     
    >     start() {
    >       let zone = dt.name.replace("Температура в зоне","Зона");
    >  
    >       if(!act.dval) {
    >         this.do(act, "aon");
    >         this.log(zone+ " (" +dt.aval+ ") <= Ust (" +this.ust_min+ "), Act = " +act.dval); //((act.dval == 1) ? "On" : "Off")
    >       }
    >       else {
    >         this.do(act, "aoff");
    >         this.log(zone+ " (" +dt.aval+ ") >= Ust (" +this.ust_max+ "), Act = " +act.dval);
    >       }
    >       
    >       this.log(act.name+ " = " + act.dval);
    >     }
    > };
    > 
    

    В общем на одном сценарии сейчас (код приведен выше) в тестовом режиме работают актюаторы на коллекторах ТП, на другом в реальном времени работают насосы рециркуляции этих коллекторов, которые управляются теми же самыми датчиками температуры… и у меня от лога (см. в конце скрипта this.log) возникает когнитивный диссонанс...:

    Журнал_Когнитивный_диссонанс.png

    Вот подскажите почему во втором случае при "сработке" датчика температуры Heat = 0 (или Насос ТП1 = 0)??? При этом на мнемосхеме насос включается и если проверить состояние насоса отдельным скриптом:

    > const motion = Device("PUMP1"); 
    > 
    > script({
    >     start() {
    >         if (motion.isOn()) this.log(motion.name+ " = On");
    >         if (motion.isOff()) this.log(motion.name+ " = Off");
    >     } 
    > });
    > 
    ````,
    > 
    > то "Насос ТП1 = On"! Как такое может быть? Что я упускаю?
    
    Нужно учитывать, что после выполнения команды действие не происходит мгновенно, если только это не виртуальное устройство. Сценарий отправляет команду, но состояние переключится только после feedback-а от железа
    
    Поэтому насос в следующей строке после команды просто еще не успел переключиться


  • @intrapro:

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

    Поэтому насос в следующей строке после команды просто еще не успел переключиться

    Все понял. Спасибо! Как раз так и получается - актюаторы не привязаны к каналам контроллеров, а насосы привязаны. А как в таком случае можно узнать состояние насоса? Сделать опрос по таймеру

    или как-то в зависимости от feedback контроллера?



  • @Alex_Jet:

    Все понял. Спасибо! Как раз так и получается - актюаторы не привязаны к каналам контроллеров, а насосы привязаны. А как в таком случае можно узнать состояние насоса? Сделать опрос по таймеру

    или как-то в зависимости от feedback контроллера?

    Можно добавить таймер с каким-то адекватным оборудованию интервалом

    Можно добавить слушателя, который сработает, когда устройство переключится:

       this.addListener(act, ‘onAct’);
        …
    },
    
    onAct() {
       if (this.isChanged(act,’value’)) … // переключилась основное значение (а не авто, например)
           ... // Здесь уже новое состояние
    
    

    Можно и то и другое - например,

    • в onAct при нормальном переключении - сбросить таймер (или завершить сценарий this.exit())

    • по таймеру - если переключения не произошло - сделать что-то еще (повторно включить, отправить сообщение и т д)

    Все зависит от задачи

    Если устанавливаете слушателя - нужно обязательно предусмотреть точку завершения сценария this.exit();



  • Ещё другой вопрос - в новой версии API не предусмотрен "вызов" экрана с нужной мнемосхемой на терминалах, на которых открыт веб-интерфейс системы? Нужно для реализации того же видеодомофона, например, видеоалерта, отображения мнемосхемы системы, в которой произошла авария и т.д.

    Ну и push-вызовы были бы полезны, но это вероятно только для мобильного нативного приложения, которое находится постоянно в работе в фоне. До его доработки, как я понимаю, ещё далеко.



  • @Alex_Jet:

    Ещё другой вопрос - в новой версии API не предусмотрен "вызов" экрана с нужной мнемосхемой на терминалах, на которых открыт веб-интерфейса системы? Нужно для реализации того же видеодомофона, например, видеоалерта, отображения мнемосхемв системы в которой произошла авария и т.д.

    Да, это тема интересная. Видеоалерты мы планируем сделать.

    Переключение экрана по команде из сценария? Здесь есть вопросы…

    Выдавать на все терминалы? Не всегда это нужно в текущий момент. И разграничение доступа опять же.

    Возможно, лучшее решение - всплывающий алерт, а с него уже переход.

    Всплывающие алерты есть у нас в Scada, наверно добавим их и в Pro



  • @intrapro:

    Да, это тема интересная. Видеоалерты мы планируем сделать.

    Переключение экрана по команде из сценария? Здесь есть вопросы… Выдавать на все терминалы?

    Ок, у Вас же по сути на терминале крутится js-клиент, который имеет связь через сокеты с сервером. И вероятно клиентам сервер присваивает какой-то id (не знаю точно поскольку не освоил сокеты), по нему можно определять на каком терминале сейчас веб-страница активна и куда надо отправить данные. В общем я себе концепцию представляю, но поскольку знаний по фреймворкам недостаточно, то не знаю как это реализуется в коде.
    @intrapro:

    Возможно, лучшее решение - всплывающий алерт, а с него уже переход.

    Всплывающие алерты есть у нас в Scada, наверно добавим их и в Pro

    Было бы хорошо попробовать как это работает. А карты тоже по сути для Scads сейчас или что с ними можно делать в Pro?



  • @Alex_Jet:

    Ок, у Вас же по сути на терминале крутится js-клиент, который имеет связь через сокеты с сервером. И вероятно клиентам сервер присваивает какой-то id (не знаю точно поскольку не освоил сокеты), по нему можно определять на каком терминале сейчас веб-страница активна и куда надо отправить данные.

    Да, вы правы, сервер знает о подключенных активных клиентах.

    В этом и вопрос - переключать экран для всех клиентов? Не всегда это хорошо. Хотя для домашнего применения может и можно …

    Команду для всплывающего алерта добавим в API, по срокам не скажу, но будет.

    @Alex_Jet:

    А карты тоже по сути для Scads сейчас или что с ними можно делать в Pro?

    Сейчас на картах возможно размещение устройств и элементов для индикации и последующей навигации (переходов по объектом)

    Если вы про геолокацию, ее нет 🙂



  • @intrapro:

    Да, вы правы, сервер знает о подключенных активных клиентах.

    В этом и вопрос - переключать экран для всех клиентов? Не всегда это хорошо.

    Да согласен, но если сервер знает о подключенных клиентах, то значит можно адресовать "сообщение" конкретному клиенту? Либо всем, если нужно. Но для этого нужен api.
    @intrapro:

    Команду для всплывающего алерта добавим в API, по срокам не скажу, но будет.

    Это хорошо. Интересно как это выглядит - виджет, размещаемый на экране? А алерты формируются из тех же сценариев?
    @intrapro:

    Сейчас на картах возможно размещение устройств и элементов для индикации и последующей навигации (переходов по объектом)

    Если вы про геолокацию, ее нет 🙂

    Про геолокация понятно что это примерно 2020 год:), если не позже. В общем Роскосмос… :lol:

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


Авторизуйтесь, чтобы ответить