Предыдущее значения свойства с историей
Модератор: immortal
- Bagir
- Сообщения: 1615
- Зарегистрирован: Вт сен 17, 2013 6:46 pm
- Откуда: Ярославская область город Углич
- Благодарил (а): 212 раз
- Поблагодарили: 375 раз
Предыдущее значения свойства с историей
Как получить? Вероятно SQL запросом. Это я мог бы, но никак не разберусь в структуре базы. Таблицу нашел. Должно быть это phistory. Но как узнать VALUE_ID? Нашел таблицу объектов и свойств. Нашел где записано количества дней истории. Но как узнать VALUE_ID так и не понял.
Помогите запросом, или инфой как получить VALUE_ID из таблицы phistory.
Помогите запросом, или инфой как получить VALUE_ID из таблицы phistory.
-
- Сообщения: 284
- Зарегистрирован: Сб ноя 24, 2012 11:47 am
- Благодарил (а): 32 раза
- Поблагодарили: 28 раз
Re: Предыдущее значения свойства с историей
- Рейтинг: 1.16%
- Bagir
- Сообщения: 1615
- Зарегистрирован: Вт сен 17, 2013 6:46 pm
- Откуда: Ярославская область город Углич
- Благодарил (а): 212 раз
- Поблагодарили: 375 раз
Re: Предыдущее значения свойства с историей
Вот спасибо! Как только не пробовал искать, ничего не попадалось. И надо было же попробовать по "FROM phistory WHERE" Ну как сам не догадался... Можно получить не только последнее значение, но еще и анализировать изменения данных. Отличный пример!
- Bagir
- Сообщения: 1615
- Зарегистрирован: Вт сен 17, 2013 6:46 pm
- Откуда: Ярославская область город Углич
- Благодарил (а): 212 раз
- Поблагодарили: 375 раз
Re: Предыдущее значения свойства с историей
Сделал так:
Метод tempChanged класса tempSensors запускается у меня при изменении свойства temp. Это удобно для слинкованных датчиков. У свойства temp есть история. Добавил метод код для определеня куда изменяется температура.
Теперь у датчиков температуры на сценах есть треугольник, показывающий направление изменения температуры. Вот как то так:

При сравнении температур, можно отключить 0, тогда всегда будет сохранено последнее изменение температуры.
Метод tempChanged класса tempSensors запускается у меня при изменении свойства temp. Это удобно для слинкованных датчиков. У свойства temp есть история. Добавил метод код для определеня куда изменяется температура.
Код: Выделить всё
// Внимание! История свойства должна храниться!!!
// получить предыдущее значение температуры из SQL базы и сравнить с новым.
//Получить ид свойства
$prop_id=$this->getPropertyByName('temp', $this->class_id, $this->id);
//Получаем VALUE_ID для следующей таблицы
$pvalue=SQLSelectOne("SELECT * FROM pvalues WHERE PROPERTY_ID='".$prop_id."' AND OBJECT_ID='".$this->id."'");
// Получаем предыдущую запись
$prevRecord = SQLSelectOne("SELECT * FROM phistory WHERE VALUE_ID='".$pvalue['ID']."' ORDER BY ADDED DESC LIMIT 1 , 1");
// Округление до 1 цифры
$old_temp=round($prevRecord[VALUE], 1);
$cur_temp = round($this->getProperty('temp'), 1);
//Сравнение
if ($cur_temp>$old_temp) {
$d=1;
} elseif ($cur_temp<$old_temp) {
$d=-1;
} else {
$d=0;
}
$this->setProperty('direction',$d);

При сравнении температур, можно отключить 0, тогда всегда будет сохранено последнее изменение температуры.
Код: Выделить всё
//Сравнение
if ($cur_temp>$old_temp) {
$this->setProperty('direction',1);
} elseif ($cur_temp<$old_temp) {
$this->setProperty('direction',-1);
} else {
// $this->setProperty('direction',0);
}
-
- Сообщения: 867
- Зарегистрирован: Вт янв 17, 2012 12:31 pm
- Благодарил (а): 121 раз
- Поблагодарили: 78 раз
Re: Предыдущее значения свойства с историей
Как значек изменения ниже датчика расположил?Bagir писал(а): Теперь у датчиков температуры на сценах есть треугольник, показывающий направление изменения температуры. Вот как то так:
![]()
- Bagir
- Сообщения: 1615
- Зарегистрирован: Вт сен 17, 2013 6:46 pm
- Откуда: Ярославская область город Углич
- Благодарил (а): 212 раз
- Поблагодарили: 375 раз
Re: Предыдущее значения свойства с историей
Можно позиционировать с помощью CSS. Я там порядочно поднабрался, пока трубы рисовал, но тут я просто перед тегом, который рисует значок, поставил <br>
- Рейтинг: 1.16%
- Bagir
- Сообщения: 1615
- Зарегистрирован: Вт сен 17, 2013 6:46 pm
- Откуда: Ярославская область город Углич
- Благодарил (а): 212 раз
- Поблагодарили: 375 раз
Re: Предыдущее значения свойства с историей
Я уже приводил пример кода метода tempChanged. Так что сейчас только расскажу о дополнениях. Свойство direction у меня пока что используется только для элементов датчиков на сценах. Показывает направление изменения значения. Если, к примеру, взять температуру или влажность, то показания при каждом считывании датчика будут разные. Даже +- градус это нормально. В основном конечно температура гуляет на пол градуса. Соответственно стрелки изменения на датчиках тоже постоянно показывают то вверх, то вниз. А следовательно от них нет никакого прока.
Но если смотреть на среднюю величину за определенный период, то уже становится более интересно. Пока что я выбрал такие временные рамки: при периоде обновления датчика 5-10 минут, сравнить среднюю температуру за последние 30 минут, и текущую температуру. Теперь днем, когда ярко светило солнце, все стрелки на датчиках показали вверх, за исключением одного, в комнате которого было открыто окно. Там температура немного упала.
Такой подход мне понравился больше. Уже через полчаса работы котла на отопление, стрелки датчиков всех комнат дружно показывали вверх.
Вот кусок кода из tempChanged для получения средней температуры за полчасар:
Ранее я отключал установку свойства direction = 0, чтобы у датчика всегда была стрелка о последнем изменении температуры. Теперь, учитывая временные рамки, direction = 0 опять обрело смысл. Незначительные колебания температуры - это не повод показывать стрелку изменения.
Но если смотреть на среднюю величину за определенный период, то уже становится более интересно. Пока что я выбрал такие временные рамки: при периоде обновления датчика 5-10 минут, сравнить среднюю температуру за последние 30 минут, и текущую температуру. Теперь днем, когда ярко светило солнце, все стрелки на датчиках показали вверх, за исключением одного, в комнате которого было открыто окно. Там температура немного упала.
Такой подход мне понравился больше. Уже через полчаса работы котла на отопление, стрелки датчиков всех комнат дружно показывали вверх.
Вот кусок кода из tempChanged для получения средней температуры за полчасар:
Код: Выделить всё
// Получение среднего значения из истории
//Получить id свойства
$prop_id=$this->getPropertyByName('temp', $this->class_id, $this->id);
//Получаем VALUE_ID для следующей таблицы
$pvalue=SQLSelectOne("SELECT * FROM pvalues WHERE PROPERTY_ID='".$prop_id."' AND OBJECT_ID='".$this->id."'");
//Получаем средние значения температуры за последние 30 минут
$start_time=time()-30*60; // 30 минут
$arr_t = SQLSelectOne("SELECT avg(VALUE) as AVG_V FROM phistory WHERE VALUE_ID='".$pvalue['ID']."' AND ADDED>='".date('Y-m-d H:i:s', $start_time)."'");
$avg_t=round($arr_t[AVG_V], 1);
Полный код метода tempChangedПоказать
Код: Выделить всё
// $params['t']
$this->setProperty("updated",time());
$this->setProperty("updatedTime",date("H:i",time()));
$this->setProperty("alive",1);
$ot=$this->object_title;
$alive_timeout=(int)$this->getProperty("aliveTimeOut");
if (!$alive_timeout) {
$alive_timeout=30*60;
}
clearTimeOut($ot."_alive");
setTimeOut($ot."_alive","sg('".$ot.".alive',0);",$alive_timeout);
$t=round($params['t'], 1);
if (($t > 150) || ($t < -50)) {
//Некорректные данные
return;
}
// Получение среднего значения из истории
//Получить id свойства
$prop_id=$this->getPropertyByName('temp', $this->class_id, $this->id);
//Получаем VALUE_ID для следующей таблицы
$pvalue=SQLSelectOne("SELECT * FROM pvalues WHERE PROPERTY_ID='".$prop_id."' AND OBJECT_ID='".$this->id."'");
//Получаем средние значения температуры за последние 30 минут
$start_time=time()-30*60; // 30 минут
$arr_t = SQLSelectOne("SELECT avg(VALUE) as AVG_V FROM phistory WHERE VALUE_ID='".$pvalue['ID']."' AND ADDED>='".date('Y-m-d H:i:s', $start_time)."'");
$avg_t=round($arr_t[AVG_V], 1);
$this->setProperty('temp',$t);
//Сравнение
if ($t>$avg_t) {
$d=1;
} elseif ($t<$avg_t) {
$d=-1;
} else {
$d=0;
}
$this->setProperty('direction',$d);
// Передать данные слинкованной комнате
$linked_room=$this->getProperty("LinkedRoom");
if ($linked_room) {
setGlobal($linked_room.'.Temperature', $t);
}
- Vovix
- Сообщения: 1155
- Зарегистрирован: Пн янв 27, 2014 1:43 am
- Откуда: г.Ижевск
- Благодарил (а): 60 раз
- Поблагодарили: 532 раза
- Контактная информация:
Re: Предыдущее значения свойства с историей
Bagir писал(а):Я уже приводил пример кода метода tempChanged. Так что сейчас только расскажу о дополнениях. Свойство direction у меня пока что используется только для элементов датчиков на сценах. Показывает направление изменения значения. Если, к примеру, взять температуру или влажность, то показания при каждом считывании датчика будут разные. Даже +- градус это нормально. В основном конечно температура гуляет на пол градуса. Соответственно стрелки изменения на датчиках тоже постоянно показывают то вверх, то вниз. А следовательно от них нет никакого прока.
Но если смотреть на среднюю величину за определенный период, то уже становится более интересно. Пока что я выбрал такие временные рамки: при периоде обновления датчика 5-10 минут, сравнить среднюю температуру за последние 30 минут, и текущую температуру. Теперь днем, когда ярко светило солнце, все стрелки на датчиках показали вверх, за исключением одного, в комнате которого было открыто окно. Там температура немного упала.
Такой подход мне понравился больше. Уже через полчаса работы котла на отопление, стрелки датчиков всех комнат дружно показывали вверх.
Вот кусок кода из tempChanged для получения средней температуры за полчасар:Ранее я отключал установку свойства direction = 0, чтобы у датчика всегда была стрелка о последнем изменении температуры. Теперь, учитывая временные рамки, direction = 0 опять обрело смысл. Незначительные колебания температуры - это не повод показывать стрелку изменения.Код: Выделить всё
// Получение среднего значения из истории //Получить id свойства $prop_id=$this->getPropertyByName('temp', $this->class_id, $this->id); //Получаем VALUE_ID для следующей таблицы $pvalue=SQLSelectOne("SELECT * FROM pvalues WHERE PROPERTY_ID='".$prop_id."' AND OBJECT_ID='".$this->id."'"); //Получаем средние значения температуры за последние 30 минут $start_time=time()-30*60; // 30 минут $arr_t = SQLSelectOne("SELECT avg(VALUE) as AVG_V FROM phistory WHERE VALUE_ID='".$pvalue['ID']."' AND ADDED>='".date('Y-m-d H:i:s', $start_time)."'"); $avg_t=round($arr_t[AVG_V], 1);
Полный код метода tempChangedПоказатьКод: Выделить всё
// $params['t'] $this->setProperty("updated",time()); $this->setProperty("updatedTime",date("H:i",time())); $this->setProperty("alive",1); $ot=$this->object_title; $alive_timeout=(int)$this->getProperty("aliveTimeOut"); if (!$alive_timeout) { $alive_timeout=30*60; } clearTimeOut($ot."_alive"); setTimeOut($ot."_alive","sg('".$ot.".alive',0);",$alive_timeout); $t=round($params['t'], 1); if (($t > 150) || ($t < -50)) { //Некорректные данные return; } // Получение среднего значения из истории //Получить id свойства $prop_id=$this->getPropertyByName('temp', $this->class_id, $this->id); //Получаем VALUE_ID для следующей таблицы $pvalue=SQLSelectOne("SELECT * FROM pvalues WHERE PROPERTY_ID='".$prop_id."' AND OBJECT_ID='".$this->id."'"); //Получаем средние значения температуры за последние 30 минут $start_time=time()-30*60; // 30 минут $arr_t = SQLSelectOne("SELECT avg(VALUE) as AVG_V FROM phistory WHERE VALUE_ID='".$pvalue['ID']."' AND ADDED>='".date('Y-m-d H:i:s', $start_time)."'"); $avg_t=round($arr_t[AVG_V], 1); $this->setProperty('temp',$t); //Сравнение if ($t>$avg_t) { $d=1; } elseif ($t<$avg_t) { $d=-1; } else { $d=0; } $this->setProperty('direction',$d); // Передать данные слинкованной комнате $linked_room=$this->getProperty("LinkedRoom"); if ($linked_room) { setGlobal($linked_room.'.Temperature', $t); }
Странно!
Я тут решил проверить работоспособность этого кода tempChanged у себя
и обнаружил, что $params['t'] у меня всегда равно 0
хотя значение свойства связанного с 1-wire объекта TempSensor1.temp нормально и показывает сейчас например 24
изменил код в двух местах:
в самом начале добавил
Код: Выделить всё
$t=$this->getProperty("temp");
Код: Выделить всё
$t=round($params['t'], 1);
Код: Выделить всё
$t=round($t,1);
видимо у вас метод вызывается с параметром при изменении, а у меня без входящего параметра...
наверно так!
Мой -CONNECT-
Windows 7(PHP 7.2) + Raspberry Pi(освещение на 1-Wire) + MP751(управление) + ESP8266(сенсоры) + LAN(сенсоры)
-=: Если вам помогло моё сообщение, нажмите кнопку "Поблагодарить за сообщение автора: Vovix" (кнопка Спасибо) справа! :=-
Windows 7(PHP 7.2) + Raspberry Pi(освещение на 1-Wire) + MP751(управление) + ESP8266(сенсоры) + LAN(сенсоры)
-=: Если вам помогло моё сообщение, нажмите кнопку "Поблагодарить за сообщение автора: Vovix" (кнопка Спасибо) справа! :=-
- Vovix
- Сообщения: 1155
- Зарегистрирован: Пн янв 27, 2014 1:43 am
- Откуда: г.Ижевск
- Благодарил (а): 60 раз
- Поблагодарили: 532 раза
- Контактная информация:
Re: Предыдущее значения свойства с историей
И еще, мне градиентная заливка была не нужна, а вот direction хотел прикрутить!
Вот я так сделал без использования дополнительных состояний, прямо в коде самого значения температуры:
Вот я так сделал без использования дополнительных состояний, прямо в коде самого значения температуры:
Код: Выделить всё
<span style="font-size:42px;font-weight:bold;
background: url(/images/%TempSensor1.direction%.gif) bottom 10px left / 20px 20px no-repeat;">
%TempSensor1.temp1%°C</span>
- Вложения
-
- Скриншот 2014-11-30 02.40.47.png (24.76 КБ) 13256 просмотров
Мой -CONNECT-
Windows 7(PHP 7.2) + Raspberry Pi(освещение на 1-Wire) + MP751(управление) + ESP8266(сенсоры) + LAN(сенсоры)
-=: Если вам помогло моё сообщение, нажмите кнопку "Поблагодарить за сообщение автора: Vovix" (кнопка Спасибо) справа! :=-
Windows 7(PHP 7.2) + Raspberry Pi(освещение на 1-Wire) + MP751(управление) + ESP8266(сенсоры) + LAN(сенсоры)
-=: Если вам помогло моё сообщение, нажмите кнопку "Поблагодарить за сообщение автора: Vovix" (кнопка Спасибо) справа! :=-
- Vovix
- Сообщения: 1155
- Зарегистрирован: Пн янв 27, 2014 1:43 am
- Откуда: г.Ижевск
- Благодарил (а): 60 раз
- Поблагодарили: 532 раза
- Контактная информация:
Re: Предыдущее значения свойства с историей
Еще подумал я: очень редко я вижу, что направление изменения равно 0 (т.е. как-бы температура стабильна)!
А почему?
Потому, что среднее значение за последние 0,5 часа может и отличается незначительно, например на 0,1 грудуса
и следовательно даже такое незначительное отличие предложенный алгоритм примет за какую-то тенденцию (направление), что по сути не верно!
Решение: надо, предположим, менять свойство direction, на направление изменения вверх(1) или вниз(-1), только если это изменение больше либо равно 0,5 градуса (можно потом откорректировать эту величину), в противном случае, изменение на менее чем 0,5 градуса считать несущественным, а температуру стабильной (direction=0)!
для примера весь мой код tempChanged
теперь стало как мне надо (я так думаю):
А почему?
Потому, что среднее значение за последние 0,5 часа может и отличается незначительно, например на 0,1 грудуса
и следовательно даже такое незначительное отличие предложенный алгоритм примет за какую-то тенденцию (направление), что по сути не верно!
Решение: надо, предположим, менять свойство direction, на направление изменения вверх(1) или вниз(-1), только если это изменение больше либо равно 0,5 градуса (можно потом откорректировать эту величину), в противном случае, изменение на менее чем 0,5 градуса считать несущественным, а температуру стабильной (direction=0)!
Код: Выделить всё
// Сравнение со средним значением с учетом разницы по модулю 0.5
if (abs($avg_t-$t)>=0.5) {
if ($t>$avg_t) {
$d=1;
} else {
$d=-1;
}}
else {
$d=0;
}
СпойлерПоказать
Код: Выделить всё
$t=$this->getProperty("temp");
$this->setProperty("updated",time());
$this->setProperty("updatedTime",date("H:i",time()));
$this->setProperty("alive",1);
$ot=$this->object_title;
$alive_timeout=(int)$this->getProperty("aliveTimeOut");
if (!$alive_timeout) {
$alive_timeout=30*60; // 30 минут
}
clearTimeOut($ot."_alive");
setTimeOut($ot."_alive","sg('".$ot.".alive',0);",$alive_timeout);
$t=round($t,1);
if (($t > 80) || ($t < -50)) return;
// Получение среднего значения из истории
//Получить id свойства
$prop_id=$this->getPropertyByName('temp1', $this->class_id, $this->id);
//Получаем VALUE_ID для следующей таблицы
$pvalue=SQLSelectOne("SELECT * FROM pvalues WHERE PROPERTY_ID='".$prop_id."' AND OBJECT_ID='".$this->id."'");
//Получаем средние значения температуры за последние 30 минут
$start_time=time()-30*60; // 30 минут
$arr_t = SQLSelectOne("SELECT avg(VALUE) as AVG_V FROM phistory WHERE VALUE_ID='".$pvalue['ID']."' AND ADDED>='".date('Y-m-d H:i:s', $start_time)."'");
$avg_t=round($arr_t[AVG_V], 1);
// Историю храним именно в temp1
$this->setProperty('temp1',$t);
if ($params['uptime']) {
$this->setProperty('uptime',$params['uptime']);
}
// Сравнение со средним значением с учетом разницы по модулю 0.5
if (abs($avg_t-$t)>=0.5) {
if ($t>$avg_t) {
$d=1;
} else {
$d=-1;
}}
else {
$d=0;
}
$this->setProperty('direction',$d);
$linked_room=$this->getProperty("LinkedRoom");
if ($linked_room) {
setGlobal($linked_room.'.Temperature',$t);
}
Мой -CONNECT-
Windows 7(PHP 7.2) + Raspberry Pi(освещение на 1-Wire) + MP751(управление) + ESP8266(сенсоры) + LAN(сенсоры)
-=: Если вам помогло моё сообщение, нажмите кнопку "Поблагодарить за сообщение автора: Vovix" (кнопка Спасибо) справа! :=-
Windows 7(PHP 7.2) + Raspberry Pi(освещение на 1-Wire) + MP751(управление) + ESP8266(сенсоры) + LAN(сенсоры)
-=: Если вам помогло моё сообщение, нажмите кнопку "Поблагодарить за сообщение автора: Vovix" (кнопка Спасибо) справа! :=-