В связи с выходом крупного обновления 5.9.х, приглашаем вас принять участие в вебинаре 09.06.2022 в 15:00. Участвовать

Зависание скриптов



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

    Мульти скрипт выполняется раз в минуту. При этом некоторые из них могут зависнуть, а некоторые еще не зависали никогда. Раз в день есть вероятность, что один-два скрипта зависнут.

    Как найти причину такого поведения?
    На картинке видно, что два скрипта зависло
    alt text

    Скрипт:

    /** 
    * @name Опрос и считывание показаний по CNT меги 
    * @desc  
    * @version 4 
    */
    const count_mega = Device("SensorA","Предыдущее CNT меги"); 
    const count = Device("Meter","Счетчик"); 
    
    script({
        start() {
          // Связывание устройств с плагинами
          let name_plugin ='';
          let port_plugin = '';
          let pass_plugin = 'gos';
          
          switch (count_mega.id){
            case 'number_223_cnt_mega_electro':
              name_plugin = 'megad3';
              port_plugin = '0';
              break;
            case 'number_223_cnt_mega_waterCold':
              name_plugin = 'megad4';
              port_plugin = '0';
              break;
            case 'number_223_cnt_mega_waterHot':
              name_plugin = 'megad4';
              port_plugin = '1';
              break;
            case 'number_222_cnt_mega_waterCold':
              name_plugin = 'megad4';
              port_plugin = '2';
              break;
            case 'number_222_cnt_mega_waterHot':
              name_plugin = 'megad4';
              port_plugin = '3';
              break; 
            case 'number_221_cnt_mega_waterCold':
              name_plugin = 'megad4';
              port_plugin = '4';
              break;
            case 'number_221_cnt_mega_waterHot':
              name_plugin = 'megad4';
              port_plugin = '5';
              break;
              case 'stolovaya_cnt_mega_waterCold':
              name_plugin = 'megad2';
              port_plugin = '4';
              break;
            case 'stolovya_cnt_mega_waterHot':
              name_plugin = 'megad2';
              port_plugin = '5';
              break;
            default:
              this.log('не найден счетчик по id в скрипте '+count_mega.id);
              this.exit();
              break;
          }
            //this.pluginCommand({unit:'megad3', command:'/gos/?pt=0&cmd=get'}, 'onGetResponse');
             this.pluginCommand({unit: name_plugin + '', command:{url:'/'+pass_plugin +'/?pt='+port_plugin + '&cmd=get', onResponse:'raw'}},'onGetResponse');
            
      },
    
      onGetResponse(body) {
    //дальше уже обработаем ответ
            let cnt = 0;
            let weightImpulse = 1;
            let inaccuracy = 0;
            let weitType = 'default';
            let ElectroMercuri = ['number_223_cnt_mega_electro'];
            let Water10Litr = ['number_221_cnt_mega_waterHot','number_221_cnt_mega_waterCold','number_222_cnt_mega_waterHot','number_222_cnt_mega_waterCold','number_223_cnt_mega_waterHot','number_223_cnt_mega_waterCold','stolovaya_cnt_mega_waterCold','stolovya_cnt_mega_waterHot'];
            
            if (ElectroMercuri.indexOf(count_mega.id) != -1)
            {
              weightImpulse = 0.0003125;
              inaccuracy = 100;
            }else 
              if (Water10Litr.indexOf(count_mega.id) != -1){
              weightImpulse = 0.01;
              inaccuracy = 2;
            }
            
         if (body.substr(0,2) =='OF'){
          cnt = body.substr(4);
          }else if (body.substr(0,2) =='ON'){
          cnt = body.substr(3);
        }else
        {
          this.log('Ошибка данных от контроллера');
          this.exit();
        }
        cnt = Number(cnt);
       //this.log(cnt);
        let diff = Number(cnt) - Number(count_mega.value);
          if (diff === 0)
          {
            // this.log('скрипт - ок0');
            this.exit();
          }else if (diff > 0)
          {
            this.assign(count,"aval",(diff * weightImpulse ) + Number(count.value));
            // this.log('скрипт - ок1 =' + cnt); 
          }else{
            //сброс по питанию уже был, допустимый или нет?
            if (Number(count_mega.value) > (65535 - inaccuracy))
            { 
              let diff2 = cnt + (65536 - count_mega.value);
              if (diff2 !== 0)
              {
              this.assign(count,"aval",((diff2 * weightImpulse ) + Number(count.value)));
              }
              // this.log('скрипт - ок2');
            }else{
              //был сброс по питанию!!
              this.log('Был сброс счетчиков у контроллера ' + count_mega.id);
              if(cnt !== 0)
              {
              this.assign(count,"aval",((cnt * weightImpuls) + Number(count.value))); //нельзя присвоить тоже значение счетчику, зависнет, дальше работать не будет
              }
              
              
            }
          }
            if (Number(count_mega.value) != cnt){
              this.assign(count_mega,"value",cnt);
            }
        this.exit();
      }
    });
    
    
    


  • @regabriel, Добрый день.
    Если по какой-то причине Мега не отправляет response, этот сценарий гарантированно повиснет. Чтобы избежать зависания, нужно добавить таймер:

    script({
      start() {
         ....
        this.pluginCommand({unit: name_plugin + '', command:{url:'/'+pass_plugin +'/?pt='+port_plugin + '&cmd=get', onResponse:'raw'}},'onGetResponse');
    
        // Взвести таймер на случай, если ответа от контроллера нет - например на 2 сек
        this.startTimer('T1', 2, 'onTimeout');
      },
      // ....
      onTimeout() {
        this.log('Истек таймаут, ответ от megad не получен');
        this.exit();
      }
    });
    

Log in to reply