Помогите с кодом (с логикой) пожалуйста
Модератор: immortal
-
- Сообщения: 2087
- Зарегистрирован: Пт апр 07, 2017 12:20 pm
- Благодарил (а): 313 раз
- Поблагодарили: 458 раз
Re: Помогите с кодом (с логикой) пожалуйста
можете на гите посмотреть, хотя все это у вас локально есть
посмотрите в пу счетчика в инжекциях
посмотрите в пу счетчика в инжекциях
Telegram | Блог
Raspberry Pi3, с образа от Сергея 3.31, PHP 7, флешка 16 Гб работает с 10.09.2017
Почти всё время уходит на исправление ошибок, оставшееся - на их повторение. (с) ))) Спасибо
Raspberry Pi3, с образа от Сергея 3.31, PHP 7, флешка 16 Гб работает с 10.09.2017
Почти всё время уходит на исправление ошибок, оставшееся - на их повторение. (с) ))) Спасибо
-
- Сообщения: 1463
- Зарегистрирован: Вс янв 10, 2016 11:05 am
- Благодарил (а): 260 раз
- Поблагодарили: 454 раза
Re: Помогите с кодом (с логикой) пожалуйста
Приятно иметь дело с человеком, который знает, чего хочет, и может это четко сформулировать.
Начну опять же с выражения благодарности ув.xor за его замечательную функцию (https://connect.smartliving.ru/profile/ ... omili.html). Также поблагодарю ув.SmoKE_xDDD за вебинар от 04.04.2021, из которого в числе прочего я узнал, каким образом можно собственные функции легко "прикрутить" к системе.
Перед тем, как приступать к счетчику, потренируемся на более простом объекте. Соберем статистику работы насосов. Узнаем, как долго они работали в течение прошлого дня и как часто включались.
Прикручиваем функцию getHistoryPart от ув.xor к системе. В директории \htdocs\lib\ создаем файл с именем, к примеру, "my.class.php" и вписываем в него код функции:
После этого можем пользоваться данной функцией в коде наравне со штатными функциями системы.
В класс с объектами насосов добавляем свойства, куда будем сохранять статистику по их использованию за истекший день:
UsagePart -- доля дня, когда насос был включен;
UsagePercent -- процент времени в течение дня, когда насос был включен (то же что и доля, только переведенная в проценты);
UsagePeriod -- период времени (текстом), когда насос был включен (например, "11 ч. 17 мин. 38 сек.");
UsageАctivationQuantity -- количество включений насоса.
У свойств включаем историю.
Добавляем в класс насосов метод "getUsageStatistics".
Код запишем в методы объектов и поправим (при необходимости) имя объекта в функциях getHistoryPart и getHistorySum:
Хотя метод и под классовый несложно переписать:
Запускать метод надо раз в сутки. Можно из OnNewMinute, а лучше даже из onNewHour:
Можно и одновременно все запускать, но это я уж перестраховываюсь, и распределяю нагрузку на систему по времени.
А самый лучший вариант -- запускать код из onNewDay. Если такого объекта в таймерах нет, надо его просто добавить. А оттуда уже запускать через небольшие промежутки времени:
Как использовать полученную статистику в интерфейсе (в информерах, в текстовых блоках с переменными) писать не буду. Это, думаю, вопрос вторичный.
А счетчиком, как более сложным объектом, займемся завтра-послезавтра.
Хотя это и не особо принципиально, но из исходных данных нет только дневного и ночного тарифов.
Да,... и имя Объект.Свойства надо знать, куда сохраняется данные счетчика об израсходованных киловаттах.
Начну опять же с выражения благодарности ув.xor за его замечательную функцию (https://connect.smartliving.ru/profile/ ... omili.html). Также поблагодарю ув.SmoKE_xDDD за вебинар от 04.04.2021, из которого в числе прочего я узнал, каким образом можно собственные функции легко "прикрутить" к системе.
Перед тем, как приступать к счетчику, потренируемся на более простом объекте. Соберем статистику работы насосов. Узнаем, как долго они работали в течение прошлого дня и как часто включались.
Прикручиваем функцию getHistoryPart от ув.xor к системе. В директории \htdocs\lib\ создаем файл с именем, к примеру, "my.class.php" и вписываем в него код функции:
Код: Выделить всё
<?php
//возвращает долю времени на интервале, где истинно сравнение $objprop со значением $value по правилу $oper
//$oper{'=','<>','>','>=','<','<=','betw','!betw'};
//ex gg('obj.prop') == 1 / gg('obj.prop') betw -1,1/ gg('obj.prop') !betw 10,15
//return t(true part)/t(whole interval)
function getHistoryPart($objprop, $start_time, $stop_time = 0, $oper = "=", $value = '1', $value2 = '0') {
if($start_time <= 0) $start_time = (time() + $start_time);
if($stop_time <= 0) $stop_time = (time() + $stop_time);
$pvalue = getHistoryValueId($objprop);
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>');
if($oper == '=' || $oper == '=='){
if($s['VALUE']==$value) $tmr_mem = $tmr_mem + $tmr1 - $tmr2;
}elseif($oper == '>'){
if($s['VALUE']>$value) $tmr_mem = $tmr_mem + $tmr1 - $tmr2;
}elseif($oper == '<'){
if($s['VALUE']<$value) $tmr_mem = $tmr_mem + $tmr1 - $tmr2;
}elseif($oper == '>='){
if($s['VALUE']>=$value) $tmr_mem = $tmr_mem + $tmr1 - $tmr2;
}elseif($oper == '<='){
if($s['VALUE']<=$value) $tmr_mem = $tmr_mem + $tmr1 - $tmr2;
}elseif($oper == '<>' || $oper == '!='){
if($s['VALUE']<>$value) $tmr_mem = $tmr_mem + $tmr1 - $tmr2;
}elseif($oper == 'betw'){
if($s['VALUE']>=$value && $s['VALUE']<=$value2) $tmr_mem = $tmr_mem + $tmr1 - $tmr2;
}elseif($oper == '!betw'){
if($s['VALUE']<$value || $s['VALUE']>$value2) $tmr_mem = $tmr_mem + $tmr1 - $tmr2;
}
}//foreach
$all = $stop_time - $start_time; //всего времени с начала интервала до конца
return $tmr_mem/$all;
}
?>
В класс с объектами насосов добавляем свойства, куда будем сохранять статистику по их использованию за истекший день:
UsagePart -- доля дня, когда насос был включен;
UsagePercent -- процент времени в течение дня, когда насос был включен (то же что и доля, только переведенная в проценты);
UsagePeriod -- период времени (текстом), когда насос был включен (например, "11 ч. 17 мин. 38 сек.");
UsageАctivationQuantity -- количество включений насоса.
У свойств включаем историю.
Добавляем в класс насосов метод "getUsageStatistics".
Код запишем в методы объектов и поправим (при необходимости) имя объекта в функциях getHistoryPart и getHistorySum:
Код: Выделить всё
//Получаем статистику работы насоса за прошлый день
//Рассчитываем долю времени работы насоса в течение прошлого дня
$StartLastDayTime = strtotime(date('Y-m-d 0:0:0',time()-60*60*24));
$EndLastDayTime = strtotime(date('0:0:0',time()-1));
$Part = getHistoryPart('PumpHeat_01.Status',$StartLastDayTime,$EndLastDayTime,'=',1);
$this->setProperty('UsagePart', $Part);
//Процент пребывания во включенном состоянии в течение анализируемого периода
$UsagePercent = round($Part*100,2);
$this->setProperty('UsagePercent', $UsagePercent);
//Продолжительность пребывания во включенном состоянии в течение дня
$UsagePeriod = round($Part*60*60*24,0);
$UsagePeriod_H = floor($UsagePeriod/60/60);
$UsagePeriod_M = floor($UsagePeriod/60 - $UsagePeriod_H*60);
$UsagePeriod_S = floor($UsagePeriod - $UsagePeriod_H*60*60 - $UsagePeriod_M*60);
$UsagePeriodLastDayText = $UsagePeriod_H." ч. ".$UsagePeriod_M." мин. ".$UsagePeriod_S." сек.";
$this->setProperty('UsagePeriod', $UsagePeriodLastDayText);
//Считаем количество включений насоса в течение прошлого дня
$UsageАctivationQuantity = getHistorySum('PumpHeat_01.Status',$StartLastDayTime,$EndLastDayTime);
$this->setProperty('UsageАctivationQuantity', $UsageАctivationQuantity);
Код: Выделить всё
//Получаем статистику работы насоса за прошлый день
//Рассчитываем долю времени работы насоса в течение прошлого дня
$ot = $this->object_title;
$StartLastDayTime = strtotime(date('Y-m-d 0:0:0',time()-60*60*24));
$EndLastDayTime = strtotime(date('0:0:0',time()-1));
$Part = getHistoryPart($ot.'.Status',$StartLastDayTime,$EndLastDayTime,'=',1);
$this->setProperty('UsagePart', $Part);
//Процент пребывания во включенном состоянии в течение анализируемого периода
$UsagePercent = round($Part*100,2);
$this->setProperty('UsagePercent', $UsagePercent);
//Продолжительность пребывания во включенном состоянии в течение дня
$UsagePeriod = round($Part*60*60*24,0);
$UsagePeriod_H = floor($UsagePeriod/60/60);
$UsagePeriod_M = floor($UsagePeriod/60 - $UsagePeriod_H*60);
$UsagePeriod_S = floor($UsagePeriod - $UsagePeriod_H*60*60 - $UsagePeriod_M*60);
$UsagePeriodLastDayText = $UsagePeriod_H." ч. ".$UsagePeriod_M." мин. ".$UsagePeriod_S." сек.";
$this->setProperty('UsagePeriod', $UsagePeriodLastDayText);
//Считаем количество включений насоса в течение прошлого дня
$UsageАctivationQuantity = getHistorySum($ot.'.Status',$StartLastDayTime,$EndLastDayTime);
$this->setProperty('UsageАctivationQuantity', $UsageАctivationQuantity);
Код: Выделить всё
if (timeIs('00:01')) callMethodSafe('PumpHeat_01.getUsageStatistics');
if (timeIs('00:02')) callMethodSafe('PumpHeat_02.getUsageStatistics');
if (timeIs('00:03')) callMethodSafe('PumpHeat_03.getUsageStatistics');
А самый лучший вариант -- запускать код из onNewDay. Если такого объекта в таймерах нет, надо его просто добавить. А оттуда уже запускать через небольшие промежутки времени:
Код: Выделить всё
callMethodSafe('PumpHeat_01.getUsageStatistics');
SetTimeOut("PumpHeat_02_getUsageStatistics","callMethodSafe('PumpHeat_02.getUsageStatistics');",5);
SetTimeOut("PumpHeat_03_getUsageStatistics","callMethodSafe('PumpHeat_03.getUsageStatistics');",10);
А счетчиком, как более сложным объектом, займемся завтра-послезавтра.
Хотя это и не особо принципиально, но из исходных данных нет только дневного и ночного тарифов.
Да,... и имя Объект.Свойства надо знать, куда сохраняется данные счетчика об израсходованных киловаттах.
Последний раз редактировалось Chainik Вт май 11, 2021 11:56 am, всего редактировалось 1 раз.
- Рейтинг: 1.16%
Re: Помогите с кодом (с логикой) пожалуйста
Примите мою искреннюю благодарность!!!
Вот уже задумался над интерфейсом, сделаю отдельную сцену с отоплением и всей статистикой.
Тарифы постараюсь узнать, но их всегда вписать можно.
Сейчас счетчик все передает в Counter02.valueWork, но можно назначить любой другой объект и свойство
Вот уже задумался над интерфейсом, сделаю отдельную сцену с отоплением и всей статистикой.
Тарифы постараюсь узнать, но их всегда вписать можно.
Сейчас счетчик все передает в Counter02.valueWork, но можно назначить любой другой объект и свойство
- xor
- Сообщения: 2041
- Зарегистрирован: Сб ноя 22, 2014 8:45 pm
- Благодарил (а): 286 раз
- Поблагодарили: 629 раз
Re: Помогите с кодом (с логикой) пожалуйста
Фундаментальный разбор! Единственно добавлю, что, если это нужно делать в полночь, я использую onNewDay
Этот метод запускается с началом нового дня как раз. Тогда разнесение запусков на неск. секунд и в разные потоки можно так записать, попроще:
Код: Выделить всё
SetTimeOut("sun_t","RunScript('sun');",2);
SetTimeOut("moon_t","RunScript('moon');",5);
SetTimeOut("rates","RunScript('Курсы');",7);
setTimeOut("holidays","RunScript('holidays');",10);
win10 connect https://connect.smartliving.ru/profile/303
-
- Сообщения: 1463
- Зарегистрирован: Вс янв 10, 2016 11:05 am
- Благодарил (а): 260 раз
- Поблагодарили: 454 раза
Re: Помогите с кодом (с логикой) пожалуйста
Xor, моё почтение!
Я бы тоже в OnNewDay запихнул, но такого объекта нет в "нулёвой" системе. Понятно, что нетрудно добавить, но вопрос в том, каким образом вы инициируете запуск OnNewDay?
Я бы тоже в OnNewDay запихнул, но такого объекта нет в "нулёвой" системе. Понятно, что нетрудно добавить, но вопрос в том, каким образом вы инициируете запуск OnNewDay?
- xor
- Сообщения: 2041
- Зарегистрирован: Сб ноя 22, 2014 8:45 pm
- Благодарил (а): 286 раз
- Поблагодарили: 629 раз
Re: Помогите с кодом (с логикой) пожалуйста
Этот метод нужно просто создать в классе, а в коде системы его обновление уже прописано так же, как и для минут и часов
- Рейтинг: 1.16%
win10 connect https://connect.smartliving.ru/profile/303
-
- Сообщения: 1463
- Зарегистрирован: Вс янв 10, 2016 11:05 am
- Благодарил (а): 260 раз
- Поблагодарили: 454 раза
Re: Помогите с кодом (с логикой) пожалуйста
Важно! Код добавленной функции должен быть обрамлен в теги PHP, иначе будет выдавать ошибку. Поправил в тексте поста.
Re: Помогите с кодом (с логикой) пожалуйста
Функцию вставил, все прекрасно работает, спасибо огромное !!!
-
- Сообщения: 1463
- Зарегистрирован: Вс янв 10, 2016 11:05 am
- Благодарил (а): 260 раз
- Поблагодарили: 454 раза
Re: Помогите с кодом (с логикой) пожалуйста
Ну прекрасно. Единственное, порекомендую еще залезть в модуль Оптимайзер и отключить всякую оптимизацию у наших свойств с историей, особенно у свойства Status. А то модуль может начать усреднять и "прореживать" нули с единицами. Он на это способен, если "пустить дело на самотек". ))
Со счетчиком принципиальных проблем не вижу, но не могу гарантировать, что завтра все закончу (в связи с появившимися неотложными делами). Но то что в итоге сделаем, не сомневайтесь.
Со счетчиком принципиальных проблем не вижу, но не могу гарантировать, что завтра все закончу (в связи с появившимися неотложными делами). Но то что в итоге сделаем, не сомневайтесь.
-
- Сообщения: 1463
- Зарегистрирован: Вс янв 10, 2016 11:05 am
- Благодарил (а): 260 раз
- Поблагодарили: 454 раза
Re: Помогите с кодом (с логикой) пожалуйста
Друзья! Я тут по наличию времени "сочиняю", чтобы долго не рыться в поисках ответа, может подскажите, как проще извлечь значение из строки? В общем, получаю нужную мне строчку из истории в виде:
{"VALUE":"555.25","ADDED":"2021-05-12 18:20:14"}
Каким образом проще извлечь из строки значение 555.25?
{"VALUE":"555.25","ADDED":"2021-05-12 18:20:14"}
Каким образом проще извлечь из строки значение 555.25?