Контроллер MY HEAT управление отопительным котлом

Модератор: immortal

Аватара пользователя
Bagir
Сообщения: 1487
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 187 раз
Поблагодарили: 338 раз

Контроллер MY HEAT управление отопительным котлом

Сообщение Bagir » Чт дек 10, 2020 12:32 pm

Изображение
  • Статус подключения: Подключено
  • Категория: Контроллер
  • Фирма: MY HEAT
  • Модель: MY HEAT SMART, MY HEAT PRO
  • Название: Контроллер управления отопительными приборами
  • Описание: Контроллер MY HEAT SMART предназначен для управления отопительным котлом по цифровым шинам и в режиме термостата, бойлером косвенного нагрева, насосом, 3-х либо 2-х ходовым клапаном, предоставляет возможность регулировать температурный режим до трех сред отопления включительно. Осуществляет управление типовыми системами отопления в квартирах с индивидуальным отоплением и небольших частных домовладениях.
  • Ссылка на сайт каталога производителя: myheat.net
  • Тип питания: 12V-
  • Магазин:myheat.net
    • Приблизительная цена: 11900 руб (10.12.2020)
  • Достоинства: Готовый модуль. Поддержка сразу нескольких цифровых шин в одном контроллере: Opentherm, EBUS, Navien, Arderia, LPB. Очень гибкая и простая настройка. Приложение для телефона. API для интеграции в системы умных домов.
  • Недостатки: не выявлены
Вложения
Thermostat.txt
ver 1.0
(55.03 КБ) 54 скачивания
Описание API.pdf
(167.04 КБ) 49 скачиваний
Последний раз редактировалось Bagir Чт дек 24, 2020 9:46 pm, всего редактировалось 4 раза.
За это сообщение автора Bagir поблагодарил:
directman66 (Вт мар 02, 2021 2:09 pm)
Рейтинг: 1.18%
Windows 7, HTTP, MegaD, Z-Wave, 1-Wire
Аватара пользователя
Bagir
Сообщения: 1487
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 187 раз
Поблагодарили: 338 раз

Описание структуры класса Thermostat

Сообщение Bagir » Чт дек 10, 2020 12:32 pm

Контроллер полностью самостоятелен. Может управлять температурой подачи котла по погодозависимой кривой и разным режимам работы. При подключении датчиков температуры помещения, они тоже могут влиять на температуру подачи. То есть будет не просто включение и выключение котла, а подбор темрературы подачи для снижения количества отключений и получения заданной t помещения.

А теперь, что интересно именно для нас: у контроллера есть простые API. То есть мы можем получать состояние нашей системы отопления, и задавать нужную температуру подачи. У многих из нас уже есть алгоритмы для расчета целевой температуры системы отопления. Теперь вопрос, как сообщить котлу какую от него температуру мы хотим получить, полностью решен. От сюда у нас есть два пути интеграции контроллера в нашу систему.

Способ 1. Алиса будет полностью управлять котлом. Мы сами рассчитываем нужную температуру подачи, исходя из собственных решений. Температура на улице, ветер, температура дома, режим день/ночь, режим экономии, дома/на работе/в отпуске, и т.д. У меня это делает класс Thermostat. В нем объекты двух газовых котлов и двух электрических котлов. А так же объект смесительного узла для теплых полов.
Уже реализовано:
- Методы turnOn и turnOff для включения и отключения котла, с таймерами минимальной работы/паузы, гистерезисом и суточным термостатом. Я люблю ночью сделать по прохладнее. Суточная температура задана в свойстве объекта одной цифрой, либо последовательностью из 24 цифр. Изменяя свойство можно просто сделать недельный термостат и режимы дома/на работе для экономии ресурсов.
- Метод setTemperature из которого можно сообщить котлу нужную температуру подачи. Тут нам и нужны api контроллера MyHeat. Ранее для этого я обманывал уличный датчик температуры, чтобы добиться от котла нужной t подачи. Способ рабочий, но весьма грубый. При изменении котел часто отключался, т.к. новая целевая температура могла быть сильно меньше текущей, и горелка котла не успевала модулировать мощность в таком диапазоне. Это мне сильно не нравилось. С контроллером я изменяю температуру плавно, и котел лишний раз не отключается.
- Виджет для меню. Теперь на терминалах в доме можно увидеть все параметры работы котла и состояние системы отопления. У контроллера есть своё приложение, и вы всегда будите в курсе о состоянии своего отопителя, даже если ваша Алиса открывается только в локальной сети. Это очень полезно, да и просто не заменимо при поездках в отпуск.
- Метод positionServo позволяет управлять положением сервопривода для контроля температуры радиаторов и теплых полов. Используя два реле, сервопривод управляет трехходовым смесительным клапаном. Кстати, контроллер это тоже умеет делать.

Способ 2. Если полное управление отоплением в Алисе не реализовано, то у Вас по любому есть данные о температурах в комнатах. Если мы сообщим контроллеру эти данные, то нам не придется монтировать дополнительные термодатчики. Что в случае законченного ремонта сделать не так просто. На этот момент у контроллера есть модуль расширения для работы с беспроводными датчиками. Но для нас больший интерес представляет интеграция контроллера в нашу систему, где уже всё и так есть. API для второго варианта пока что в разработке, но я уверен, что в скором времени они тоже будут.

Вернемся к первому варианту. Вот план схема, как работают методы моего класса Thermostat
План.jpg
План.jpg (49.87 КБ) 1632 просмотра
Сейчас я дописываю в коде комментарии чтобы было проще разобраться, и скоро выложу этот класс тут. Класс работает уже более года, и заслужил лимит доверия, по крайней мере с моей стороны. Но с появлением контроллера MyHeat, я внес некоторые корректировки, чтобы задействовать все возможности контроллера. А так же подкорректировал разные коэффициенты расчета температур. Ранее, при грубом рулении котлом, в них не было особой необходимости, т.к. я не имел возможность изменять t подачи котла на 1 градус, а только грубо ступенчато.
На следующий год у меня запланирован бассейн. Так что методы класса будут добавлены. Контроллер и сам может организовать подогрев бассейна, и я уже это делал это на объекте, но если мы хотим рулить всем сами, то без управления t подачи котла просто не обойтись.
Последний раз редактировалось Bagir Сб дек 12, 2020 12:38 am, всего редактировалось 1 раз.
За это сообщение автора Bagir поблагодарили (всего 3):
tarasfrompir (Пт дек 11, 2020 8:19 am) • Chainik (Пт дек 11, 2020 11:48 pm) • directman66 (Вт мар 02, 2021 2:11 pm)
Рейтинг: 3.53%
Windows 7, HTTP, MegaD, Z-Wave, 1-Wire
Аватара пользователя
Bagir
Сообщения: 1487
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 187 раз
Поблагодарили: 338 раз

Описание методов класса

Сообщение Bagir » Пт дек 11, 2020 11:11 pm

Теперь давайте разбираться, что делают эти методы, да и вообще что нужно рассчитать для полного управления системой отопления.

Для начала нужно периодически рассчитывать среднюю (или минимальную, тут кому как интересно) температуру всех комнат для общих отопителей. Например, если в системе котел работает на несколько комнат, то для расчета температуры подачи нам нужно знать целевую температуру воздуха. Если зонного регулирования в комнатах нет, то лучше рассчитать среднюю температуру комнат, если есть, то нужно обязательно прогреть самую холодную, а остальные ограничат потребление тепла сами. Тек же для работы дневного термостата, нужно периодически пересчитывать целевую температуру воздуха. Я добавил в класс Timer отдельный объект ClockChimeClimate. В нем каждые 5 минут происходит вызов сценария tempHomeChanges. Использование сценария оправдано ещё и вызовом его из объектов класса Rooms при изменении текущей температуры в любой комнате.
класс Timer объект.метод ClockChimeClimate.onNewMinuteПоказать

Код: Выделить всё

$m=date('i',time());

// Расчет средней температуры жилых комнат
if (!($m%5)) { 
 runScript('tempHomeChanges');
}
 
// Расчет целевой температуры воздуха всех объектов класса  
if (!($m%5)) {
 // запуск методов airCalculate
 $objects=getObjectsByClass('Thermostat');
 foreach($objects as $obj) {
   $obj=getObject($obj['TITLE']);
   $obj->callMethod('airCalculate');
 }
}
сценарий tempHomeChangesПоказать

Код: Выделить всё

/*  вычисляет среднюю температуру жилых комнат
	для передачи её объектам термостатов котлов
    которые работают на всю систему отопления.
*/

$check=array('OfficeRoom','Bedroom','Livingroom','HallArea','KitchenArea');

$t_avg=0;   //средняя температура
$r_count=0; //количество принятых комнат

foreach($check as $r) {
 $prop_id=getValueIdByName($r, 'Temperature');
 $arr_s = SQLSelectOne("SELECT UNIX_TIMESTAMP(UPDATED) as UPDATED, VALUE FROM `pvalues` WHERE ID=$prop_id");

 if (time()-$arr_s['UPDATED'] < 6*60*60) {
  echo 'температура '.gg("$r.inRoomText").' '.$arr_s['VALUE'].'<br>';
  $r_count++;
  $t_avg=$t_avg+$arr_s['VALUE'];
 } else {
  echo 'данные о температуре '.gg("$r.inRoomText").' не актуальны <br>';
 }
}

if (!$r_count) {
 echo 'Данные не получены. Взять среднее по последним измерениям <br>';
 foreach($check as $r) {
  $r_count++;
  $t_avg=$t_avg+gg("$r.Temperature");
 }
}

$t_avg=round($t_avg/$r_count, 1);
echo "Средняя температура в жилых комнатах $t_avg <br>";

// передать данные в объект термостат
// температуру следует передавать и в объекты других термостатов, котлы которых работают на всю систему
// sg('ts_avghome.status',$t_avg);
sg('thrm_alpha.airCurrentTemp', $t_avg);
sg('thrm_beta.airCurrentTemp', $t_avg);

Далее идет перебор всех объектов класса Thermostat для выполнение методов airCalculate. В свойстве airRequiredTemp будет текущая целевая температура. Но любая система имеет инерцию. Это время, которое нам требуется на прогрев, и время на остывание. Допустим мы хотим понизить температуру ночью на 1 градус, а утром опять её увеличить. После того, как мы убавим, или даже полностью отключим отопитель, пройдет какое то время, прежде чем комната начнет остывать. Так же и при нагреве. Это и есть инерционность системы. Для каждого объекта это свойство индивидуально, и подбирается опытным путём по графикам. Метод airCalculate запишет свойство airShiftTemp в котором будет целевая температура комнаты с учетом инерции системы, чтобы успеть ее достичь.
класс Thermostat метод airCalculateПоказать

Код: Выделить всё

$m=date('i',time());
/*  Расчет целевой температуры воздуха в зависимости от времени суток

    В результате записывается свойство с историей airRequiredTemp 
    для построения графика и контроля достижения заданной температуры;
    и свойство без истории airShiftTemp для расчета температуры подачи 
    с учетом инерции системы.
*/
if (defined('THRM_LOG_LEVEL') && THRM_LOG_LEVEL != '') { $log_level = THRM_LOG_LEVEL; } else { $log_level = 0; }
if ($log_level>0) { $ot=$this->object_title; }
if ($log_level>1) { DebMes($ot.'.airCalculate','thrm'); }

$h=(int)date('G',time());
$m=date('i',time());

$airFunc=$this->getProperty('airFunc');

// свойство airFunc может содержать массив из 24 цифр разделенных пробелом, либо только одну цифру.
if (is_numeric($airFunc)) {
  $t_desire = $airFunc;
  // логи
  if ($log_level>1) { DebMes("$ot Свойство airFunc задано числом $t_desire",'thrm'); }

} else {
  // логи
  if ($log_level>1) { DebMes("$ot Свойство airFunc задано массивом",'thrm'); }
  // Преобразовать строку в массив
  $arrTemp=explode(' ', $airFunc);
  
  // Проверить корректность массива температур
  if (count($arrTemp)<>24) {
    if ($log_level>0) { DebMes("$ot ИСКЛЮЧЕНИЕ в методе airCalculate объекта ".$this->object_title.' не корректный массив в свойстве airFunc','thrm'); }
    say("$ot Исключение в методе airCalculate объекта ".$this->object_title);
    return;
  }

  // Получить значение температуры текущего часа
  $t_desire=$arrTemp[$h];

  // следующий элемент массива
  $hn=$h+1;
  if ($hn>23) {$hn-=24;}

  // пропорционально изменить на разницу значения следующего часа
  $t_desire+=($arrTemp[$hn]-$arrTemp[$h])*$m/60;
  $t_desire=round($t_desire, 1);

  // логи
  if ($log_level>1) { 
    DebMes("$ot Установленная температура текущего часа $arrTemp[$h]",'thrm');
    DebMes("$ot Установленная температура следующего часа $arrTemp[$hn]",'thrm');
  }
} 

// логи
if ($log_level>0) {
  DebMes("$ot Требуемая температура $t_desire",'thrm');
}

// airRequiredTemp используется в основном для построения графиков
// и показа желаемого значения температуры на элементах термостатов
$this->setProperty('airRequiredTemp', $t_desire);


// пересчитать со сдвигом значение $t_desire если $airFunc не число
// иначе $t_desire останется равным числу в $airFunc
if (!is_numeric($airFunc)) {
  // Смотреть в будущее чтобы успеть по причине инерционности системы
  $h+=$this->getProperty('timeShift');
  if ($h>23) {$h-=24;}

  // Получить значение температуры текущего часа
  $t_desire=$arrTemp[$h];

  // следующий элемент массива
  $hn=$h+1;
  if ($hn>23) {$hn-=24;}

  // пропорционально изменить на разницу значения следующего часа
  $t_desire+=($arrTemp[$hn]-$arrTemp[$h])*$m/60;
  $t_desire=round($t_desire, 1);

  // логи
  if ($log_level>1) { 
    DebMes("$ot Установленная температура будущего часа $arrTemp[$h]",'thrm');
    DebMes("$ot Установленная температура следующего часа $arrTemp[$hn]",'thrm');
  }
  if ($log_level>0) {
    DebMes("$ot Требуемая будущая температура $t_desire",'thrm');
  }
}


// сохраненная будущая температура не равна расчетной будущей
// перезапись новой температуры, вызов метода расчета t подачи воды
if ($this->getProperty('airShiftTemp') <> $t_desire) { 
 $this->setProperty('airShiftTemp', $t_desire);
 $this->callMethod('waterCalculate', array('airShiftTemp'=>$t_desire));
}

Если целевая температура комнаты изменилась, будет вызван метод waterCalculate для расчета температуры подачи. Тут мы вычислим свойство waterRequiredTemp - требуемая температура подачи котла. От чего она зависит? Факторов довольно много. Самый главный это температура на улице. Чем холоднее, тем больше нужна температура подачи, чтобы компенсировать потери тепла. Я использую классический расчет по температурной кривой с коэффициентами наклона и сдвига, как в большинстве котлов. Далее очень весомый фактор будет момент приближения нашей текущей температуры к целевой. И чтобы не перегреть комнату, нужно понизить подачу. Ещё сильное влияние окажет ветер. Он просто выдувает тепло из дома, и мы должны это компенсировать. Ну и под финал - интенсивность освещённости. Когда солнце светит ярко, энергии тепловой требуется меньше, чем в очень пасмурные дни. Всем этим занимается метод pzaCalculate, результаты вычисления которого использует waterCalculate. Но одной погодозависимой автоматикой сыт не будешь, и если помещение холодное, то правильнее будет разогнать отопитель на полную мощность для начального прогрева. В итоге waterCalculate возьмет максимально допустимую температуру по ПЗА если мы опаздываем на три градуса, далее будет работать по ПЗА, а при приближении целевой на 1 градус начнет уменьшать подачу.
класс Thermostat метод waterCalculateПоказать

Код: Выделить всё

/* Расчет температуры подачи

 если фактическая температура воздуха +3 <= заблаговременной расчетной
 т.е. запаздываем на 3 градуса, то берем максимальную температуру подачи из ПЗА.

 иначе если температура воздуха +1 <= заблаговременной расчетной
 т.е. меньше заданной на 1 градус, то берем температуру по ПЗА

 иначе начинаем приближаться к заблаговременной температуре воздуха +5
*/

if (defined('THRM_LOG_LEVEL') && THRM_LOG_LEVEL != '') { $log_level = THRM_LOG_LEVEL; } else { $log_level = 0; }
if ($log_level>0) { $ot=$this->object_title; }
if ($log_level>1) { DebMes($ot.'.waterCalculate','thrm'); }

//$pzat = $this->getProperty('pzaTemp');         // температура по ПАЗ
if (isset($params['pzaTemp'])) { $pzat=$params['pzaTemp']; } else { $pzat=$this->getProperty('pzaTemp'); }
$act = $this->getProperty('airCurrentTemp');  // текущая температура воздуха (возможно выцепить без обращения к db)
//$ast  = $this->getProperty('airShiftTemp');    // заблаговременный расчет требуемой температуры воздуха	
if (isset($params['airShiftTemp'])) { $ast=$params['airShiftTemp']; } else { $ast=$this->getProperty('airShiftTemp'); }


if ($act+3<=$ast) { 
  $t='максимальная t подачи из ПЗА'; 
  $wrt=$this->callMethod('pzaCalculate', array('t'=>-30)); // Получить максимальную температуру по ПЗА;
}
elseif ($act+1<=$ast) { 
  $t='t подачи по ПЗА';
  $wrt=$pzat; 
}
else {
  $t='коррекция t при приближении';
  $wrt=$pzat;
  $wrt-=$pzat*17/100 * min(max((1-$ast+$act),0),1);
  $wrt=round($wrt);
}

if ($log_level>0) { DebMes("$ot $t $wrt",'thrm'); }

if ($this->getProperty('waterRequiredTemp') <> $wrt) {
 $this->setProperty('waterRequiredTemp', $wrt);
 // Запуск исполняющих методов
 $this->callMethod('setTemperature', array('t'=>$wrt));
 $this->callMethod('positionServo');
}

// подумать когда и при каких условиях вызывать чтобы сократить выполнение кода
$this->callMethod('workDecision');

Теперь о самом методе pzaCalculate. В нем как раз и происходит расчет температуры по ПЗА. Метод вызывается при изменении уличной температуры. Рассчитывает ПЗА и сразу вызывает waterCalculate для перерасчета подачи. Тут как раз и происходит расчет по температуре улицы, скорости ветра и освещенности. Не все коэффициенты выведены в свойства объектов. Многие из них прописаны в коде. Для точной настройки нужно подгонять их под свой дом индивидуально. В этом очень помогают графики. О них мы тоже попозже поговорим.
класс Thermostat метод pzaCalculateПоказать

Код: Выделить всё

/* Расчет требуемой температуры подачи по ПЗА
   Учитывается уличная температура, скорость ветра, яркость солнца
   Коэффициенты влияния этих факторов указаны в коде
*/
if (defined('THRM_LOG_LEVEL') && THRM_LOG_LEVEL != '') { $log_level = THRM_LOG_LEVEL; } else { $log_level = 0; }
if ($log_level>0) { $ot=$this->object_title; }
if ($log_level>1) { DebMes($ot.'.pzaCalculate','thrm'); }

// температура улица. ВНИМАНИЕ данные берутся с объекта улицы 
if (isset($params['t'])) { $t =$params['t']; } else { $t = gg('DrivewayArea.Temperature'); }

// коэффициент выбора кривой. Поднимает хвост графика. Увеличить для + в морозы
if (isset($params['k1'])) { $k1 =$params['k1']; } else { $k1 = $this->getProperty('K1'); }
// коэффициент правки всей кривой. Перемещает вверх/вниз весь график
if (isset($params['k2'])) { $k2 =$params['k2']; } else { $k2 = $this->getProperty('K2'); }
// значение по умолчанию
if (!$k1) { $k1=1.5; } 
if (!$k2) { $k2=20; }


// Рассчитать изгиб кривой 
$Tp = sqrt((20-$t)*$k1)*10;
if (!isset($params['t']) && $log_level>1) { DebMes("$ot Изгиб кривой $Tp",'thrm'); }
// При увеличении желаемой комнатной температуры на 1°C кривая традиционно смещается на 5°C:
$Tp = $Tp + ($k2-20)*5;
if (!isset($params['t']) && $log_level>1) { DebMes("$ot Смещение кривой $Tp",'thrm'); }

// Правка на ветер
// <3 Слабый  <6 Сильный  <9 Очень сильный  Иначе Шквальный
// поправку вносим от 0 до 10 м*с. Корректировка на 25%
$Tp+=$Tp*25/100 * min(max(gg('weather_now.windSpeed')/10,0),1);
if (!isset($params['t']) && $log_level>1) { DebMes("$ot Поправка на ветер $Tp",'thrm'); }

// Правка на солнце
// Освещенность наблюдается от 0 до 600 пунктов. Понижать t будет от 200 до 600 
// Корректировка на 10%
$Tp-=$Tp*10/100 * min(max((gg('DrivewayArea.Luminiscence')-200)/400,0),1);
if (!isset($params['t']) && $log_level>1) { DebMes("$ot Поправка на солнце $Tp",'thrm'); }

// округлить, ограничить и записать 
$Tp = round($Tp);
$Tp = min($Tp,85);
$Tp = max($Tp,20);
if (!isset($params['t']) && $log_level>0) { DebMes("$ot Итоговая t по ПЗА $Tp",'thrm'); }

// при передаче параметра t вернуть ответ для графиков. Иначе запуск метода 
if (isset($params['t'])) {
 if ($log_level>0) { DebMes("$ot На запрос уличной $t отправлен ответ $Tp",'thrm'); }
 return($Tp);
} else {
 $this->setProperty('pzaTemp', $Tp);
 $this->callMethod('waterCalculate', array('pzaTemp'=>$Tp));
}

Далее по цепочке waterCalculate вызывает методы setTemperature и positionServo. В общем коде этих методов нет ничего интересного. Тут мы прописывает код в методе объектов. Например для объекта котла, подключенного через контроллер MyHeat в методе setTemperature будет отправка температуры подачи котлу, по средствам API контроллера. Код я выложу в самом конце. Сейчас мы продолжим обсуждать работу класса. Метод positionServo используется для объектов смесительных узлов. В нем мы поворачиваем трехходовой кран в нужную сторону для получения нужной t подачи. То есть у котла мы управляем температурой подачи, а у смесительного узла крутим сервопривод.


waterCalculate вызывает ещё один метод. Это WorkDecision. Он примет решение о полном включении или отключении отопителя, или циркуляционного насоса смесительного узла. Будут вызваны методы turnOn и turnOff. их коде устанавливаются таймеры минимальной работы и паузы. Без них, в ситуации нахождения на грани равенства температур, котел может постоянно включаться и выключаться. Тут работает правило, что если включились, то должны работать какое то время. А если выключились, то несколько минут ждем. Это убирает тактование. Очень полезно для электрических котлов, да и для всех в целом.
класс Thermostat метод workDecisionПоказать

Код: Выделить всё

/* Принимает решение о работе котла или насоса, на основе текущей и требуемой температуры воздуха
   Запускается из метода waterCalculate, а так же может быть вызван при необходимости проверки решения 
   о работе котла из других элементов системы
*/
if (defined('THRM_LOG_LEVEL') && THRM_LOG_LEVEL != '') { $log_level = THRM_LOG_LEVEL; } else { $log_level = 0; }
if ($log_level>0) { $ot=$this->object_title; }
if ($log_level>1) { DebMes($ot.'.workDecision','thrm'); }

// Не выполнять логику если установлен ручной режим
if (!$this->getProperty('auto')) { 
  if ($log_level>0) { DebMes("$ot Выполнение запрещено. auto режим не выбран",'thrm'); }
  return;
}

// Сбор данных
$s = $this->getProperty('status');
$t = $this->getProperty('Title');
$n = $this->object_title;
$t_desire = $this->getProperty('airShiftTemp');

// гистерезис и значение по умолчанию  
$hyst = $this->getProperty('hysteresis');
if (!is_numeric($hyst)) {$hyst = 0.2;}

// предельные температуры подачи и значения по умолчанию  
$waterMaxTemp = $this->getProperty('waterMaxTemp');
$waterMinTemp = $this->getProperty('waterMinTemp');
if (!is_numeric($waterMaxTemp)) {$waterMaxTemp = 75;}
if (!is_numeric($waterMinTemp)) {$waterMinTemp = 10;}

// Текущая температура подачи. Если данных нет, то принять за 40 
$waterCurrentTemp = $this->getProperty('waterCurrentTemp');
if (!is_numeric($waterCurrentTemp)) {$waterCurrentTemp = 40;}



// Получить значение метода, запрещающего работу
$mayBanOn = intval($this->callmethod('mayBanOn'));
// При запрете метод вернет 2. Преобразовать ответ в true / false
if ($log_level>1) { DebMes("$ot метод mayBanOn вернул $mayBanOn",'thrm'); }
if ($mayBanOn == 2) {$mayBanOn = true;} else {$mayBanOn = false;}


if ($s) { // *** котел сейчас работает, проверка решения на Отключение 
  // текущая t воздуха >= заблаговременной требуемой + гистерезис
  if ($this->getProperty('airCurrentTemp') >= $t_desire + $hyst || $mayBanOn || $waterCurrentTemp > $waterMaxTemp) {
    // Если существует таймер 
    if (timeOutExists($n.'_work') && !$mayBanOn && $waterCurrentTemp < $waterMaxTemp) {
      if ($log_level>0) { DebMes("$ot Обеспечение минимального времени работы котла $t",'thrm'); }
    } else {
      $this->callMethod('turnOff');
    }
  }  
} else { // *** котел сейчас НЕ работает, проверка решения на Включение
  // текущая t воздуха <= заблаговременной требуемой - гистерезис
  if (($this->getProperty('airCurrentTemp') <= $t_desire - $hyst || $waterCurrentTemp < $waterMinTemp) && !$mayBanOn) {
    // Если существует таймер паузы
    if (timeOutExists($n.'_nowork')) {
      if ($log_level>0) { DebMes("$ot Обеспечение минимальной паузы перед включением котла $t",'thrm'); }
    } else {
      $this->callMethod('turnOn');
    }
  } 
}
класс Thermostat методы turnOn и turnOffПоказать

Код: Выделить всё

if (defined('THRM_LOG_LEVEL') && THRM_LOG_LEVEL != '') { $log_level = THRM_LOG_LEVEL; } else { $log_level = 0; }
if ($log_level>0) { $ot=$this->object_title; }
if ($log_level>1) { DebMes($ot.'.turnOff','thrm'); }

$this->setProperty('status',0);

$n = $this->object_title;

// Время минимальной работы
$mintimeoff = $this->getProperty('mintimeoff');
if ( !is_numeric($mintimeoff) ) {$mintimeoff = 20*60;}

// установить таймер паузы
setTimeOut($n.'_nowork', "debmes('Tаймер $n закончен'); cm('$n.workDecision');", $mintimeoff);

// Удалить таймер работы
clearTimeOut($n.'_work');

Код: Выделить всё

if (defined('THRM_LOG_LEVEL') && THRM_LOG_LEVEL != '') { $log_level = THRM_LOG_LEVEL; } else { $log_level = 0; }
if ($log_level>0) { $ot=$this->object_title; }
if ($log_level>1) { DebMes($ot.'.turnOn','thrm'); }

$this->setProperty('status',1);

$n = $this->object_title;

// Время минимальной работы
$mintimeon = $this->getProperty('mintimeon');
if ( !is_numeric($mintimeon)  ) {$mintimeon = 15*60;}

//установить таймер работы
setTimeOut($n.'_work', "debmes('Tаймер $n закончен'); cm('$n.workDecision');", $mintimeon);

// Удалить таймер паузы
clearTimeOut($n.'_nowork');

Для управления объектами класса можно вывести их в меню или на сцены. Код шаблона отображения покажет все необходимые элементы.
Шаблон.png
Шаблон.png (12.39 КБ) 1418 просмотров
класса Thermostat Шаблон отображенияПоказать

Код: Выделить всё

<svg width="100%" height="155px" version="1.1" xmlns="http://www.w3.org/2000/svg">

 <defs>
  <filter id="fg%.object_id%">
   <feGaussianBlur in="SourceGraphic" stdDeviation="1" />
  </filter>
  <clipPath id="cut%.object_id%"  >
    <rect x="0" y="0" rx="4" ry="4" width="60" height="35" />
  </clipPath>
 </defs>
  

 <! -- Название термостата по описанию объекта -->
 <text x="0" y="14" fill="rgb(48, 48, 48)" stroke="none" font-size="16px">%.object_description%</text>

 <! -- Текущая температура воздуха --> 
 <g transform="translate(194,25)">
  <title>Текущая температура воздуха</title>
  <rect x="0" y="1" rx="4" ry="4" width="60" height="35" fill="none" stroke="#999999" stroke-width="1" filter="url(#fg%.object_id%)" clip-path="inset(-0.2px 0px 0.2px 0px round 1.2px)"/>
  <rect x="0" y="0" rx="4" ry="4" width="60" height="35" fill="none" stroke="#dddddd" stroke-width="1"/>
  <text x="7" y="11" fill="rgb(150, 150, 150)" font-size="10px">Текущая</text>
  <text x="7" y="30" fill="rgb(48, 48, 48)" font-weight="bold" font-size="17px">%.airCurrentTemp%<tspan font-size="12px">°C</tspan></text>
 </g>

 <! -- Индикатор работы и таймеров --> 
 <g transform="translate(1,70)">
  <title>Индикатор работы и таймеров</title>
  <rect x="0" y="1" rx="4" ry="4" width="39" height="35" fill="none" stroke="#999999" stroke-width="1" filter="url(#fg%.object_id%)" clip-path="inset(-0.2px 0px 0.2px 0px round 1.2px)"/>

  <g style='display:%.status|"none;inline"%' onClick='callMethod("%.turnOff");'>
   <rect x="0" y="0" rx="4" ry="4" width="39" height="35" fill="white" stroke="#dddddd" stroke-width="1"/>
   <! -- Значок пламени -->
   <g fill="none" stroke="black" stroke-width="1.5">
    <path d="m 13,6 c 6,10 -6,10 0,20" />
    <path d="m 20,6 c 6,10 -6,10 0,20" />
    <path d="m 27,6 c 6,10 -6,10 0,20" />
    <path d="m 7,28 25,0" />
   </g>
  </g>

  <g style='display:%.status|"inline;none"%' onClick='callMethod("%.turnOn");'>
   <rect x="0" y="0" rx="4" ry="4" width="39" height="35" fill="white" stroke="#dddddd" stroke-width="1"/>
  </g>

  <! -- Рамки таймеров --> 
  <rect id="greentimer%.object_id%" x="3" y="3" rx="1" ry="1" width="33" height="29" fill="none" stroke="gold" stroke-width="4" style='display:none'/>
  <rect id="redtimer%.object_id%"   x="3" y="3" rx="1" ry="1" width="33" height="29" fill="none" stroke="red"  stroke-width="4" style='display:none'/>
 </g>

 <! -- ПЗА температура воды --> 
 <g transform="translate(52,70)">
  <title>температура по ПЗА</title>
  <rect x="0" y="1" rx="4" ry="4" width="60" height="35" fill="none" stroke="#999999" stroke-width="1" filter="url(#fg%.object_id%)" clip-path="inset(-0.2px 0px 0.2px 0px round 1.2px)"/>
  <rect x="0" y="0" rx="4" ry="4" width="60" height="35" fill="none" stroke="#dddddd" stroke-width="1"/>
  <text x="7" y="11" fill="rgb(150, 150, 150)" font-size="10px">ПЗА вода</text>
  <text x="6" y="30" fill="rgb(48, 48, 48)" font-weight="bold" font-size="17px">%.pzaTemp%<tspan font-size="13px">°C</tspan></text>
 </g>

 <! -- Расчетная температура воды --> 
 <g transform="translate(123,70)">
  <title>Расчетная температура теплоносителя</title>
  <rect x="0" y="1" rx="4" ry="4" width="60" height="35" fill="none" stroke="#999999" stroke-width="1" filter="url(#fg%.object_id%)" clip-path="inset(-0.2px 0px 0.2px 0px round 1.2px)"/>
  <rect x="0" y="0" rx="4" ry="4" width="60" height="35" fill="none" stroke="#dddddd" stroke-width="1"/>
  <text x="7" y="11" fill="rgb(150, 150, 150)" font-size="10px">Расчетная</text>
  <text x="6" y="30" fill="rgb(48, 48, 48)" font-weight="bold" font-size="17px">%.waterRequiredTemp%<tspan font-size="13px">°C</tspan></text>
 </g>

 <! -- Текущая температура воды --> 
 <g transform="translate(194,70)">
  <title>Текущая температура теплоносителя</title>
  <rect x="0" y="1" rx="4" ry="4" width="60" height="35" fill="none" stroke="#999999" stroke-width="1" filter="url(#fg%.object_id%)" clip-path="inset(-0.2px 0px 0.2px 0px round 1.2px)"/>
  <rect x="0" y="0" rx="4" ry="4" width="60" height="35" fill="none" stroke="#dddddd" stroke-width="1"/>
  <text x="7" y="11" fill="rgb(150, 150, 150)" font-size="10px">Текущая</text>
  <text x="6" y="30" fill="rgb(48, 48, 48)" font-weight="bold" font-size="17px">%.waterCurrentTemp%<tspan font-size="13px">°C</tspan></text>
 </g>

 <! -- Сообщения --> 
 <g transform="translate(78,115)">
  <title>Сообщения</title>
  <rect x="0" y="1" rx="4" ry="4" width="105" height="35" fill="none" stroke="#999999" stroke-width="1" filter="url(#fg%.object_id%)" clip-path="inset(-0.2px 0px 0.2px 0px round 1.2px)"/>
  <rect x="0" y="0" rx="4" ry="4" width="105" height="35" fill="none" stroke="#dddddd" stroke-width="1"/>
  <text x="4" y="14" fill="rgb(150, 150, 150)" font-size="10px">вкл по температуре</text>
  <text x="4" y="25" fill="rgb(150, 150, 150)" font-size="10px">уст. таймер работы</text>
 </g>

 <! -- Гистерезис --> 
 <g transform="translate(194,115)">
  <title>Отклонение вверх и вниз</title>
  <g onClick='callMethod("%.workDecision");' >
  <rect x="0" y="1" rx="4" ry="4" width="60" height="35" fill="none" stroke="#999999" stroke-width="1" filter="url(#fg%.object_id%)" clip-path="inset(-0.2px 0px 0.2px 0px round 1.2px)"/>
  <rect x="0" y="0" rx="4" ry="4" width="60" height="35" fill="none" stroke="#dddddd" stroke-width="1"/>
   <text x="4" y="11" fill="rgb(150, 150, 150)" font-size="10px">Гистерезис</text>
   <text x="6" y="30" fill="rgb(48, 48, 48)" font-weight="bold" font-size="17">%.hysteresis%<tspan font-size="13px">°C</tspan></text>
  </g>
 </g> 
 
 <! -- Авто --> 
 <g transform="translate(1,115)">
  <title>Автоматическое или ручное управление</title>
  <g style='display:%.auto|"none;block"%' onClick='ajaxSetGlobal("%.auto", 0); callMethod("%.workDecision");'>
   <rect x="0" y="1" rx="4" ry="4" width="66" height="35" fill="#2f89cd" stroke="#999999" stroke-width="1" filter="url(#fg%.object_id%)" clip-path="inset(-0.2px 0px 0.2px 0px round 1.2px)"/>
   <rect x="0" y="0" rx="4" ry="4" width="66" height="35" fill="none" stroke="#dddddd" stroke-width="1"/>                                  <! -- тонкий контур рамки по середине --> 
   <rect x="44" y="2" rx="3" ry="3" width="20" height="31" fill="#f6f6f6" stroke="#999999" stroke-width="1" filter="url(#fg%.object_id%)"/>    <! -- размытая рамка наружу и во внутрь  --> 
   <rect x="44" y="2" rx="3" ry="3" width="20" height="31" fill="#f6f6f6" stroke="#dddddd" stroke-width="1"/>                                  <! -- контур с заливкой внутри --> 
   <text x="4" y="23" fill="white" font-weight="bold" font-size="17">auto</text>
  </g>
  <g style='display:%.auto|"block;none"%' onClick='ajaxSetGlobal("%.auto", 1); callMethod("%.workDecision");'>
   <rect x="0" y="1" rx="4" ry="4" width="66" height="35" fill="#e9e9e9" stroke="#999999" stroke-width="1" filter="url(#fg%.object_id%)" clip-path="inset(-0.2px 0px 0.2px 0px round 1.2px)"/>
   <rect x="0" y="0" rx="4" ry="4" width="66" height="35" fill="none" stroke="#dddddd" stroke-width="1"/>
   <rect x="2" y="2" rx="3" ry="3" width="20" height="31" fill="#f6f6f6" stroke="#999999" stroke-width="1" filter="url(#fg%.object_id%)"/>
   <rect x="2" y="2" rx="3" ry="3" width="20" height="31" fill="#f6f6f6" stroke="#dddddd" stroke-width="1"/>
   <text x="25" y="21" fill="rgb(48, 48, 48)" font-weight="bold" font-size="11">manual</text>
  </g>
  <!-- размытая и обрезанная общая рамка -->
 </g>

 

 
 
 <! -- График расчетной температуры воздуха --> 
 <g transform="translate(1,59)" >
  <title>Расчет температуры воздуха по суточному термостату</title>
  <rect x="0" y="-33" rx="4" ry="4" width="182" height="35" fill="none" stroke="#999999" stroke-width="1" filter="url(#fg%.object_id%)" clip-path="inset(-0.2px 0px 0.2px 0px round 1.2px)"/>
  <rect x="0" y="-34" rx="4" ry="4" width="182" height="35" fill="none" stroke="#dddddd" stroke-width="1"/>
  <text x="7" y="-23" fill="rgb(150, 150, 150)" font-size="10px">Расчетная температура воздуха</text>
  <text x="129" y="-4" fill="rgb(48, 48, 48)" font-weight="bold" font-size="17px">%.airRequiredTemp%<tspan font-size="13px">°C</tspan></text>
  <g transform="rotate(270)" fill="rgb(90, 90, 90)" >
   <rect id="gr%.object_id%0" width="0" height="4" y="2" />
   <rect id="gr%.object_id%1" width="0" height="4" y="7" />
   <rect id="gr%.object_id%2" width="0" height="4" y="12" />
   <rect id="gr%.object_id%3" width="0" height="4" y="17" />
   <rect id="gr%.object_id%4" width="0" height="4" y="22" />
   <rect id="gr%.object_id%5" width="0" height="4" y="27" />
   <rect id="gr%.object_id%6" width="0" height="4" y="33" />
   <rect id="gr%.object_id%7" width="0" height="4" y="38" />
   <rect id="gr%.object_id%8" width="0" height="4" y="43" />
   <rect id="gr%.object_id%9" width="0" height="4" y="48" />
   <rect id="gr%.object_id%10" width="0" height="4" y="53" />
   <rect id="gr%.object_id%11" width="0" height="4" y="58" />
   <rect id="gr%.object_id%12" width="0" height="4" y="64" />
   <rect id="gr%.object_id%13" width="0" height="4" y="69" />
   <rect id="gr%.object_id%14" width="0" height="4" y="74" />
   <rect id="gr%.object_id%15" width="0" height="4" y="79" />
   <rect id="gr%.object_id%16" width="0" height="4" y="84" />
   <rect id="gr%.object_id%17" width="0" height="4" y="89" />
   <rect id="gr%.object_id%18" width="0" height="4" y="95" />
   <rect id="gr%.object_id%19" width="0" height="4" y="100" />
   <rect id="gr%.object_id%20" width="0" height="4" y="105" />
   <rect id="gr%.object_id%21" width="0" height="4" y="110" />
   <rect id="gr%.object_id%22" width="0" height="4" y="115" />
   <rect id="gr%.object_id%23" width="0" height="4" y="120" />
  </g>
 </g> 

</svg>


<script type="text/javascript">
  var url=ROOTHTML;

  url+='objects/?script='+encodeURIComponent('scriptTimeOutExists')+'&timername=%.object_title%_nowork';
  $.ajax({
   url: url
  }).done(function(data) { 
    if (data==0) {
     document.getElementById('redtimer%.object_id%').setAttribute('style', 'display:none');
    } else {
     document.getElementById('redtimer%.object_id%').setAttribute('style', 'display:block');
    }
  });

  url+='objects/?script='+encodeURIComponent('scriptTimeOutExists')+'&timername=%.object_title%_work';
  $.ajax({
   url: url
  }).done(function(data) { 
    if (data==0) {
     document.getElementById('greentimer%.object_id%').setAttribute('style', 'display:none');
    } else {
     document.getElementById('greentimer%.object_id%').setAttribute('style', 'display:block');
    }
  });
 
 
 // Получить значение аир функции и разбить на массив
 //var tstring = '23 23 23 23 23 23.5 24 24 24 24 23.5 23.5 23.5 23.5 23.5 23.5 23.7 24 24 24 24 24 23.5 23';
 var tstring = '%.airFunc%';
 var tarr = tstring.split(' ');

 // Дополнить массив до 24 последним элементов
 var i = tarr.length + 1;
 while (i <= 24) {
   tarr.push(tarr[tarr.length-1]);
   i++;
 }
               
 // Перебрать массив для установки графика              
 var h = new Date();
 tarr.forEach(function(item, i, temparr) {
  document.getElementById('gr%.object_id%' + i).setAttribute('width', (item - Math.max.apply(null, tarr) + 2) * 9);
  if (h.getHours() == i) {
  document.getElementById('gr%.object_id%' + i).setAttribute('fill', "gold");
  }
 });
</script>

Теперь о том, как установить, и обеспечить работу.
Убедимся, что в системе нет одноименного класса Thermostat. Импортируем класс, можно вместе с объектами моих отопителей. Будет проще разобраться. Потом удалите объекты и создадите свои. После импорта можно сразу добавить один из объектов в меню, чтобы убедиться что всё работает. Затем нужно настроить вызов методов класса. Всего будет три точки от куда запускаются методы.

1. Из метода onNewMinute каждые 5 минут происходит вызов методов airCalculate. Пример кода в самом начале. Нужно для суточного термостата. Далее методы класса будут вызываются по цепочке при необходимости.

2. При изменении температуры комнатных датчиков запускается сценарий tempHomeChanges. Он установит свойство airCurrentTemp что приведет к вызову метода waterCalculate.
Если у вас только один датчик температуры, то можно сразу писать его значение в свойство airCurrentTemp. Тогда сценарий tempHomeChanges не нужен. Сценарий только рассчитывает среднюю температуру комнат.

3. При изменении уличной температуры нужно вызвать метод pzaCalculate. Тут есть момент. В коде метода pzaCalculate есть получение свойства уличной температуры weather_now.temperature, скорости ветра weather_now.windSpeed и интенсивности освещённости DrivewayArea.Luminiscence. Замените их на свои. Если в вашей системе нет этих данных, тогда закомментируйте в методе pzaCalculate код поправки температуры подачи на эти факторы. Но без уличной температуры никак не обойтись.

Для ведения логов можно добавить в файл config.php строку Define('THRM_LOG_LEVEL', 2); Тогда все комментарии будут писаться в файл ...\cms\debmes\ГГГГ-ММ-ДД_thrm.log
0 - не писать, 1 - только основные логи, 2 - вся отладочная информация.


Ожидайте продолжение в ближайшее время! Скоро выложу класс целиком для скачивания.
А пока коротенькое резюме. Класс Thermostat может управлять отопителями по средствам их включения и выключения. Суточный термостат. Рассчитывает температуру подачи на основе ПЗА и целевой температуры дома. При подключении контроллера MyHeat может управлять отопителем по цифровой шине для поддержания целевой температуры. Управление сервоприводом смесительного узла.
Последний раз редактировалось Bagir Вс дек 13, 2020 10:08 pm, всего редактировалось 2 раза.
За это сообщение автора Bagir поблагодарили (всего 3):
timurufa86 (Пт дек 25, 2020 8:55 am) • Chainik (Вт дек 29, 2020 5:41 pm) • Nail (Вт мар 02, 2021 5:45 pm)
Рейтинг: 3.53%
Windows 7, HTTP, MegaD, Z-Wave, 1-Wire
stellhawk
Сообщения: 261
Зарегистрирован: Чт ноя 08, 2018 5:51 am
Благодарил (а): 10 раз
Поблагодарили: 81 раз

Re: Контроллер MY HEAT управление отопительным котлом

Сообщение stellhawk » Сб дек 12, 2020 8:31 am

переименуйте класс пока не поздно. иначе будут проблемы с совместимостью.
классов с таким названием целое множество.
Аватара пользователя
Bagir
Сообщения: 1487
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 187 раз
Поблагодарили: 338 раз

Re: Контроллер MY HEAT управление отопительным котлом

Сообщение Bagir » Вс дек 13, 2020 4:49 pm

stellhawk писал(а):
Сб дек 12, 2020 8:31 am
переименуйте класс
Да поздно уже. Конечно можно поправить в коде имя, но зачем? Класс полностью соответствует своему названию. Да и зачем в системе два класса с таким именем? У меня тут есть всё, от расчетов до визуального представления. Да и с ходу управлять другими термостатами этим классом всё равно не получится. Придется делать много поправок. Я намерено выложил в начале код, если кто то захочет взять себе какие то отдельные расчеты температур. Думаю, что успею завтра выложить файлы с классом. Ну а если уж у кого то получится такая ситуация, что в системе будет одноименный класс, и нужно его оставить, то переименовать можно и в файле перед импортом.
Windows 7, HTTP, MegaD, Z-Wave, 1-Wire
Аватара пользователя
Bagir
Сообщения: 1487
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 187 раз
Поблагодарили: 338 раз

Re: Контроллер MY HEAT управление отопительным котлом

Сообщение Bagir » Чт дек 24, 2020 9:56 pm

Выложил класс. Интересная эта штука. Чем дальше лезешь в расчеты температур, тем больше переделываешь. Если раньше я мог управлять котлом, можно сказать ступенями, то сейчас, с контроллером MyHeat, полная свобода. Поправил расчеты и коэффициенты. Я думаю, что можно добиться идеальной точности для любой системы отопления, подправив настройки для себя.
В начале можно просто поиграться с классом без управления реальным котлом, чтобы посмотреть на сколько отличаются расчеты.
Windows 7, HTTP, MegaD, Z-Wave, 1-Wire
directman66
Сообщения: 2801
Зарегистрирован: Пн дек 26, 2016 9:51 am
Откуда: Екатеринбург
Благодарил (а): 380 раз
Поблагодарили: 682 раза
Контактная информация:

Re: Контроллер MY HEAT управление отопительным котлом

Сообщение directman66 » Вт мар 02, 2021 2:10 pm

Может все таки подготовить модуль для установки через маркет? Из ваших наработок может получиться отличный модуль plug and play!

Совсем не понял, как подружить класс с котлом, API облачный/локальный? Где что прописать требуется?
Если вам помогло данное сообщение, не поленитесь нажать кнопку "спасибо".
CONNECT | Оборудование | Блог | Дополнения | Email | Telegram | +79122962262 WhatsApp
Аватара пользователя
Bagir
Сообщения: 1487
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 187 раз
Поблагодарили: 338 раз

Re: Контроллер MY HEAT управление отопительным котлом

Сообщение Bagir » Вс май 02, 2021 4:49 pm

directman66 писал(а):
Вт мар 02, 2021 2:10 pm
подготовить модуль для установки через маркет?
С модулями я работал, но серьёзно эту тему не изучал. Наверное по этому и делаю у себя всё на классах. Возможно в будущем перейду на модули.
directman66 писал(а):
Вт мар 02, 2021 2:10 pm
API облачный/локальный?
Увы, пока только облачный, но обещают сделать и локальный. Когда это произойдет, я конечно перейду, и покажу где что поправить.
directman66 писал(а):
Вт мар 02, 2021 2:10 pm
Совсем не понял, как подружить класс с котлом
Класс в основном занимается расчетами температур подачи по ПЗА и целевой t дома, работой с сервоприводами трехходовых клапанов, и включением отопителя. Контроллер MyHeat, или любой другой, используется для получения данных котла и установки t подачи. Код работы с контроллером есть в личном методе setTemperature.
directman66 писал(а):
Вт мар 02, 2021 2:10 pm
Где что прописать требуется?
Пожалуйста поконкретнее о чем именно речь, и я обязательно отвечу.

На сегодняшний день класс у меня отработал уже три зимы. Первый сезон конечно был пристрелочный. Второй год подбирал коэффициенты для моего дома. В эту зиму в структуре класса ничего серьезного уже не менял.
Управляет двумя ступенями электрического котла дома. Долго думал стоит ли ступени реализовывать в классе, но в итоге просто завел два разные объекта котла для первой и второй ступени.
Газовый энергонезависимый котел. Управление вкл/выкл через контакты домашнего термостата.
Газовый настенный котел. Управление через контроллер MyHeat.
Электрический котел в бане. Тоже вкл/выкл.
Windows 7, HTTP, MegaD, Z-Wave, 1-Wire
Аватара пользователя
Nail
Сообщения: 349
Зарегистрирован: Пн мар 05, 2018 7:09 am
Откуда: Самара
Благодарил (а): 153 раза
Поблагодарили: 21 раз

Re: Контроллер MY HEAT управление отопительным котлом

Сообщение Nail » Чт май 06, 2021 9:00 am

Bagir писал(а):
Вс май 02, 2021 4:49 pm
directman66 писал(а):
Вт мар 02, 2021 2:10 pm
подготовить модуль для установки через маркет?
С модулями я работал, но серьёзно эту тему не изучал. Наверное по этому и делаю у себя всё на классах. Возможно в будущем перейду на модули.
directman66 писал(а):
Вт мар 02, 2021 2:10 pm
API облачный/локальный?
Увы, пока только облачный, но обещают сделать и локальный. Когда это произойдет, я конечно перейду, и покажу где что поправить.
directman66 писал(а):
Вт мар 02, 2021 2:10 pm
Совсем не понял, как подружить класс с котлом
Класс в основном занимается расчетами температур подачи по ПЗА и целевой t дома, работой с сервоприводами трехходовых клапанов, и включением отопителя. Контроллер MyHeat, или любой другой, используется для получения данных котла и установки t подачи. Код работы с контроллером есть в личном методе setTemperature.
directman66 писал(а):
Вт мар 02, 2021 2:10 pm
Где что прописать требуется?
Пожалуйста поконкретнее о чем именно речь, и я обязательно отвечу.

На сегодняшний день класс у меня отработал уже три зимы. Первый сезон конечно был пристрелочный. Второй год подбирал коэффициенты для моего дома. В эту зиму в структуре класса ничего серьезного уже не менял.
Управляет двумя ступенями электрического котла дома. Долго думал стоит ли ступени реализовывать в классе, но в итоге просто завел два разные объекта котла для первой и второй ступени.
Газовый энергонезависимый котел. Управление вкл/выкл через контакты домашнего термостата.
Газовый настенный котел. Управление через контроллер MyHeat.
Электрический котел в бане. Тоже вкл/выкл.
Я так понимаю связанно с Opentherm? Тут игрушка появилась интересная по цене чуть выгоднее , два в одном Zigbee и Opentherm.
Не плохо бы потестить.
https://t.me/slsys/69346
Mini AMD A6 1450 Quad-core.Ubuntu Server 18.04 (64-bit). MegaD. Zigbee2mqtt+SLS ZigBee Gateway. Broadlink.
directman66
Сообщения: 2801
Зарегистрирован: Пн дек 26, 2016 9:51 am
Откуда: Екатеринбург
Благодарил (а): 380 раз
Поблагодарили: 682 раза
Контактная информация:

Re: Контроллер MY HEAT управление отопительным котлом

Сообщение directman66 » Чт май 06, 2021 5:26 pm

Эту игрушку тестируем, поддержка в мажоре будет обязательно.
Если вам помогло данное сообщение, не поленитесь нажать кнопку "спасибо".
CONNECT | Оборудование | Блог | Дополнения | Email | Telegram | +79122962262 WhatsApp
Ответить