majordomo icon indicating copy to clipboard operation
majordomo copied to clipboard

Расширение getHistoryAvg возможностью интегрального рассчета среднего значения

Open ai91 opened this issue 6 months ago • 0 comments

Описание проблемы: Исходная реализация getHistoryAvg занимается простым подсчётом среднего значения всех сохраненных значений в запрашиваемом интервале. При таком подходе есть два проблемных сценария:

  1. Если данные поступают нерегулярно
  2. Если из-за встроенной в majordomo дедупликации данных, повторяющиеся значения не сохраняются в БД.

Пример: На данном графике имеется свойство, в которое поступало нулевое значение до 3:34, а в 3:35 и далее начало поступать значение 10000. image Если вызвать getHistoryAvg для интервала 3:30 - 4:30, то базовая имплементация обнаружит в БД только два значения: 3:34 - 0, и 3:35 - 10000. Соответсвенно результат среднего будет 5000. Значение верно математически для сохранённых данных, но неверно в прикладном смысле: среднее потребление электроустановкой за прошедший час не равно 5000Вт, а близко к 9000Вт.

Решение: Данный пуллреквест расширяет системную функцию getHistoryAvg дополнительным опциональным параметром integral: function getHistoryAvg($varname, $start_time, $stop_time = 0, $integral = false) При передаче параметра integral: true, функция находит значения для моментов времени start_time и stop_time методом интерполяции между ближайшими сохранёнными точками вокруг них, после чего рассчитывается среднее значение интегрированием методом трапеций. Изменения обратно-совместимы, т.е. если не менять пользовательский код, то поведение не меняется.

Примеры использования: Пример 1: image getHistoryAvg('OTest.power', strtotime('2024-01-27 03:30:00'), strtotime('2024-01-27 04:30:00')) = 5000 getHistoryAvg('OTest.power', strtotime('2024-01-27 03:30:00'), strtotime('2024-01-27 04:30:00'), true) = 9105

Пример 2: image getHistoryAvg('OTest.power', strtotime('2024-01-27 03:30:00'), strtotime('2024-01-27 03:40:00')) = 5000 getHistoryAvg('OTest.power', strtotime('2024-01-27 03:30:00'), strtotime('2024-01-27 03:40:00'), true) = 4633

Пример 3: Когда данные поступают регулярно и без дублирующих значений, результаты одинаковы. image getHistoryAvg('OElectricity.gridValueIn', strtotime('2024-01-28 07:00:00'), strtotime('2024-01-28 08:00:00')) = 301 getHistoryAvg('OElectricity.gridValueIn', strtotime('2024-01-28 07:00:00'), strtotime('2024-01-28 08:00:00'), true) = 301

Пример 4: Данные поступают регулярно, но некоторые дублирующие значения были не сохранены majordomo: image getHistoryAvg('OElectricity.gridValueIn', strtotime('2024-01-28 06:00:00'), strtotime('2024-01-28 07:00:00')) = 314 getHistoryAvg('OElectricity.gridValueIn', strtotime('2024-01-28 06:00:00'), strtotime('2024-01-28 07:00:00'), true) = 316

TODO: после мерджа, необходимо обновить документацию:

  1. https://mdminfo.ru/wiki/GetHistoryAvg
  2. https://kb.mjdm.ru/vstroennie-v-majordomo-funkcii/3
  3. https://mjdm.ru/forum/viewtopic.php?t=2997

ai91 avatar Jan 28 '24 12:01 ai91