Помогите с кодом (с логикой) пожалуйста
Модератор: immortal
-
- Сообщения: 1462
- Зарегистрирован: Вс янв 10, 2016 11:05 am
- Благодарил (а): 260 раз
- Поблагодарили: 454 раза
Re: Помогите с кодом (с логикой) пожалуйста
Я тоже считаю, что основной целевой параметр -- температура в помещении. Однако управлять отоплением по температуре на улице тоже можно. Ведь не зря же к большинству котлов можно подключить внешний уличный датчик температуры.
Вот набросал в фотошопе из того, что попалось под руку. Сильно приблизительно, но надо с чего-то начинать. Коротенько объясню идею.
Непосредственно поддержанием целевой температуры будет заниматься контроллер. Мы со стороны сервера будем давать ему "ценные указания". Так будет надежнее с точки зрения отказоустойчивости.
Теперь по поводу кнопок-индикаторов. Большая кнопка сверху будет служить индикатором того, включено отопление или нет. Если хоть один контур активен, то она будет активна. Нажатие по этой кнопке будет выключать все отопление сразу. Можно также сделать, чтобы нажатие при выключенном отоплении активизировало сразу все контуры.
Дальше, понятно, температура на улице и температура в каком-то помещении (выбранном за ориентир температуры в доме).
Затем идет ряд кнопок по управлению той или иной веткой. Таких рядов будет несколько (по числу веток отопления).
Первая кнопка активирует/деактивирует данный контур.
Вторая (в виде руки) -- переключатель между ручным и автоматическим режимом. Ведь потом мы обязательно дорастем до автоматики и "тонких настроек" )) Под автоматикой я в данном случае понимаю автоматическое изменение сервером целевой температуры в зависимости от разных условий и значимых параметров.
Третья -- кнопка-индикатор, показывающая текущее состояние насоса на контуре (включен/выключен), а при нажатии происходит "ручное" включение/выключение насоса.
Дальше кнопки "+/-", которыми мы будем регулировать целевую температуру в контуре. В вашем случае это температура обратки. Между кнопками, собственно, регулируемая температура.
Затем фактическая температура в контуре.
Быстро не обещаю, т.к. отвлекает работа и куча неотложных дел...
Вот набросал в фотошопе из того, что попалось под руку. Сильно приблизительно, но надо с чего-то начинать. Коротенько объясню идею.
Непосредственно поддержанием целевой температуры будет заниматься контроллер. Мы со стороны сервера будем давать ему "ценные указания". Так будет надежнее с точки зрения отказоустойчивости.
Теперь по поводу кнопок-индикаторов. Большая кнопка сверху будет служить индикатором того, включено отопление или нет. Если хоть один контур активен, то она будет активна. Нажатие по этой кнопке будет выключать все отопление сразу. Можно также сделать, чтобы нажатие при выключенном отоплении активизировало сразу все контуры.
Дальше, понятно, температура на улице и температура в каком-то помещении (выбранном за ориентир температуры в доме).
Затем идет ряд кнопок по управлению той или иной веткой. Таких рядов будет несколько (по числу веток отопления).
Первая кнопка активирует/деактивирует данный контур.
Вторая (в виде руки) -- переключатель между ручным и автоматическим режимом. Ведь потом мы обязательно дорастем до автоматики и "тонких настроек" )) Под автоматикой я в данном случае понимаю автоматическое изменение сервером целевой температуры в зависимости от разных условий и значимых параметров.
Третья -- кнопка-индикатор, показывающая текущее состояние насоса на контуре (включен/выключен), а при нажатии происходит "ручное" включение/выключение насоса.
Дальше кнопки "+/-", которыми мы будем регулировать целевую температуру в контуре. В вашем случае это температура обратки. Между кнопками, собственно, регулируемая температура.
Затем фактическая температура в контуре.
Быстро не обещаю, т.к. отвлекает работа и куча неотложных дел...
Re: Помогите с кодом (с логикой) пожалуйста
Огромное спасибо!
Все прекрасно, только еще можно добавить гистерезис на температуру обратки.
Все прекрасно, только еще можно добавить гистерезис на температуру обратки.
-
- Сообщения: 1462
- Зарегистрирован: Вс янв 10, 2016 11:05 am
- Благодарил (а): 260 раз
- Поблагодарили: 454 раза
Re: Помогите с кодом (с логикой) пожалуйста
Пока не за что благодарить.
А гистерезисом у нас будет заведовать контроллер. На порту, куда у вас подключен висящий на контуре температурный датчик, выставляете
Mode -- "<>";
Val -- нужную целевую температуру обратки в контуре;
Hst -- значение гистерезиса (например, 1.5). Тут вам виднее, какое значение лучше выбрать в зависимости от средней динамики изменения температуры в контуре при изменении состояния насоса;
Act -- "7:4" (например). "7" -- это номер выхода, на котором висит насос. Команда "4" означает, что когда температура будет меньше Val-Hst, насос включится, а когда больше Val+Hst -- выключится.
Таким образом рутинной операцией поддержания заданной температуры в контуре будет заведовать MegaD без привлечения сервера. Это будет надежнее.
Со стороны сервера будут поступать лишь 2 команды, которые будут изменять значение "Val" без перезагрузки контроллера: включить термостат
выключить термостат
В последнем случае мы задаем нереально низкую целевую температуру, при которой насос и не подумает включаться.
А какие модели температурных датчиков вы применяете? DS18B20?
И к каким портам они подключены (порт и контур отопления, с которым связан датчик)?
Лучше даже полную цепочку, чтобы была ясность:
№ порта темп.датчика --- № порта релейного выхода, к которому подключен насос --- контур отопления.
Ну и адрес контроллера в вашей локальной сети, чтобы вам меньше нужно было править в коде руками (192.168.ххх.ххх).
А гистерезисом у нас будет заведовать контроллер. На порту, куда у вас подключен висящий на контуре температурный датчик, выставляете
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.ххх.ххх).
Re: Помогите с кодом (с логикой) пожалуйста
Добрый день!
Температурные датчики DS18B20
Порты:
1. Насос 1 эт. - 8, датчик - 31
2. Насос 2 эт. - 7, датчик - 30
3. Насос теплого пола - 9, датчик - 32
Адрес контроллера 192.168.0.211, пароль стандартный
Температурные датчики DS18B20
Порты:
1. Насос 1 эт. - 8, датчик - 31
2. Насос 2 эт. - 7, датчик - 30
3. Насос теплого пола - 9, датчик - 32
Адрес контроллера 192.168.0.211, пароль стандартный
-
- Сообщения: 1462
- Зарегистрирован: Вс янв 10, 2016 11:05 am
- Благодарил (а): 260 раз
- Поблагодарили: 454 раза
Re: Помогите с кодом (с логикой) пожалуйста
Отлично. Значит выбранная схема пройдет (т.к. функцию "удаленный термостат" поддерживает только DS18B20).
Разбираемся с датчиками.
Все датчики, которые подключены к цифровым портам, я предлагаю поместить в отдельный класс. Назовем его, к примеру, "Sensors". (Для всех датчиков, подключаемых к стандартным портам, будем создавать свои отдельные классы).
На каждый измеряемый датчиком параметр в классе будет создаваться отдельный объект. Ведь есть датчики, которые изменяют сразу несколько параметров. Наименования объектов могут быть любые, но я бы выбрал что-то стандартизированное и отражающее смысл измеряемого параметра:
SensorTemp_01
SensorTemp_02
SensorTemp_03
...
SensorHum_01
SensorHum_02...
У каждого объекта будет отдельный код опроса, который мы запишем в код ОБЪЕКТА.
Добавим в класс свойства:
Value -- текущее значение (свойство без истории);
ValueSaved -- сохраненное значение (свойство с историей);
DebMessage -- некорректное значение (свойство без истории).
Добавляем в класс метод "getValue".
Добавляем для объекта "SensorTemp_01" код метода:
По остальным датчикам то же самое, только в коде надо поправить комментарии, чтобы потом не перепутать, за что отвечает этот датчик и указать соответствующий порт опроса в строке "$Port = 31;". Для второго датчика это будет "$Port = 30;"
Можно было бы, конечно, обойтись парой строчек, но хочется сделать более-менее универсальный вариант.
Смысл в следующем. Мы "развязываем" текущее значение и то значение, которое должно быть записано в историю. Дело в том, что актуальное значение с датчика мы можем захотеть знать раз 10 секунд, а вот в историю записывать можем раз в полчаса. Поэтому мы не будем писать значение в историю, каждый раз, когда опрашиваем датчик. Все эти временнЫе параметры настроим в коде опроса конкретного датчика.
Напишем сценарий для запуска опроса датчиков, подключенных к цифровым портам. Пусть называется "SensorsPolling". Каждая строчка сценария будет запускать команду на опрос отдельного датчика/параметра.
Строчки, по которым код у вас еще не настроен, я пока закомментировал. Как настроите, раскомментируете их.
По мере добавления цифровых датчиков для опроса и настройки кода сюда будут добавляться строчки для организации периодического опроса.
Будем запускать опрос датчиков из onNewMinute. Просто добавим туда строчку:
Теперь в свойствах Value и ValueSaved должны появляться значения.
Можете добавить для аналитики домашнюю страницу и вывести графики с датчиков туда. Если никогда этого раньше не делали, я подскажу, там все очень просто.
Дальше будем разбираться с насосами. Там, с одной стороны проще, но надо будет чуть-чуть понастраивать в модуле "MegaD".
Разбираемся с датчиками.
Все датчики, которые подключены к цифровым портам, я предлагаю поместить в отдельный класс. Назовем его, к примеру, "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);
}
}
Можно было бы, конечно, обойтись парой строчек, но хочется сделать более-менее универсальный вариант.
Смысл в следующем. Мы "развязываем" текущее значение и то значение, которое должно быть записано в историю. Дело в том, что актуальное значение с датчика мы можем захотеть знать раз 10 секунд, а вот в историю записывать можем раз в полчаса. Поэтому мы не будем писать значение в историю, каждый раз, когда опрашиваем датчик. Все эти временнЫе параметры настроим в коде опроса конкретного датчика.
Напишем сценарий для запуска опроса датчиков, подключенных к цифровым портам. Пусть называется "SensorsPolling". Каждая строчка сценария будет запускать команду на опрос отдельного датчика/параметра.
Код: Выделить всё
//Скрипт запуска кода опроса цифровых датчиков
callMethodSafe('SensorTemp_01.getValue');
//callMethodSafe('SensorTemp_02.getValue');
//callMethodSafe('SensorTemp_03.getValue');
По мере добавления цифровых датчиков для опроса и настройки кода сюда будут добавляться строчки для организации периодического опроса.
Будем запускать опрос датчиков из onNewMinute. Просто добавим туда строчку:
Код: Выделить всё
runScriptSafe('SensorsPolling');
Можете добавить для аналитики домашнюю страницу и вывести графики с датчиков туда. Если никогда этого раньше не делали, я подскажу, там все очень просто.
Дальше будем разбираться с насосами. Там, с одной стороны проще, но надо будет чуть-чуть понастраивать в модуле "MegaD".
- Рейтинг: 1.16%
-
- Сообщения: 1462
- Зарегистрирован: Вс янв 10, 2016 11:05 am
- Благодарил (а): 260 раз
- Поблагодарили: 454 раза
Re: Помогите с кодом (с логикой) пожалуйста
Разбираемся с насосами.
Создадим для них отдельный класс. Пусть называется "PumpsHeat".
Добавим в класс свойство "Status". У свойства включим историю (допустим, на 999 дней). Потом можно будет посчитать общее время работы любого насоса за произвольный период. Да и на график состояние насоса будет полезно вывести, особенно при настройке системы отопления.
Только надо не забыть в модуле Optimizer выключить по данному свойству оптимизацию значений.
Добавим в класс методы:
turnOn
turnOff
switch
getStatus -- выставляет значение свойства "Status" при произвольном запросе.
setStatus -- будет выставлять значение свойства "Status" при самостоятельном (без внешней команды) переключении насоса контроллером.
Добавим в класс объекты насосов "PumpHeat_01", "PumpHeat_02", "PumpHeat_03" ... .
Все коды методов пропишем в коды ОБЪЕКТОВ, кроме метода "setStatus" (его запишем в метод класса).
Для "PumpHeat_01":
Код метода turnOn
Код метода turnOff
Код метода switch
Код метода getStatus
Код метода setStatus (запишем в метод КЛАССА)
Теперь надо в модуле "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).
Создадим для них отдельный класс. Пусть называется "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);
Код: Выделить всё
//Циркуляционный насос радиаторного контура 1-го этажа
//Обозначение провода, к которому подключен насос
//
//Параметры доступа к контроллеру
$ipAddress = "192.168.0.211";
$Password = "sec";
//Порт, к которому подключен насос
$Port = 8;
//Команда на выключение
file_get_contents("http://".$ipAddress."/".$Password."/?cmd=".$Port.":0");
//Запись значения в свойство "Status"
$this->setProperty('Status', 0);
Код: Выделить всё
//Циркуляционный насос радиаторного контура 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');
}
Код: Выделить всё
//Циркуляционный насос радиаторного контура 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);
}
Код: Выделить всё
//Метод выставляет значение свойства "Status" при самостоятельном (без внешней команды) переключении насоса контроллером
if(isset($_GET['v'])) {
if ($_GET['v'] == 1) {
$this->setProperty('Status', 1);
} else {
$this->setProperty('Status', 0);
}
}
Т.е. выставляем по объекту насоса метод "setStatus".
В методах объектов по остальным насосам пропишите то же самое, только комментарий поправьте в начале и строчку с номером выхода, куда подключен соответствующий насос.
Если что-то "не взлетит", не волнуйтесь, это вопросы отладки. Пишу "с колес", так что не все баги могу сразу заметить.
Ну теперь сделаем перерыв, т.к. начинаются более творческие вещи с интерфейсом и объектами контуров.
А благодарить, в т.ч. финансово, надо ув.skysilver (https://connect.smartliving.ru/tasks/748.html) за то, что взялся за исправление багов модуля "MegaD". Так что ставьте его доработанную версию модуля "MegaD" (https://mjdm.ru/forum/viewtopic.php?f=5 ... start=1365).
- Рейтинг: 1.16%
Re: Помогите с кодом (с логикой) пожалуйста
Большое спасибо!
Температура обновляется, график рисуется.
По насосам все прописал ))))))
Температура обновляется, график рисуется.
По насосам все прописал ))))))
-
- Сообщения: 1462
- Зарегистрирован: Вс янв 10, 2016 11:05 am
- Благодарил (а): 260 раз
- Поблагодарили: 454 раза
Re: Помогите с кодом (с логикой) пожалуйста
Отлично.
Все ли работает штатно при управлении контроллером насосами в автономном режиме?
Допишите, пожалуйста, сопоставление объектов портам Меги (чтобы мне ничего не перепутать).
1. Насос 1 эт. - 8 (PumpHeat_01), датчик - 31 (SensorTemp_01)
2. Насос 2 эт. - 7 (), датчик - 30 ()
3. Насос теплого пола - 9 (), датчик - 32 ()
Все ли работает штатно при управлении контроллером насосами в автономном режиме?
Допишите, пожалуйста, сопоставление объектов портам Меги (чтобы мне ничего не перепутать).
1. Насос 1 эт. - 8 (PumpHeat_01), датчик - 31 (SensorTemp_01)
2. Насос 2 эт. - 7 (), датчик - 30 ()
3. Насос теплого пола - 9 (), датчик - 32 ()
Re: Помогите с кодом (с логикой) пожалуйста
С автономного режима я начинал, там все работает штатно.
1. Насос 1 эт. - 8 (PumpHeat_01), датчик - 31 (SensorTemp_01)
2. Насос 2 эт. - 7 (PumpHeat_02), датчик - 30 (SensorTemp_02)
3. Насос теплого пола - 9 (PumpHeat_03), датчик - 32 (SensorTemp_03)
1. Насос 1 эт. - 8 (PumpHeat_01), датчик - 31 (SensorTemp_01)
2. Насос 2 эт. - 7 (PumpHeat_02), датчик - 30 (SensorTemp_02)
3. Насос теплого пола - 9 (PumpHeat_03), датчик - 32 (SensorTemp_03)
-
- Сообщения: 1462
- Зарегистрирован: Вс янв 10, 2016 11:05 am
- Благодарил (а): 260 раз
- Поблагодарили: 454 раза
Re: Помогите с кодом (с логикой) пожалуйста
Понятно.
А сейчас после настройки выхда в модуле MegaD у вас происходит изменение свойства "Status" у объектов насосов при автономном переключении насосов Мегой?
Пока вы проверяете, я, тем временем, сделал более подходящую иконку для насосов. А то дренажный насос выглядит не совсем подходящим для системы отопления. ))
Взял вот это: https://yandex.ru/images/search?pos=111 ... ource=wiz
И после "обработки напильником" получил вот это: не работает ( ), работает ( ).
А сейчас после настройки выхда в модуле MegaD у вас происходит изменение свойства "Status" у объектов насосов при автономном переключении насосов Мегой?
Пока вы проверяете, я, тем временем, сделал более подходящую иконку для насосов. А то дренажный насос выглядит не совсем подходящим для системы отопления. ))
Взял вот это: https://yandex.ru/images/search?pos=111 ... ource=wiz
И после "обработки напильником" получил вот это: не работает ( ), работает ( ).