Помогите с кодом (с логикой) пожалуйста

Использование системы в различных ситуациях, вопросы программирования сценариев.

Модератор: immortal

Chainik
Сообщения: 1462
Зарегистрирован: Вс янв 10, 2016 11:05 am
Благодарил (а): 260 раз
Поблагодарили: 454 раза

Re: Помогите с кодом (с логикой) пожалуйста

Сообщение Chainik » Вт май 04, 2021 10:36 pm

Я тоже считаю, что основной целевой параметр -- температура в помещении. Однако управлять отоплением по температуре на улице тоже можно. Ведь не зря же к большинству котлов можно подключить внешний уличный датчик температуры.

Вот набросал в фотошопе из того, что попалось под руку. Сильно приблизительно, но надо с чего-то начинать.
изображение_2021-05-04_221853.png
изображение_2021-05-04_221853.png (12.41 КБ) 1707 просмотров
Коротенько объясню идею.
Непосредственно поддержанием целевой температуры будет заниматься контроллер. Мы со стороны сервера будем давать ему "ценные указания". Так будет надежнее с точки зрения отказоустойчивости.

Теперь по поводу кнопок-индикаторов. Большая кнопка сверху будет служить индикатором того, включено отопление или нет. Если хоть один контур активен, то она будет активна. Нажатие по этой кнопке будет выключать все отопление сразу. Можно также сделать, чтобы нажатие при выключенном отоплении активизировало сразу все контуры.
Дальше, понятно, температура на улице и температура в каком-то помещении (выбранном за ориентир температуры в доме).
Затем идет ряд кнопок по управлению той или иной веткой. Таких рядов будет несколько (по числу веток отопления).
Первая кнопка активирует/деактивирует данный контур.
Вторая (в виде руки) -- переключатель между ручным и автоматическим режимом. Ведь потом мы обязательно дорастем до автоматики и "тонких настроек" )) Под автоматикой я в данном случае понимаю автоматическое изменение сервером целевой температуры в зависимости от разных условий и значимых параметров.
Третья -- кнопка-индикатор, показывающая текущее состояние насоса на контуре (включен/выключен), а при нажатии происходит "ручное" включение/выключение насоса.
Дальше кнопки "+/-", которыми мы будем регулировать целевую температуру в контуре. В вашем случае это температура обратки. Между кнопками, собственно, регулируемая температура.
Затем фактическая температура в контуре.

Быстро не обещаю, т.к. отвлекает работа и куча неотложных дел...
John
Сообщения: 38
Зарегистрирован: Пн ноя 10, 2014 1:52 pm
Благодарил (а): 12 раз
Поблагодарили: 0

Re: Помогите с кодом (с логикой) пожалуйста

Сообщение John » Вт май 04, 2021 10:55 pm

Огромное спасибо!

Все прекрасно, только еще можно добавить гистерезис на температуру обратки.
Chainik
Сообщения: 1462
Зарегистрирован: Вс янв 10, 2016 11:05 am
Благодарил (а): 260 раз
Поблагодарили: 454 раза

Re: Помогите с кодом (с логикой) пожалуйста

Сообщение Chainik » Ср май 05, 2021 9:27 am

Пока не за что благодарить.
А гистерезисом у нас будет заведовать контроллер. На порту, куда у вас подключен висящий на контуре температурный датчик, выставляете
Mode -- "<>";
Val -- нужную целевую температуру обратки в контуре;
Hst -- значение гистерезиса (например, 1.5). Тут вам виднее, какое значение лучше выбрать в зависимости от средней динамики изменения температуры в контуре при изменении состояния насоса;
Act -- "7:4" (например). "7" -- это номер выхода, на котором висит насос. Команда "4" означает, что когда температура будет меньше Val-Hst, насос включится, а когда больше Val+Hst -- выключится.
Таким образом рутинной операцией поддержания заданной температуры в контуре будет заведовать MegaD без привлечения сервера. Это будет надежнее.

Со стороны сервера будут поступать лишь 2 команды, которые будут изменять значение "Val" без перезагрузки контроллера: включить термостат

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

file_get_contents("http://192.168.0.14/sec/?pt=30&misc=45");
выключить термостат

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

file_get_contents("http://192.168.0.14/sec/?pt=30&misc=5");
В последнем случае мы задаем нереально низкую целевую температуру, при которой насос и не подумает включаться.

А какие модели температурных датчиков вы применяете? DS18B20?
И к каким портам они подключены (порт и контур отопления, с которым связан датчик)?
Лучше даже полную цепочку, чтобы была ясность:
№ порта темп.датчика --- № порта релейного выхода, к которому подключен насос --- контур отопления.
Ну и адрес контроллера в вашей локальной сети, чтобы вам меньше нужно было править в коде руками (192.168.ххх.ххх).
John
Сообщения: 38
Зарегистрирован: Пн ноя 10, 2014 1:52 pm
Благодарил (а): 12 раз
Поблагодарили: 0

Re: Помогите с кодом (с логикой) пожалуйста

Сообщение John » Ср май 05, 2021 10:51 am

Добрый день!

Температурные датчики DS18B20
Порты:
1. Насос 1 эт. - 8, датчик - 31
2. Насос 2 эт. - 7, датчик - 30
3. Насос теплого пола - 9, датчик - 32
Адрес контроллера 192.168.0.211, пароль стандартный
Chainik
Сообщения: 1462
Зарегистрирован: Вс янв 10, 2016 11:05 am
Благодарил (а): 260 раз
Поблагодарили: 454 раза

Re: Помогите с кодом (с логикой) пожалуйста

Сообщение Chainik » Ср май 05, 2021 11:27 am

Отлично. Значит выбранная схема пройдет (т.к. функцию "удаленный термостат" поддерживает только DS18B20).

Разбираемся с датчиками.

Все датчики, которые подключены к цифровым портам, я предлагаю поместить в отдельный класс. Назовем его, к примеру, "Sensors". (Для всех датчиков, подключаемых к стандартным портам, будем создавать свои отдельные классы).
На каждый измеряемый датчиком параметр в классе будет создаваться отдельный объект. Ведь есть датчики, которые изменяют сразу несколько параметров. Наименования объектов могут быть любые, но я бы выбрал что-то стандартизированное и отражающее смысл измеряемого параметра:
SensorTemp_01
SensorTemp_02
SensorTemp_03
...
SensorHum_01
SensorHum_02...
У каждого объекта будет отдельный код опроса, который мы запишем в код ОБЪЕКТА.

Добавим в класс свойства:
Value -- текущее значение (свойство без истории);
ValueSaved -- сохраненное значение (свойство с историей);
DebMessage -- некорректное значение (свойство без истории).
Добавляем в класс метод "getValue".
Добавляем для объекта "SensorTemp_01" код метода:

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

//Модель датчика
//DS18B20
//Обозначение провода, к которому подключен датчик
//
//Комментарий: температурный датчик на обратке радиаторного контура 1-го этажа
//Запрашиваемый параметр: температура

//Исключение датчика из опроса (Disabled = 1)
$Disabled = 0;
if ($Disabled == 1) return;

//Параметры работы с полученными значениями
//Периодичность опроса датчика в минутах
$FrequencyPolling = 1;
//Периодичность сохранения значения в историю в минутах (не должна быть меньше периодичности опроса)
$FrequencySaving = 5;
//Минимально допустимое значение
$MinimumAllowedValue = 1;
//Максимально допустимое значение
$MaximumAllowedValue = 84;
//Максимальное количество повторных попыток опроса в случае некорректности данных
$MaximumAllowedRePolling = 5;
//Обработка полученного значения (удаление лишнего текста, например)
$Processing = 'explode(":",$Value); $Value = $Value[1]';

//Параметры доступа к контроллеру
$ipAddress = "192.168.0.211";
$Password = "sec";
//Порт для получения данных
$Port = 31;

//Запрос
//Общая часть запроса
$RequestCommon = "http://".$ipAddress."/".$Password."/?pt=".$Port;
//Специальная часть запроса
$RequestSpecial = "&cmd=get";
//Запрос полный
$Request = $RequestCommon.$RequestSpecial;

//Получение значения с датчика
//Проверка периодичности опроса
$m=date('i',time());
if ($m%$FrequencyPolling == 0) {
//Запрос значения
$i = 0;
RequestValue:
$Value = file_get_contents($Request);
//Обработка значения
if ($Processing !="") {
eval('$Value = '.$Processing.';');
}

//say("OLD=".$this->getProperty('Value', $params['OLD_VALUE']));
//say($Value);

//Проверка значения на корректность
if ($Value >= $MinimumAllowedValue && $Value <= $MaximumAllowedValue) {
$this->setProperty('Value', $Value);
//Проверка периодичности записи значений в историю
if ($m%$FrequencySaving == 0) $this->setProperty('ValueSaved', $Value);
} else {
//Подсчет количества попыток повторного опроса
$i++;
if ($i <= $MaximumAllowedRePolling) {
//Пауза перед повторной попыткой опроса
sleep(2);
//Повторный опрос
Goto RequestValue;
} 
//Запись сообщения в свойство для последующей отладки
$this->setProperty('DebMessage', $Value);
}
}
По остальным датчикам то же самое, только в коде надо поправить комментарии, чтобы потом не перепутать, за что отвечает этот датчик и указать соответствующий порт опроса в строке "$Port = 31;". Для второго датчика это будет "$Port = 30;"

Можно было бы, конечно, обойтись парой строчек, но хочется сделать более-менее универсальный вариант.
Смысл в следующем. Мы "развязываем" текущее значение и то значение, которое должно быть записано в историю. Дело в том, что актуальное значение с датчика мы можем захотеть знать раз 10 секунд, а вот в историю записывать можем раз в полчаса. Поэтому мы не будем писать значение в историю, каждый раз, когда опрашиваем датчик. Все эти временнЫе параметры настроим в коде опроса конкретного датчика.

Напишем сценарий для запуска опроса датчиков, подключенных к цифровым портам. Пусть называется "SensorsPolling". Каждая строчка сценария будет запускать команду на опрос отдельного датчика/параметра.

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

//Скрипт запуска кода опроса цифровых датчиков
callMethodSafe('SensorTemp_01.getValue');
//callMethodSafe('SensorTemp_02.getValue');
//callMethodSafe('SensorTemp_03.getValue');
Строчки, по которым код у вас еще не настроен, я пока закомментировал. Как настроите, раскомментируете их.
По мере добавления цифровых датчиков для опроса и настройки кода сюда будут добавляться строчки для организации периодического опроса.

Будем запускать опрос датчиков из onNewMinute. Просто добавим туда строчку:

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

runScriptSafe('SensorsPolling');
Теперь в свойствах Value и ValueSaved должны появляться значения.
Можете добавить для аналитики домашнюю страницу и вывести графики с датчиков туда. Если никогда этого раньше не делали, я подскажу, там все очень просто.

Дальше будем разбираться с насосами. Там, с одной стороны проще, но надо будет чуть-чуть понастраивать в модуле "MegaD".
За это сообщение автора Chainik поблагодарил:
John (Ср май 05, 2021 6:06 pm)
Рейтинг: 1.16%
Chainik
Сообщения: 1462
Зарегистрирован: Вс янв 10, 2016 11:05 am
Благодарил (а): 260 раз
Поблагодарили: 454 раза

Re: Помогите с кодом (с логикой) пожалуйста

Сообщение Chainik » Ср май 05, 2021 2:46 pm

Разбираемся с насосами.

Создадим для них отдельный класс. Пусть называется "PumpsHeat".
Добавим в класс свойство "Status". У свойства включим историю (допустим, на 999 дней). Потом можно будет посчитать общее время работы любого насоса за произвольный период. Да и на график состояние насоса будет полезно вывести, особенно при настройке системы отопления.
Только надо не забыть в модуле Optimizer выключить по данному свойству оптимизацию значений.

Добавим в класс методы:
turnOn
turnOff
switch
getStatus -- выставляет значение свойства "Status" при произвольном запросе.
setStatus -- будет выставлять значение свойства "Status" при самостоятельном (без внешней команды) переключении насоса контроллером.

Добавим в класс объекты насосов "PumpHeat_01", "PumpHeat_02", "PumpHeat_03" ... .

Все коды методов пропишем в коды ОБЪЕКТОВ, кроме метода "setStatus" (его запишем в метод класса).
Для "PumpHeat_01":
Код метода turnOn

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

//Циркуляционный насос радиаторного контура 1-го этажа
//Обозначение провода, к которому подключен насос
//

//Параметры доступа к контроллеру
$ipAddress = "192.168.0.211";
$Password = "sec";
//Порт, к которому подключен насос
$Port = 8;

//Команда на включение
file_get_contents("http://".$ipAddress."/".$Password."/?cmd=".$Port.":1");
//Запись значения в свойство "Status"
$this->setProperty('Status', 1);
Код метода turnOff

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

//Циркуляционный насос радиаторного контура 1-го этажа
//Обозначение провода, к которому подключен насос
//

//Параметры доступа к контроллеру
$ipAddress = "192.168.0.211";
$Password = "sec";
//Порт, к которому подключен насос
$Port = 8;

//Команда на выключение
file_get_contents("http://".$ipAddress."/".$Password."/?cmd=".$Port.":0");
//Запись значения в свойство "Status"
$this->setProperty('Status', 0);
Код метода switch

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

//Циркуляционный насос радиаторного контура 1-го этажа
//Обозначение провода, к которому подключен насос
//

//Параметры доступа к контроллеру
$ipAddress = "192.168.0.211";
$Password = "sec";
//Порт, к которому подключен насос
$Port = 8;

//Узнаем состояние насоса
$State = file_get_contents("http://".$ipAddress."/".$Password."/?pt=".$Port."&cmd=get");
//Команда на переключение
if ($State == "ON") {
  $this->callMethod('turnOff');
} else {
  $this->callMethod('turnOn');
}
Код метода getStatus

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

//Циркуляционный насос радиаторного контура 1-го этажа
//Обозначение провода, к которому подключен насос
//

//Параметры доступа к контроллеру
$ipAddress = "192.168.0.211";
$Password = "sec";
//Порт, к которому подключен насос
$Port = 8;

//Узнаем состояние насоса
$State = file_get_contents("http://".$ipAddress."/".$Password."/?pt=".$Port."&cmd=get");
//Команда на переключение
if ($State == "ON") {
  $this->setProperty('Status', 1);
} else {
  $this->setProperty('Status', 0);
}
Код метода setStatus (запишем в метод КЛАССА)

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

//Метод выставляет значение свойства "Status" при самостоятельном (без внешней команды) переключении насоса контроллером
if(isset($_GET['v'])) {
if ($_GET['v'] == 1) {
  $this->setProperty('Status', 1);
} else {
  $this->setProperty('Status', 0);
}
}
Теперь надо в модуле "MegaD" выполнить настройку выхода, к которому подключен насос, чтобы при самостоятельном переключении порта контроллером у нас изменялось свойство "Status" соответствующего насоса. Для этого на вкладке "Данные" надо настроить выход аналогично тому, как это сделано здесь (https://ab-log.ru/forum/viewtopic.php?f ... &start=852) в пункте 6.
Т.е. выставляем по объекту насоса метод "setStatus".

В методах объектов по остальным насосам пропишите то же самое, только комментарий поправьте в начале и строчку с номером выхода, куда подключен соответствующий насос.

Если что-то "не взлетит", не волнуйтесь, это вопросы отладки. Пишу "с колес", так что не все баги могу сразу заметить.

Ну теперь сделаем перерыв, т.к. начинаются более творческие вещи с интерфейсом и объектами контуров.

А благодарить, в т.ч. финансово, надо ув.skysilver (https://connect.smartliving.ru/tasks/748.html) за то, что взялся за исправление багов модуля "MegaD". Так что ставьте его доработанную версию модуля "MegaD" (https://mjdm.ru/forum/viewtopic.php?f=5 ... start=1365).
За это сообщение автора Chainik поблагодарил:
John (Ср май 05, 2021 6:06 pm)
Рейтинг: 1.16%
John
Сообщения: 38
Зарегистрирован: Пн ноя 10, 2014 1:52 pm
Благодарил (а): 12 раз
Поблагодарили: 0

Re: Помогите с кодом (с логикой) пожалуйста

Сообщение John » Ср май 05, 2021 6:00 pm

Большое спасибо!

Температура обновляется, график рисуется.
По насосам все прописал ))))))
Chainik
Сообщения: 1462
Зарегистрирован: Вс янв 10, 2016 11:05 am
Благодарил (а): 260 раз
Поблагодарили: 454 раза

Re: Помогите с кодом (с логикой) пожалуйста

Сообщение Chainik » Ср май 05, 2021 8:28 pm

Отлично.
Все ли работает штатно при управлении контроллером насосами в автономном режиме?

Допишите, пожалуйста, сопоставление объектов портам Меги (чтобы мне ничего не перепутать).
1. Насос 1 эт. - 8 (PumpHeat_01), датчик - 31 (SensorTemp_01)
2. Насос 2 эт. - 7 (), датчик - 30 ()
3. Насос теплого пола - 9 (), датчик - 32 ()
John
Сообщения: 38
Зарегистрирован: Пн ноя 10, 2014 1:52 pm
Благодарил (а): 12 раз
Поблагодарили: 0

Re: Помогите с кодом (с логикой) пожалуйста

Сообщение John » Ср май 05, 2021 9:30 pm

С автономного режима я начинал, там все работает штатно.

1. Насос 1 эт. - 8 (PumpHeat_01), датчик - 31 (SensorTemp_01)
2. Насос 2 эт. - 7 (PumpHeat_02), датчик - 30 (SensorTemp_02)
3. Насос теплого пола - 9 (PumpHeat_03), датчик - 32 (SensorTemp_03)
Chainik
Сообщения: 1462
Зарегистрирован: Вс янв 10, 2016 11:05 am
Благодарил (а): 260 раз
Поблагодарили: 454 раза

Re: Помогите с кодом (с логикой) пожалуйста

Сообщение Chainik » Чт май 06, 2021 8:49 am

Понятно.
А сейчас после настройки выхда в модуле MegaD у вас происходит изменение свойства "Status" у объектов насосов при автономном переключении насосов Мегой?

Пока вы проверяете, я, тем временем, сделал более подходящую иконку для насосов. А то дренажный насос выглядит не совсем подходящим для системы отопления. ))
Взял вот это: https://yandex.ru/images/search?pos=111 ... ource=wiz
И после "обработки напильником" получил вот это: не работает (
PumpHeatOff.png
PumpHeatOff.png (2.6 КБ) 1641 просмотр
), работает (
PumpHeatOn.gif
PumpHeatOn.gif (185 КБ) 1641 просмотр
).
Ответить