Вопросы по работе системы



  • @Alex_Jet, к сожалению, прямой ответ на оба вопроса в данной версии - нет.

    Первая задача, на мой взгляд, решается штатными средствами

    Вариант 1. Если нужно установить ошибку и при этом исключить значение 1023 -
    можно использовать флажки на уровне устройства:

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

    Err_outOfRange.png

    Здесь будет 3 состояния, использовать метод интервалов (не совсем понятно преобразование в функции канала в значения 50, 75, 100. Вероятно, есть какой- то функционал на уровне сценария?) Но если рассматривать поставленную задачу без преобразования, то в состояниях будет так:

    Номер состояния 0 Граница интервала 499
    Номер состояния 1 Граница интервала 999
    Номер состояния 2 Граница интервала - любое значение выше

    Если не принимать 1023, то для 1023 сохраняется предыдущее состояние, но будет ошибка

    Вариант 2. Можно организовать для 1023 отдельное состояние ошибки
    Тогда нужно это значение принимать (при этом можно устанавливать ошибку, одно другому не мешает)
    Номер состояния 0 Граница интервала 499
    Номер состояния 1 Граница интервала 999
    Номер состояния 2 Граница интервала. 1010
    Номер состояния 3 Граница интервала. - Состояние ошибка

    По второй задаче - да, в Berry было, в Cherry делать не стали 😞
    Используя метод чередования, в v5 планируем сделать такой функционал 🙂
    Причем для любого плагина, не только для MegaD



  • Здравствуйте. Как отвязать лицензию pro от одного компьютера и привязать к новому? Просто будет перенос системы для расширения и повышения надежности.



  • @regabriel На сайте в личном кабинете деактивируйте лицензию.
    После этого активируйте ее на новом сервере.



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

    не совсем понятно преобразование в функции канала в значения 50, 75, 100. Вероятно, есть какой- то функционал на уровне сценария?

    Это чтобы сразу на устройстве отображался объем воды в емкости в понятном % соотношении. Соответственно, в сценарии используются эти значения для управления старыми устройствами (датчик нижнего уровня воды и датчик верхнего уровня воды).
    Я понял ваши идеи. Попробую реализовать. В остальном - ждем версии 5.



  • @intrapro, вопрос по "Дельта сохранения" в свойствах БД устройства. Если датчику присваиваются значения 2,88...2,95, то чтобы в БД уменьшить количество записываемых значений, а значит аппроксимировать график, то мне нужно в качестве "Дельта сохранения" указать что-то типа 0,1?



  • @Alex_Jet, да, все верно



  • Здравствуйте. Для работы одного сложного устройства пришлось создать "библиотеку" в 600-1000 строк из объекта с методами.

    Если данное устройство будет использоваться в нескольких сценариях, как лучше организовать работу?

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



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

    Здравствуйте. Для работы одного сложного устройства пришлось создать "библиотеку" в 600-1000 строк из объекта с методами.

    Если данное устройство будет использоваться в нескольких сценариях, как лучше организовать работу?

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

    Добрый день!
    Можно вынести код объекта в отдельный файл в виде модуля

    // File mybigobject.js
    
    module.exports = {
      get() {
         ...
      },...
    
    };
    

    В сценарии делаете require - загрузка модуля:

    ... const myobj = require("путь к файлу/mybigobject");
        const x = myobj.get();
    

    Пропишите абсолютный путь - тогда не будет проблем с дефолтными путями.
    Если этот модуль разместить в node_modules, то путь прописывать не надо.

    Но есть 2 момента:

    • редактировать этот файл нужно будет не через систему - для 1000 строк это точно не минус 🙂
    • если будете менять код, то сервер нужно перезагружать, так как require кэширует модуль. Это тоже плюс для Вас - можете вызывать в разных сценариях, модуль загрузится только однажды


  • Спасибо за развернутые ответы. Но возникают еще вопросы)))

    Выяснилось, что для отправки большого количества запросов с большой скоростью на мегад pluginCommand не справляется.
    (не знаю из-за чего, но скорость по сравнению с file_get_contents в скриптике из php в десятки раз медленнее)
    Из-за чего встает задачка проверки возможности самому отправлять запросы напрямую.

    Как подключать библиотеки express или request ?
    В плагине от меги нашел вариант:

    require("./lib/httpclient");
    

    Правильно ли я понимаю, что подключать нужно через ./lib/ , а список всех доступных модулей можно посмотреть в /opt/intrahouse-c/backend/node_modules ? Или есть тонкости?



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

    Спасибо за развернутые ответы. Но возникают еще вопросы)))

    Выяснилось, что для отправки большого количества запросов с большой скоростью на мегад pluginCommand не справляется.
    (не знаю из-за чего, но скорость по сравнению с file_get_contents в скриптике из php в десятки раз медленнее)
    Из-за чего встает задачка проверки возможности самому отправлять запросы напрямую.

    pluginCommand из сценария - дополнительная возможность отправки команды плагину. Основной ход все же - отправлять запросы через каналы.

    Для ускорения работы плагина MegaD:

    • если есть опрос каналов, можно попробовать его отключить (на уровне каналов и в параметрах плагина - период опроса всех каналов поставить 0)
    • самое главное - для меги есть спец настройка для замедления отправки следующей команды. "Интервал отправки запросов" установлен по умолчанию в 200 мсек, на самом деле это очень много, но были проблемы с зависанием контроллера при частой отправке запросов. Можно сильно уменьшить этот параметр.

    Интересно конечно посмотреть в отладчике плагина, где происходит замедление, но если не меняли параметр Интервал опроса, то отправляется только 5 запросов в секунду. И собственно pluginCommand здесь ни при чем
    Тем не менее, можно попробовать и другие варианты

    В плагине от меги нашел вариант:

    require("./lib/httpclient");
    

    Правильно ли я понимаю, что подключать нужно через ./lib/ , а список всех доступных модулей можно посмотреть в /opt/intrahouse-c/backend/node_modules ? Или есть тонкости?

    Нет, все что в /opt/intrahouse-c/backend/node_modules, делаете require без путей.
    Приведенный пример - это http клиент внутри плагина megad, не из node_modules, а из файла /var/lib/intrahouse-c/plugins/megad/lib/httpclient.js

    Как подключать библиотеки express или request ?

    Для запросов к MegaD ни request, ни тем более express не нужен, нужен простой http клиент (get запросы без затей). Встроенный в nodejs модуль http покроет
    с избытком:

    require('http').get('http://192.168.11.22/sec/?.....')
    

    Примеры использования есть на примере сниппетов:

    https://forum.ih-systems.com/topic/139/сниппеты/3?_=1594984596289

    В зависимости от вашей задачи есть варианты:

    • использовать require('http') из сценария или сниппета (здесь есть накладные расходы на запуск - останов сценария; если запросов ооочень много, то может пострадать общая производительность системы, так как сценарии работают в основном процессе)
    • использовать http плагин (который кстати использует request, так как поддерживает post запросы и др фишки). Плагины запускаются как дочерние процессы.
    • если там действительно много запросов и скорость не устраивает, написать свой плагин с оптимизацией под конкретную задачу.


  • Ошибочка:
    На мнемосхеме:
    Добавляем устройство -> текстовое представление
    Элемент -> выравнивание по горизонтали и по вертикали не работает. Всегда текст остается в центре.



  • Коллеги, все же я хочу реализовать "виджет", показывающий остаток количества куб.м воды, которые еще могут протечь через фильтр тонкой очистки. Итак, есть счетчик объема холодной воды, есть "виджет" в виде аналогового датчика, который будет изображать из себя "Счетчик остатка ресурса фильтра". У него будет в качестве уставки - значение ресурса фильтра в куб.м, а также дополнительные параметры - "replacement" - чтобы наступал момент информирования пользователя о замене фильтра, а также "reset" - для сброса показаний счетчика ресурса фильтров к первоначальному виду после замены элемента фильтра. Получился примерно следующий сценарий, однако он не до конца работает...

    const meter = Device("Meter","Счетчик расхода");
    const life_meter = Device("SensorA","Счетчик ресурса фильтра", [
      {"name":"replacement", "note":"Остаточный объем для индикации замены фильтра, м³", "type":"number", "val":1},
      {"name":"reset", "note":"Флаг сброса счетчика ресурса фильтра", "type":"cb", "val":0}
      ]);
    
    startOnChange([meter,life_meter]); 
    
    script({
      value: 0,
      weight_meter: 0.01,
      
      start() {
        
        //Изменения из меню счетчика ресурса фильтра
        if(this.isChanged(life_meter, "reset")) {
          this.value = 0;
          this.assign(life_meter, "value", life_meter.setpoint);
          this.assign(life_meter, "reset", 0);
        }
        if(this.isChanged(life_meter, "setpoint")) {
          this.value = 0;
          this.assign(life_meter, "value", life_meter.setpoint);
        }
        
        //Изменения значения счетчика расхода
        if(this.isChanged(meter, "value")) {
          this.log("> Значение счетчика = " +meter.value);
          
          if(life_meter.value == life_meter.setpoint) {
            this.log("> life_meter.value == life_meter.setpoint");
            
            this.value = life_meter.setpoint - this.weight_meter;
          }
          else {
            this.value = this.value - this.weight_meter;
          }
          this.log("> this.value = " +this.value);
          
          this.assign(life_meter, "value", this.value);
        }
        
        //Индикация для замены фильтра
        if(life_meter.value < life_meter.getParam("replacement")) {
          this.assign(life_meter, "error", 1);
        }
        else if(life_meter.error) {
          this.assign(life_meter, "error", 0);
        }
      } 
    });
    

    Однако при изменениях со стороны meter почему-то система "не видит" условия if(this.isChanged(meter, "value")). Лог сценария при этом такой:

    20.07 23:27:34.067 S152(,METER1_02,METER1_03) Trigger METER1_02
    20.07 23:27:34.067 S152(,METER1_02,METER1_03) Started
    20.07 23:27:34.068 S152(,METER1_02,METER1_03) isChanged(METER1_03,reset)=false Changed: {"METER1_02":{"aval":14.73}}
    20.07 23:27:34.069 S152(,METER1_02,METER1_03) isChanged(METER1_03,defval)=false Changed: {"METER1_02":{"aval":14.73}}
    20.07 23:27:34.069 S152(,METER1_02,METER1_03) isChanged(METER1_02,dval)=false Changed: {"METER1_02":{"aval":14.73}}
    20.07 23:27:34.069 S152(,METER1_02,METER1_03) Stopped
    

    Подскажите что не так?



  • @Alex_Jet, похоже, Вы нашли баг с использованием счетчика в сценарии версии v4. А именно - value для счетчика - это aval, а не dval 😞

    Попробуйте использовать для счетчика "aval" вместо "value", т е
    сделать такую замену:

     if(this.isChanged(meter, "value"))  ==>  if(this.isChanged(meter, "aval")) 
    
    this.log("> Значение счетчика = " +meter.value); ==> this.log("> Значение счетчика = " +meter.getParam("aval")); 
    
    


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

    @Alex_Jet, похоже, Вы нашли баг с использованием счетчика в сценарии версии v4. А именно - value для счетчика - это aval, а не dval 😞

    Попробуйте использовать для счетчика "aval" вместо "value", т е
    сделать такую замену:

     if(this.isChanged(meter, "value"))  ==>  if(this.isChanged(meter, "aval")) 
    
    this.log("> Значение счетчика = " +meter.value); ==> this.log("> Значение счетчика = " +meter.getParam("aval")); 
    
    

    Самое интересное, что если я комментирую условие if(this.isChanged(meter, "value")) и пробую вручную запускать сценарий, то все нормально считает:

    21.07 02:17:11.873 S152(,METER1_02,METER1_03) Started
    21.07 02:17:11.874 S152(,METER1_02,METER1_03) isChanged(METER1_03,reset)=false
    21.07 02:17:11.875 S152(,METER1_02,METER1_03) isChanged(METER1_03,defval)=false
    21.07 02:17:11.875 S152(,METER1_02,METER1_03) log: > Значение счетчика = 14.73
    21.07 02:17:11.922 S152(,METER1_02,METER1_03) log: > this.value = -0.01
    21.07 02:17:11.929 S152(,METER1_02,METER1_03) assign METER1_03.value=-0.01
    21.07 02:17:11.929 S152(,METER1_02,METER1_03) assign METER1_03.error=1
    21.07 02:17:11.930 S152(,METER1_02,METER1_03) Stopped
    

    В принципе при замене "value" на "aval" все работает, как задумано:

    21.07 09:38:11.875 S152(,METER1_02,METER1_03) Trigger METER1_02
    21.07 09:38:11.876 S152(,METER1_02,METER1_03) Started
    21.07 09:38:11.876 S152(,METER1_02,METER1_03) isChanged(METER1_03,reset)=false Changed: {"METER1_02":{"aval":14.74}}
    21.07 09:38:11.877 S152(,METER1_02,METER1_03) isChanged(METER1_03,defval)=false Changed: {"METER1_02":{"aval":14.74}}
    21.07 09:38:11.877 S152(,METER1_02,METER1_03) isChanged(METER1_02,aval)=true Changed: {"METER1_02":{"aval":14.74}}
    21.07 09:38:11.878 S152(,METER1_02,METER1_03) log: > Значение счетчика = 14.74
    21.07 09:38:11.924 S152(,METER1_02,METER1_03) log: > life_meter.value == life_meter.setpoint
    21.07 09:38:11.928 S152(,METER1_02,METER1_03) log: > this.value = 4.99
    21.07 09:38:11.931 S152(,METER1_02,METER1_03) assign METER1_03.value=4.99
    21.07 09:38:11.933 S152(,METER1_02,METER1_03) Stopped
    21.07 09:40:33.108 S152(,METER1_02,METER1_03) Trigger METER1_02
    21.07 09:40:33.109 S152(,METER1_02,METER1_03) Started
    21.07 09:40:33.109 S152(,METER1_02,METER1_03) isChanged(METER1_03,reset)=false Changed: {"METER1_02":{"aval":14.75}}
    21.07 09:40:33.110 S152(,METER1_02,METER1_03) isChanged(METER1_03,defval)=false Changed: {"METER1_02":{"aval":14.75}}
    21.07 09:40:33.110 S152(,METER1_02,METER1_03) isChanged(METER1_02,aval)=true Changed: {"METER1_02":{"aval":14.75}}
    21.07 09:40:33.113 S152(,METER1_02,METER1_03) log: > Значение счетчика = 14.75
    21.07 09:40:33.159 S152(,METER1_02,METER1_03) log: > this.value = 4.98
    21.07 09:40:33.163 S152(,METER1_02,METER1_03) assign METER1_03.value=4.98
    21.07 09:40:33.164 S152(,METER1_02,METER1_03) Stopped
    21.07 09:40:50.176 S152(,METER1_02,METER1_03) Trigger METER1_02
    21.07 09:40:50.177 S152(,METER1_02,METER1_03) Started
    21.07 09:40:50.177 S152(,METER1_02,METER1_03) isChanged(METER1_03,reset)=false Changed: {"METER1_02":{"aval":14.76}}
    21.07 09:40:50.178 S152(,METER1_02,METER1_03) isChanged(METER1_03,defval)=false Changed: {"METER1_02":{"aval":14.76}}
    21.07 09:40:50.178 S152(,METER1_02,METER1_03) isChanged(METER1_02,aval)=true Changed: {"METER1_02":{"aval":14.76}}
    21.07 09:40:50.178 S152(,METER1_02,METER1_03) log: > Значение счетчика = 14.76
    21.07 09:40:50.189 S152(,METER1_02,METER1_03) log: > this.value = 4.970000000000001
    21.07 09:40:50.194 S152(,METER1_02,METER1_03) assign METER1_03.value=4.970000000000001
    21.07 09:40:50.195 S152(,METER1_02,METER1_03) Stopped
    

    Вопрос - почему на третьем шаге получаю столь длинную цифру???



  • На экране добавляю навигатор, пишет что нету таких мнемосхем.
    alt text



  • Не могу найти в чем проблема. Для аналогового датчика давления настроил 3 состояния - низкое (верхний предел - 1), среднее (верхний предел - 3) и высокое (верхний предел - 10) давление. Соответственно для каждого состояния на мнемосхеме задал фон индикатора - желтый/зеленый/красный. Однако при показаниях в районе 2,6-2,9 фон почему-то желтый, а должен быть зеленым!
    Проблема_с_отображением_состояния.png

    Еще вопрос - почему у датчика аналогового нельзя удалить не нужные состояния? Система пишет "Эту запись удалить нельзя"? Было 3 состояния, перестал их использовать, 2 по счету удалил, а ни 1, ни 0 удалить нельзя.



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

    Не могу найти в чем проблема. Для аналогового датчика давления настроил 3 состояния - низкое (верхний предел - 1), среднее (верхний предел - 3) и высокое (верхний предел - 10) давление. Соответственно для каждого состояния на мнемосхеме задал фон индикатора - желтый/зеленый/красный. Однако при показаниях в районе 2,6-2,9 фон почему-то желтый, а должен быть зеленым!
    Проблема_с_отображением_состояния.png

    Еще вопрос - почему у датчика аналогового нельзя удалить не нужные состояния? Система пишет "Эту запись удалить нельзя"? Было 3 состояния, перестал их использовать, 2 по счету удалил, а ни 1, ни 0 удалить нельзя.

    В "состояниях" задан цвет картинки.
    А на виджете вы картинку не используете, у вас там цвет заливки круга. Он в свойствах объекта на виджете задается, там тоже нужно для каждого из 3-х состояний цвета назначить.



  • @Erik, это все учтено. Я же пишу - что "на мнемосхеме задал фон индикатора - желтый/зеленый/красный".
    Кстати, я бы из состояний вообще убрал значения для изображений и их цветов. Поскольку это все дублируется в состояниях устройства на мнемосхеме. И вообще такое ощущение что описания на мнемосхеме и состояния устройств хранятся в отдельных файлах, при этом приоритет у мнемосхем!



  • В состояниях - только цвет изображения.
    Цвет фона - только в свойствах объекта на мнемосхеме/виджете. Ничего не дублируется.
    Можно в свойствах объекта на мнемосхеме изменить картинку и ее цвет, если это нужно. И приоритет для этого правильный. Ничего убирать не надо.



  • @Erik. Зачем в состояниях нужно изображение и его цвет если все это задается "в свойствах объекта на мнемосхеме"? Причем если эти параметры менять на мнемосхеме, то в состояниях остается все неизменным. Поэтому и я говорю о приоритете свойств мнемосхемы над свойствами состояний:
    Пояснение.png


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