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



  • Здравствуйте. Для работы одного сложного устройства пришлось создать "библиотеку" в 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



  • Мне пригодилось.
    Я делал интерфейсы как для ПК так и для телефона. И в разных цветовых решениях нужны разные цвета фона/картинок. Устройство одно, а "стилей отображения" несколько. Хорошо, что это возможно.
    А когда добавляешь устройство на мнемосхему, цвета иконки подтягиваются из состояний. Но их можно изменить. Т.е. иконка по умолчанию имеет цвета из состояний устройства. А если менять - изменения коснутся только этого конкретного отображения на этой мнемосхеме. Удобно по моему.



  • @Erik, да, оказывается - это цвета и иконки "по умолчанию" в мобильном нативном приложении. Я им практически не пользуюсь - нарисовал веб-интерфейс для смартфона. Не хватает в системе комментариев для чего это море возможностей нужно)



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

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

    Отвечу сам, хотя подсказал уважаемый @intrahouse, - для того чтобы состояния устройства менялись в зависимости от его показаний нужно в свойствах устройства (вкладка "Дополнительно") выбрать "Аналоговое значение - интервалы". Вот про это я как раз и забыл...



  • Всем доброго времени суток! Сменил роутер, для работы с БП. Настройки все сменились, IP там... Сервак перестал работать, т.к. смена IP. Как сменить настройки сервера, чтобы всё снова заработало. В прошлый раз пришлось удалить программу и установить заново. Система Lubuntu.



  • @Sergeus Таким устройствам нужно давать статические адреса на самом роутере



  • This post is deleted!

Log in to reply