Xor

<<< Back

О среднем в Мажордомо

Записки ниже не касаются тех, у кого значения в таблицу пишутся регулярно и с повторами.

У меня это, к сожалению, не так.

Штатная функция gethistoryavg возвращает среднее арифметическое от значений в периоде, подразумевая равноправие всех отсчетов значений.
Предлагается вместо этого использовать средневзвешенное по времени, где вес значения зависит от длительности его действия.

Итог виден тут:

2019-03-24 14:51:00
2019-03-23 14:51:00
getHistoryAvgMy=0.3879
getHistoryAvg=-0.301436781609196

Вычисленное средневзвешенное значение = 0.38, среднее getHistoryAvg = -0.30

Вот код функции:

/**
* getHistoryAvgMy
*
* Return AVG data
*
* @access public
*/
function getHistoryAvgMy($varname, $start_time, $stop_time = 0) { 
        if ($start_time <= 0) $start_time = (time() + $start_time);
        if ($stop_time  <= 0) $stop_time  = (time() + $stop_time);

        // Get hist val id
    $pvalue = getHistoryValueId($varname);
    if (defined('SEPARATE_HISTORY_STORAGE') && SEPARATE_HISTORY_STORAGE == 1) {
        $table_name = createHistoryTable($pvalue);
    } else {
        $table_name = 'phistory';
    }

         // Получить количество записей за нужный период времени
         $arr_s = SQLSelectOne("SELECT COUNT(ID) as COUNT_ID FROM $table_name ".
                  "WHERE VALUE_ID=".$pvalue." and not value is null ".
                  "AND ADDED between '".date('Y-m-d H:i:s', $start_time)."' AND '".date('Y-m-d H:i:s', $stop_time)."'");
         // Взять это количество записей +1
         $arr_s = SQLSelect("SELECT * FROM $table_name WHERE VALUE_ID=".$pvalue." and not value is null ".
                  " AND ADDED<='".date('Y-m-d H:i:s', $stop_time)."' ORDER BY ADDED DESC LIMIT 0 , ".(1+$arr_s['COUNT_ID']));
         $tmr2 = $stop_time;

         // Переберем весь массив
         foreach($arr_s as $s) {
          $tmr1 = $tmr2;
          $tmr2 = strtotime($s['ADDED']);

          // Ограничить началом 
          if ($tmr2<$start_time) 
                        $tmr2 = $start_time; 
            // Двигаясь вниз по массиву времени складывать отрезки 
            //echo(date('H:i:s', $tmr1).' - '.date('H:i:s', $tmr2).' = '.($tmr1 - $tmr2).'c  t='.$s['VALUE'].'<br>');
            $tmr_mem = $tmr_mem + $tmr1 - $tmr2; 
            $ss = $ss + $s['VALUE']*($tmr1 - $tmr2); 
         }

         $avg =  $ss / $tmr_mem ;

         if (!$avg)
                return false;

        return $avg;
}

Проверялось в экселе по этой строке:

 echo(date('H:i:s', $tmr1).' - '.date('H:i:s', $tmr2).' = '.($tmr1 - $tmr2).'c  t='.$s['VALUE'].'<br>');

Discuss (0) (4)

See also:
2018-10-31 Об "обделённых" пользователях Win-систем -- с точки зрения кэширования winTTS сообщений
2018-09-16 Перезагрузка Мажордомо в Win-системах

Москва, Россия

На форуме: xor