Скрипт заполнения и слива системы отопления

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

Модератор: immortal

Ответить
cheese
Сообщения: 8
Зарегистрирован: Чт окт 29, 2015 10:57 am
Откуда: Минск
Благодарил (а): 0
Поблагодарили: 0

Скрипт заполнения и слива системы отопления

Сообщение cheese » Вт фев 14, 2017 9:56 am

Люди, помогите! )))
Возник еще вопрос.

В общем-то делаю скрипты по сливу и заполнению системы отопления.

Начнем со слива.
вот код:
В коде специально слишком много say и есть лимит, чтобы слышать и понимать процесс выполнения алгоритма.

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

$in9 = gg('in9.state'); // датчик уровня в расширительном бачке
$in10 = gg('in10.state'); // датчик минимального уровня
$in11 = gg('in11.state'); // датчик протока при сливе
$r5 = gg('r5.status'); // клапан на заполнение
$r6 = gg('r6.status'); // клапан на слив
$r7 = gg('r7.status'); // клапан расширительного бачка
$r8 = gg('r8.status'); // реле компрессора для продувки системы

if ($r5 == 1 && $r7 == 1) {
    
    sg('r6.status', 0); // Точно 6 ставим в 0, проверяли то 5 и 7 ???
    say('Идет слив системы отопления.', 2);
    
$flushFinished = false;
    $flushStarted = (gg('in11.state') == 1); //датчик протока при сливе
    $limit = 3; //Пробуем только 3 раза
    while (true) {
        $limit--;
        $in11 = gg('in11.state'); // датчик протока при сливе
        say('Проверяем слив: слив начался = ' . ($flushStarted ? 'false' : 'true') . ', закончился = ' . ($flushFinished ? 'true' : 'false') . ', новое состояние 11 = ' . ($in11), 2);
        $flushStarted = $flushStarted || ($in11 == 1);  //Станет true как только $in11 станет 1 первый раз, если еще не true
        $flushFinished = $flushFinished || ($flushStarted && ($in11 == 0)); //Станет true как только $flushStarted true и $in11 станет 0
        if ($flushFinished || ($limit < 0)) {
            say('Прерываем цикл: состояние = ' . ($flushFinished ? 'true' : 'false') . ', лимит сработал = ' . ($limit < 0 ? 'true' : 'false'), 2);
            break;
        }
        sleep(10); //Ждем еще
    }
    
    say('Слив завершен.', 2);
    say('Перекрываю клапан расширительного бачка.', 2);
sleep(5);
    sg('r7.status', 0); //Перекрываем клапан расширительного бачка
    sleep(5);
}

say('Включаю компрессор', 2);
sleep(5);
sg('r8.status', 0);
sleep(10);
say('Выключаю компрессор', 2);
sleep(5);
sg('r8.status', 1);
sleep(10);
sg('r7.status', 1);
sg('r6.status', 1);
Хронология действий следующая:

1. Проверяем закрыт ли клапан на заполнение системы и открыт ли клапан расширительного бачка; (if ($r5 == 1 && $r7 == 1))
2. Если все норм, то открываем на слив системы. sg('r6.status', 0); Водичка пошла, при этом датчик протока замыкается и говорит, что водичка идет. (т.е. in11=1)
3. Когда система сольется, датчик протока размыкается (in11=0).
4. Если датчик протока разомкнут (in11=0) перекрываем клапан расширителььного бачка. (sg('r7.status', 0);)
5. Далее включаем компрессор для продувки системы отопления (sg('r8.status', 0);)
6. После того как он поработал, выключаем (sg('r8.status', 1);)
7. Открываем клапан расширительного бачка.
Ну после этого идет небольшая проверка положения клапанов. (не указано в этом коде)

Вопрос следующий. Majordomo не видит изменения состояния входа Megad-2561 во время выполнения скрипта. Т.е. он не реагирует на физическое изменение состояния входа во время исполнения скрипта. Т.е. он не видит изменения in11
1. Как сделать так, чтобы Majordomo реагировал во время выполнения скрипта без танцев с бубном. Может есть какой-то метод или скрипт для принудительно обновления состояния?

Технически удалось решить данную проблему принудительным опросом MegaD-2561 напрямую из скрипта. И все заработало. Скрипт ниже:

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

$getRealState = function ($port) {
    $response = file_get_contents('http://192.168.1.111/sec/?cmd=get&pt=' . $port);
  //  say('Ответ сервера: ' . $response, 2);
    return strtolower(substr($response, 0, 3)) == 'off' ? 0 : 1;
};
$in9 = gg('in9.state'); // датчик уровня в расширительном бачке
$in10 = gg('in10.state'); // датчик минимального уровня
$in11 = gg('in11.state'); // датчик протока при сливе
$r5 = gg('r5.status'); // клапан на заполнение
$r6 = gg('r6.status'); // клапан на слив
$r7 = gg('r7.status'); // клапан расширительного бачка
$r8 = gg('r8.status'); // реле компрессора для продувки системы
$p11 = 11; //Port для датчика протока

if ($r5 == 1 && $r7 == 0) {
    
    sg('r6.status', 0); // открываем сливной клапан
    say('Идет слив системы отопления.', 2);
    $flushFinished = false;
    $flushStarted = ($getRealState($p11) == 1); //датчик протока при сливе
  //  $limit = 8; //Пробуем только X раз
    while (true) {
        $limit--;
        $in11 = $getRealState($p11); // датчик протока при сливе
      //  say('Проверяем слив: слив начался = ' . ($flushStarted ? 'true' : 'false') . ', закончился = ' . ($flushFinished ? 'true' : 'false') . ', новое состояние 11 = ' . ($in11), 2);
        $flushStarted = $flushStarted || ($in11 == 1);  //Станет true как только $in11 станет 1 первый раз, если еще не true
        $flushFinished = $flushFinished || ($flushStarted && ($in11 == 0)); //Станет true как только $flushStarted true и $in11 станет 0
        if ($flushFinished || ($limit < 0)) {
           // say('Прерываем цикл: состояние = ' . ($flushFinished ? 'true' : 'false') . ', лимит сработал = ' . ($limit < 0 ? 'true' : 'false'), 2);
           break;
        }
        sleep(5); //Ждем еще
    }

    say('Слив завершен.', 2);
    say('Перекрываю клапан расширительного бачка.', 2);
    sleep(5);
    sg('r7.status', 1); //Перекрываем клапан расширительного бачка
    sleep(5);
}

say('Включаю компрессор', 2);
sleep(5);
sg('r8.status', 0);
sleep(10);
say('Выключаю компрессор', 2);
sleep(5);
sg('r8.status', 1);
say('Открывю клапан расширительного бачка', 2);
sleep(3);
sg('r7.status', 0);
sleep(5);
say('Проверяю состояние клапанов после слива', 2);
if ($r5 == 1 && $r7 == 0 && $r6 == 0) {
 say('Все клапаны открыты.', 2);
}
else {
 say('Какой-то клапан перекрыт', 2);
}

Но хотелось бы сделать более элегантное решение.

Также я заметил, что во время выполнения какого-нибудь длинного скрипта, сайт системы Majordomo висит. И не отвисает до выполнения скрипта. В моем случае система отопления может сливаться целый час (цикл то идет). И все это время я не смогу ничего сделать с majordomo.
2. Как сделать так, чтобы выполнение скрипта проходило в "фоновом" режиме?

Конечно можно все это сделать используя шаблоны поведения, но хотелось бы все в один скрипт запихнуть.

Есть идеи? ))
cheese
Сообщения: 8
Зарегистрирован: Чт окт 29, 2015 10:57 am
Откуда: Минск
Благодарил (а): 0
Поблагодарили: 0

Re: Скрипт заполнения и слива системы отопления

Сообщение cheese » Вт фев 14, 2017 9:59 am

Забыл про компоненты:
Собственно Debian 8 x64 и MegaD-2561
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Скрипт заполнения и слива системы отопления

Сообщение Bagir » Вт фев 14, 2017 10:40 am

sleep() это зло.
все в один скрипт запихнуть - тоже зло.
По моему мнению система должна просто реагировать на входящие данные и принимать соответствующие решения. Трудно что то посоветовать конкретное. Но я бы делал примерно так: создал объект, у которого будет метод для приёма входящих данных. Добавим свойство этому объекту, которое будет отвечать за текущую выполняемую задачу. Затем, когда в метод приёма данных будут поступать сигналы от объектов-датчиков, то логика метода приёма данных будет принимать новые решения в соответствии со значением свойства с выполняемой задачей.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Скрипт заполнения и слива системы отопления

Сообщение Bagir » Вт фев 14, 2017 10:50 am

Например у меня есть объект реле включения прожекторов. Один из вариантов у меня реализован так: Можно самому пощёлкать этим реле, изменяя его свойство status, но ещё у этого объекта есть метод, при запуске которого он смотрит на свойства других объектов. Например датчик движения, датчик света, датчик открытия ворот, и т.д. Если логика этого объекта считает, что надо включить свет, то она просто включает его на неопределённый срок (например при открытых воротах), либо включает на определенное время, создавая таймер для выключения (например по датчику движения). Если датчик движения, или любое другое событие происходит опять, то таймер отключения перезапускается. Причем перед перезапуском таймера проверяется сколько времени он еще должен работать, т.к. некоторые события могут включать свет на короткое время, а некоторые на долго.
Это можно назвать своего рода подписка на события. Но подписать метод на события других датчиков невозможно, поэтому когда свойства влияющих датчиков изменяются, они вызывают метод объекта реле освещения, который и принимает решение.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
DimSun75
Сообщения: 318
Зарегистрирован: Вс янв 01, 2017 8:32 pm
Откуда: Москва
Благодарил (а): 7 раз
Поблагодарили: 44 раза

Re: Скрипт заполнения и слива системы отопления

Сообщение DimSun75 » Вт фев 14, 2017 10:58 am

+1 К предыдущему оратору ;)

Почитайте про такую сущность, как конечные автоматы.

И еще, есть такая замечательная вещь, как таймеры. С помощью них гораздо проще контролировать, когда переход из одного состояния в другое не произошел в нужное время. И они не нагружают систему.
AndrewS
Сообщения: 123
Зарегистрирован: Пт апр 15, 2016 10:18 am
Откуда: 21RU
Благодарил (а): 5 раз
Поблагодарили: 20 раз
Контактная информация:

Re: Скрипт заполнения и слива системы отопления

Сообщение AndrewS » Вт фев 14, 2017 11:02 am

Вообще логику простых процессов нужно закладывать в контроллер и выводить на кнопку, чтобы при обрыве связи или отвале памяти ваша система отопления не оказалась бесполезной кучей электроники. Подойдет любая ардуина, я нз в МегаД можно ли закладывать логику, но если нет подойдет любая ардуина или PIC или Atmel. Я бы не стал вешать на MJD логику, а только контроль и мониторинг.
Слабость - велика, а сила - ничтожна.
ARMBIAN 5.38 stable Debian GNU/Linux 9 (stretch) 4.14.18-sunxi
System load: 2.03 1.85 1.78 Up time: 23 days
Memory usage: 65 % of 2014MB CPU temp: 37°C
Orange Pi Plus 2 H3 Quad Core 1.6GHZ 2GB
DimSun75
Сообщения: 318
Зарегистрирован: Вс янв 01, 2017 8:32 pm
Откуда: Москва
Благодарил (а): 7 раз
Поблагодарили: 44 раза

Re: Скрипт заполнения и слива системы отопления

Сообщение DimSun75 » Вт фев 14, 2017 11:21 am

AndrewS писал(а):Вообще логику простых процессов нужно закладывать в контроллер и выводить на кнопку, чтобы при обрыве связи или отвале памяти ваша система отопления не оказалась бесполезной кучей электроники. Подойдет любая ардуина, я нз в МегаД можно ли закладывать логику, но если нет подойдет любая ардуина или PIC или Atmel. Я бы не стал вешать на MJD логику, а только контроль и мониторинг.
Не совсем соглашусь. Именно этот процесс не такой уж и простой, судя по скрипту. Поэтому наваливать его в железку смысла нет. Да и проходить он будет скорее всего при присутствии людей.
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Скрипт заполнения и слива системы отопления

Сообщение Bagir » Вт фев 14, 2017 12:02 pm

В МегаД есть логика, и она очень эффективна в моменты когда сервер лёг. Домустим есть у нас кнопка и люстра с тремя лампочками. С помощью МД можно одной кнопкой управлять любым количеством лампочек. Разными комбинациями нажатий включать и выключать свет в других комнатах (например в коридоре). Полностью выключать свет во всем доме (например при долгом удержании кнопки). Но если сервер бахнется, то логика МегаД при нажатии кнопки просто, например, включит первую лампочку, а при повторном нажатии выключит её. Да, былого удобства нет, но вы не остались без света даже в аварийной ситуации!
Так же и с управлением сложными системами. Логика контроллера должна обеспечить минимально допустимый функционал. Ну а если сервер в сети, то пускай он всем и рулит. Я всегда старюсь придерживаться этого подхода.
За это сообщение автора Bagir поблагодарил:
DimSun75 (Вт фев 14, 2017 1:19 pm)
Рейтинг: 1.16%
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
cheese
Сообщения: 8
Зарегистрирован: Чт окт 29, 2015 10:57 am
Откуда: Минск
Благодарил (а): 0
Поблагодарили: 0

Re: Скрипт заполнения и слива системы отопления

Сообщение cheese » Вт фев 14, 2017 3:20 pm

Да и проходить он будет скорее всего при присутствии людей.
Точно подмечено. А потом еще и электро котел нужно будет включить. Но это уже в случае наполнения.
Ну а если сервер в сети, то пускай он всем и рулит.
Сервер планируется именно в сети. Смысл этой процедуры в том, чтобы залить систему отопления удаленно и поставить дом на прогрев.
Просто по поводу слива процедура аналогичная.
А по поводу света, так я буду использовать бистабильное реле. Т.е. тут уже будет пофиг и на контроллер и на сервер в случае чего.

Тут скорее вопрос не в сложности скрипта.
А вопрос в том, что значения во время выполнения скрипта не обновляются.
Ну и опять же по поводу фонового выполнения скрипта. ко мне че-то приходят идеи сделать еще один VPS и на него это все пустить. Но опять же, получается дробление системы.
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Скрипт заполнения и слива системы отопления

Сообщение Bagir » Вт фев 14, 2017 5:03 pm

cheese писал(а):Сервер планируется именно в сети.
Я имел ввиду что сервер onLine. Если в коде не делать ошибки, то система работает очень стабильно. Но всякое же бывает... Поэтому жизненно важные системы я предпочитаю дублировать автономной логикой для поддержания минимально допустимой работоспособности. Пример выше про свет.
Во время выполнения скрипта данные конечно же не обновляются. Система попросту занята выполнением этого скрипта. Занята - громко сказано. Она попросту дурака валяет на слипе.
Конечно можно запустить параллельно этот скрипт и получить какой то результат, но уж простите за прямоту, я считаю это просто полная ерунда.
Но, на ошибках учатся. Я их весьма много делал ранее, когда пытался грести против течения, и особенно не прислушиваясь к постам sergejey. Мне казалось, что так лучше. Но в результате весь этот бредо-код пошел в скором времени под снос. Зато были получены бесценные уроки.
Самое главное, что вы ничего не теряйте, экспериментируйте, и делитесь результатами.
За это сообщение автора Bagir поблагодарил:
Matviiv (Ср фев 15, 2017 1:55 pm)
Рейтинг: 1.16%
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Ответить