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

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

Модератор: immortal

Chainik
Сообщения: 1463
Зарегистрирован: Вс янв 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
Сообщения: 1463
Зарегистрирован: Вс янв 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
Сообщения: 1463
Зарегистрирован: Вс янв 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
Сообщения: 1463
Зарегистрирован: Вс янв 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 КБ) 1762 просмотра
), работает (
PumpHeatOn.gif
PumpHeatOn.gif (185 КБ) 1762 просмотра
).
John
Сообщения: 38
Зарегистрирован: Пн ноя 10, 2014 1:52 pm
Благодарил (а): 12 раз
Поблагодарили: 0

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

Сообщение John » Чт май 06, 2021 10:48 am

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

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

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

Надо добиться, чтобы и в автономном режиме работало переключение свойства. Значит модуль по каким-то причинам не "отлавливает" параметры, прилетающие от Меги. Надо проверять настройку в модуле MegaD. Кстати, какая у вас версия прошивки в Меге (может быть у вас очень старая)?

В модуле в настройках должен быть прописан "Local IP:" (это адрес вашего сервера). Как вот тут (https://www.ab-log.ru/forum/viewtopic.p ... 104#p40104) на картинке.
У вас вообще MegaD что-нибудь когда-нибудь "отлавливал" (например, нажатия на выключатели освещения)?
John
Сообщения: 38
Зарегистрирован: Пн ноя 10, 2014 1:52 pm
Благодарил (а): 12 раз
Поблагодарили: 0

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

Сообщение John » Чт май 06, 2021 11:40 am

Да, все работает! Мой косяк, галку напротив Act не поставил ))
С Megad я немного знаком, у меня их в системе сейчас 11 штук, 8 из них занимаются светом, 2 датчиками (температура, движение, CO2, влажность) и вот один сейчас я поставил на бойлер.
Chainik
Сообщения: 1463
Зарегистрирован: Вс янв 10, 2016 11:05 am
Благодарил (а): 260 раз
Поблагодарили: 454 раза

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

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

Т.е. теперь при автономном переключении насоса Мегой свойство насоса "Status" меняется?
Ответить