Плагин MegaD



  • @sergeyygr Если нужно два запроса передавать с интервалом 100 мсек, лучше сделать сниппет прямо на устройстве:

    module.exports = callback => {
      const http = require('http');
    
      http.get('http://192.168.1.151/sec/?uart_tx=010400030002&mode=rs485');
      setTimeout(nextReq, 100); // 100 ms
    
      function nextReq() {
        http.get('http://192.168.1.151/sec/?uart_rx=1&mode=rs485', res => {
    
          let rawData = '';
          res.on('data', chunk => {
            rawData += chunk;
          });
    
          res.on('end', () => {
            const data = rawData;
            if (data.includes('CRC Error')) {
              callback('CRC Error'); // Контроллер вернул ошибку CRC
              return;
            }
    
            // 01|03|02|08|a1 - в таком виде ожидается ответ
             const arr = data.split("|");
            if (arr && arr.length > 4) {
              const val = parseInt(arr[3]+arr[4], 16);
              callback(null, val/10000);  
            } else {
              callback('Не удалось извлечь значение из строки: '+ data); // Данные получены, но парсинг неудачен
            }
          });
        });
      }
    };
    
    

    Период опроса (запуска сниппета) настраивается также на устройстве



  • Можно конечно и сценарий использовать

    const power = Device("SensorA", "Power"); 
    script({
      start() {
        this.pluginCommand({unit:'megad1', command:{url:'/sec/?uart_tx=010400030002&mode=rs485'}});
    
        // Следующий запрос через 100 мсек
        this.startTimer('T1', 0.1, 'getNext');
        // Взвести таймер на случай, если ответа от контроллера нет
        this.startTimer('T2', 2, 'onTimeout');
      },
    
      getNext() {
        // Передать запрос на megad1, ответ без обработки придет в сценарий (onResponse:'raw')
        this.pluginCommand({unit:'megad1', command:{url:'/sec/?pt=7&cmd=get', onResponse:'raw'}}, 'getResponse');
      },
    
      getResponse(body) {
        this.log('getResponse body= '+body);
       
        if (body.includes('CRC Error')) {
          this.log('CRC Error'); // Контроллер вернул ошибку CRC
          this.exit();
        }
    
        // 01|03|02|08|a1 - в таком виде ожидается ответ
        const arr = body.split("|");
        if (arr && arr.length > 4) {
          const val = parseInt(arr[3]+arr[4], 16);
          this.assign(power,"value",val/10000 );
        } else {
          this.log('Не удалось извлечь значение из строки: '+ body); // Данные получены, но парсинг неудачен
        }
      
        this.exit();
     },
    
      onTimeout() {
        this.log('Истек таймаут, ответ от megad не получен');
        this.exit();
      }
    });
    


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

    Спасибо, получилось!
    Однако не получается считывать несколько показаний.
    Счетчик выдает несколько параметров, а именно:
    http://192.168.1.151/sec/?uart_tx=010400000001&mode=rs485
    http://192.168.1.151/sec/?uart_rx=1&mode=rs485 /Напряжение
    http://192.168.1.151/sec/?uart_tx=010400030002&mode=rs485
    http://192.168.1.151/sec/?uart_rx=1&mode=rs485 /Мощность
    http://192.168.1.151/sec/?uart_tx=010400050002&mode=rs485
    http://192.168.1.151/sec/?uart_rx=1&mode=rs485 /Накопленная электроэнергия (кВт/час)
    http://192.168.1.151/sec/?uart_tx=010400070001&mode=rs485
    http://192.168.1.151/sec/?uart_rx=1&mode=rs485 /Частота сети
    http://192.168.1.151/sec/?uart_tx=010400080001&mode=rs485
    http://192.168.1.151/sec/?uart_rx=1&mode=rs485 /Коэффициент мощности
    http://192.168.1.151/sec/?uart_tx=010400010002&mode=rs485
    http://192.168.1.151/sec/?uart_rx=1&mode=rs485 /Сила тока
    И в связи стем, что запрос на вывод показаний для всех переключений на параметр один и тот-же происходит конфликт, показания замирают. Как быть?
    Использую инструкции отсюда: https://ab-log.ru/smart-house/ethernet/megad-rs485

    Можно сценарий сделать. Который будет запущен на старте сервера и будет последовательно опрашивать с каким-то интервалом.
    Примерно так, но надо тестировать

    
    // Здесь все датчики - для примера два первых:
    const voltage = Device("SensorA", "Voltage"); 
    const power = Device("SensorA", "Power"); 
    
    script({
      boot() {  
        return true; // Сценарий будет запускаться на старте и всегда будет активным
      },
    
      step:0,  
    
      start() {
        this.step = 1;
        this.getTx();
      },
    
      getTx() {
       let url;
       switch (this.step) {
         case 1: // Напряжение - voltage
          url = '/sec/?uart_tx=010400000001&mode=rs485';
          break;
    
         case 2: // Мощность - power
          url = '/sec/?uart_tx=010400030002&mode=rs485';
          break;
          // ...  
       }
    
       // Отправить запрос на контроллер
       this.pluginCommand({unit:'megad1', command:{url}});
    
       // запрос Rx через 100 мсек 
       this.startTimer('T1', 0.1, 'getRx');
    
       // Запрос следующего параметра через 1 сек
       this.startTimer('T2', 1, 'nextParam');
      },
    
      getRx() {
        // Передать запрос на megad1, ответ придет в сценарий (onResponse:'raw')
       // БЫЛО С ОПЕЧАТКОЙ   this.pluginCommand({unit:'megad1', command:{url:'/sec/uart_rx=1&mode=rs485', onResponse:'raw'}}, 'getResponse');
       this.pluginCommand({unit:'megad1', command:{url:'/sec/?uart_rx=1&mode=rs485', onResponse:'raw'}}, 'getResponse');
      },
    
      getResponse(body) {
        // body 
        // this.log('getResponse body= '+body+' step='+this.step);
       
        if (body.includes('CRC Error')) {
          this.log('CRC Error'); // Контроллер вернул ошибку CRC - здесь нужно что-то решать, пока просто выход
          this.exit();
        }
    
        // 01|03|02|08|a1 - в таком виде ожидается ответ
        const arr = body.split("|");
        if (arr && arr.length > 4) {
          this.assignValue(arr);  
        } else {
          this.log('Не удалось извлечь значение из строки: '+ body); // Данные получены, но парсинг неудачен
          this.exit();
        }
      },
    
      assignValue(arr) {
        const val = parseInt(arr[3]+arr[4], 16); // Если парсинг разный - перенести в case 
        switch (this.step) {
          case 1: 
            this.assign(voltage,"value", val );
            return;
          case 2: 
            this.assign(power,"value", val/10000 );
            return;
          // ...
        }
      },
    
      nextParam() {
       this.step = this.step < 7 ? this.step+1 : 1;
       this.getTx();
      }
    });
    
    

    UPD: В сценарии была опечатка! Был пропущен знак вопроса. Сейчас он скорректирован и полностью рабочий. После поиска ошибки в этом топике также разбирается, как ввести сдвиг значения для соответствия реальному счетчику



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

    Не работает. В отладчике "37 Now is NOT active."

    Нужно посмотреть, нет ли ошибки в таблице Рабочие сценарии.
    Если нет - смотреть отладчик при запуске.

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

    • запуск для устройств убрать

    • прописать ваши названия устройств вместо SensorA:

      const voltage = Device("VOLT1", "Voltage");
      const power = Device("POWER1", "Power");

    • сохранить, обновить таблицу - теперь это обычный сценарий

    • Запустить отладчик для сценария. Окно пока будет пустое

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

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



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



  • @sergeyygr, посмотрите, в Рабочих сценариях для этого сценария есть что-то в графах: Число запусков, Последний запуск, Последний останов

    WorkScene.png



  • @sergeyygr а останова нет? То есть сценарий уже работает в цикле. Можно раскомментировать эту строку и смотреть в журнале

    this.log('getResponse body= '+body+' step='+this.step);
    

    Можно еще в getTx добавить логирование

    this.log('getTx step='+this.step);
    

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



  • @aleks-zonov, при сработке датчика движения MegaD отправляет на сервер http-сообщения. Именно их нужно ловить на сервере. Для этого в плагине нужно прописать "Расширения" (в выпадающем списке перейдите на "Расширения" и добавьте 2 штуки для замыкания и размыкания датчика движения). Примеры для кнопок в режиме click посмотрите - тут



  • @sergeyygr, появились сообщения в журнале?

    Интересно, остальные рабочие сценарии отладчик тоже не видит(. Глюк системы?

    Да, бывает, что отладчик в Рабочих сценариях не ловит сообщения.
    Отладчик лучше использовать в основном разделе Сценарии, а в Рабочих смотреть статистику в таблице - запуск/останов/ошибка



  • Now is NOT active - означает, что в данный момент сценарий в спячке, т е ожидает сработки триггера.

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

    20.08 19:12:29.028 Started
    20.08 19:12:29.029 plugincCommand { unit: 'megad1',
      command: { url: '/sec/?uart_tx=010400000001&mode=rs485' } }
    20.08 19:12:29.030 Error: { message: 'Plugin megad1 is not running!' }
    20.08 19:12:29.030 start timer T1 for 0.1 sek
    20.08 19:12:29.031 start timer T2 for 2 sek
    20.08 19:12:29.176 Done timer T1
    20.08 19:12:29.176 exec function getRx
    20.08 19:12:29.177 plugincCommand { unit: 'megad1',
      command: { url: '/sec/uart_rx=1&mode=rs485', onResponse: 'raw' } }
    20.08 19:12:29.178 Error: { message: 'Plugin megad1 is not running!' }
    20.08 19:12:29.178 exec function getResponse
    20.08 19:12:29.179 Stopped
    


  • @sergeyygr сегодня не получится 😞
    Попробуйте удалить этот сценарий полностью и перезагрузить сервер. Отладчик для других сценариев должен работать



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

    Запускаю отладчик, перехожу на вкладку Рабочие сценарии, запускаю сценарий, возвращаюсь, а там отладчик остановлен.

    Нужно открыть две разные вкладки браузера



  • @sergeyygr Добрый день.
    Сегодня сделали эмуляцию ответов от megad на запросы
    '/sec/?uart_tx=010400000001&mode=rs485' (так как у нас такого железа нет)

    Скопировали Ваш сценарий, вот что видим в отладчике:

    21.08 11:29:14.662 exec function nextParam
    21.08 11:29:14.663 plugincCommand { unit: 'megad1',
      command: { url: '/sec/?uart_tx=010400000001&mode=rs485' } }
    21.08 11:29:14.663 start timer T1 for 0.1 sek
    21.08 11:29:14.664 start timer T2 for 1 sek
    21.08 11:29:14.764 Done timer T1
    21.08 11:29:14.765 exec function getRx
    21.08 11:29:14.766 plugincCommand { unit: 'megad1',
      command: { url: '/sec/uart_rx=1&mode=rs485', onResponse: 'raw' } }
    21.08 11:29:15.139 exec function getResponse
    21.08 11:29:15.139 assign PZEM_Volt.value=223.5
    21.08 11:29:15.672 Done timer T2
    21.08 11:29:15.673 exec function nextParam
    21.08 11:29:15.673 plugincCommand { unit: 'megad1',
      command: { url: '/sec/?uart_tx=010400030002&mode=rs485' } }
    21.08 11:29:15.674 start timer T1 for 0.1 sek
    21.08 11:29:15.674 start timer T2 for 1 sek
    21.08 11:29:15.774 Done timer T1
    21.08 11:29:15.775 exec function getRx
    21.08 11:29:15.776 plugincCommand { unit: 'megad1',
      command: { url: '/sec/uart_rx=1&mode=rs485', onResponse: 'raw' } }
    21.08 11:29:15.943 exec function getResponse
    21.08 11:29:15.943 assign PZEM_Watt.value=2.237
    

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

    Если останется необходимость, можно подключиться удаленно.



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

    Привязка к конкретному каналу MegaD нет. Присутствует лишь стандартная строка запроса, но период опроса стоит «0». Может строку запроса удалить и оставить поле пустым?

    Имеется в виду для плагина в целом? Опрос состояния всех устройств? Нет, это не должно никак влиять. У Вас другие входы-выходы работают с этим контроллером? Можно посмотреть отладчик плагина - там должны быть запросы от сценария.
    Возможно, для тестирования время нужно увеличить - вместо 1 сек 5 сек

    В устройствах «Метод получения значения» стоит «Вычисляется сценарием».

    Это не важно, можно оставить Стандарт



  • @sergeyygr, знака вопроса не хватало! Бывает, глаз замылился. А наш эмулятор проглотил 😞 Здорово, что получилось!
    В сценарии есть еще глючок - нужно считать только до 6

    nextParam() {
    this.step = this.step < 6 ? this.step+1 : 1;  // было this.step < 7 
    this.getTx();
    }
    

    А интервал 1 сек нормально отрабатывает?



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

    Спасибо большое!

    Да не за что. Извините за опечатку

    А можно в моем случае как-то корректировать значение кВт/час?

    Что имеете в виду?



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

    Сейчас показания 3кВт/час, а надо установить 31кВт/час. Что бы показания совпадали со счетчиком на вводе.

    Можно просто добавить смещение в сценарии

    case 5:
    this.assign(kWh,"value", 28 + val/10 );
    return;
    

    Более универсально - добавить свойство устройству и редактировать его через интерфейс (правое меню устройства)

    const kWh = Device("PZEM_kWh", "Мощность накопленная ", [
      {"name":"offset", "note":"Базовое значение мощности", "type":"number", "val":28} ]);
    
    ...
    case 5:
    this.assign(kWh,"value", kWh.getParam("offset") + val/10 );
    
    


  • Подскажите как перевести показания АЦП порта меги в реальные показания, в плагине есть графа формула расчета но что то мне подсказывает что это не то.



  • Это сообщение удалено!


  • Подскажите как применить формулу для расчета показаний АЦП меги вот формула (840-х/840-410)*100=у где х-показания АЦП а y-в данном случае влажность в % ?


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