Элемент Поле выбора (radio)

Вносятся изменения в файлы или устанавливаются доп программы

Модераторы: immortal, newz20

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

Элемент Поле выбора (radio)

Сообщение Bagir » Ср авг 10, 2022 3:27 am

Предлагаю вашему вниманию расширенные настройки элемента в меню "Поле выбора (radio)" Этот переключатель с несколькими кнопками можно весьма интересно использовать. В отличии от элемента "Выключатель", тут мы можем задавать не только состояния вкл/выкл, но и добавить ещё автоматический режим и работу по таймеру.
WhatsApp Image 2022-08-10 at 00.12.26.jpeg
WhatsApp Image 2022-08-10 at 00.12.26.jpeg (43.35 КБ) 1398 просмотров
Немного об этих режимах:
Off и On - тут всё понятно. Работает как обычный выключатель, но при этом запрещает автоматическое управление. Например нам нужно, чтобы свет горел постоянно, а не погасал при отсутствии активности в комнате. Либо наоборот, мы меняем лампочку, и нам не нужно чтобы он включился.
Auto - В этом режиме реле будет слушаться логики. Например включаться при движении когда темно.
Time - Реле включится на время.

Теперь подробнее:
Разберем Авто режим. Я упомянул слово "Логика". Суть умного дома, это не включать лампочку с телефона. А действовать по заранее установленным правилам. И эти правила надо где то записывать. К этой теме следующий абзац не относится, но он нужен, чтобы объяснить принцип работы кнопки выключателя. Вы легко переделайте всё на свою конструкцию. А вот как у меня. Вся логика хранится в методах объектов реле класса Relays.
Свойства:
status - Стандартное свойство показывающее состояние контактов реле.
modeSwitch - мое свойство, связанное с радио переключателем. Может иметь значения 0,1,2,3 соответствующие кнопкам скрина.
bottonColor - цвет кнопки выключателя, когда реле включено. В обычном выключателе и так понятно его состояние. А тут, при режиме Авто или таймер, состояние можно определить по цвету кнопки.
WhatsApp Image 2022-08-10 at 00.29.13.jpeg
WhatsApp Image 2022-08-10 at 00.29.13.jpeg (4.38 КБ) 1398 просмотров
Теперь методы класса:
turnOn - Стандартный метод включения реле. При его вызове, в общем коде метода устанавливается свойство status. Добавим туда еще и установку нашего нового свойства modeSwitch. Оно будет дублировать свойство status только в режимах Вкл и Выкл. Проверка is_numeric() не даст записать в это свойство, если оно не было задействовано ранее для объекта реле. Их же у нас много, а такие переключатели нужны далеко не для всех. И ещё, при выполнении turnOn, свойство modeSwitch будет установлено 1 только если ранее было именно 0.

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

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

$a=$this->getProperty('modeSwitch') ;
if (is_numeric($a) && $a==0) {
 $this->setProperty('modeSwitch', 1);
}
turnOff - Стандартный метод выключения. Всё аналогично, только проверять на число уже не надо. Достаточно нестрогой проверки == 1

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

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

if ($this->getProperty('modeSwitch') == 1) {
 $this->setProperty('modeSwitch', 0);
}
refresh и switch остаются без добавлений.

logic - новый метод. В нем я и храню логику. Этот общий метод будет выполняться перед кодом метода объекта. Если свойство modeSwitch не задано, ничего не делаем. При 0 выключаем реле, при 1 включаем. Это позволит выключать или выключать реле несмотря на условия логики, если мы выбрали кнопку вкл или выкл на радио переключателе. В общем коде метода напишем

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

$ms=$this->getProperty('modeSwitch');

if (!is_numeric($ms)) {
 return; 
} elseif ($ms==0) {
 $this->callMethod('turnOff');
} elseif ($ms==1) {
 $this->callMethod('turnOn');
}
Теперь создадим новый объект класса Relays, или возьмем тот что уже есть.
В его методе turnOn добавим код установки цвета активной кнопки

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

$this->setProperty('bottonColor','#ff0000');
В методе turnOff сбрасываем цвет

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

$this->setProperty('bottonColor',NULL);
В методе logic пока не будем писать условия, а просто предположим, что никаких условий для работы этого реле нет, а значит оно должно быть отключено. Сюда мы ещё вернемся в конце.

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

$this->callMethod('turnOff');
Всё готово к привязке переключателя к объекту реле. Создаем новый радио переключатель:
Название:Лампочка%testRelay.bottonColor%
testRelay это имя нашего объекта класса Relays. %testRelay.bottonColor% добавит в конец код цвета кнопки. Его не будет видно.
Данные:
0|Off
1|On
2|Auto
3|Time
Связанный объект: укажем наш объект testRelay
Свойство: modeSwitch
Только чтение: Да Это очень важно, т.к. изменения состояния в свойство modeSwitch мы будем передавать в коде ниже
Код:

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

$n='testRelay';
$obj=getObject($n);

clearTimeOut($n.'_work');
switch ($params['VALUE']) {
case 0: // Off
 $obj->setProperty('modeSwitch',0);
 $obj->callMethod('turnOff');
 break;
case 1: // On
 $obj->setProperty('modeSwitch',1);
 $obj->callMethod('turnOn');
 break;
case 2: // Auto
 if ($obj->getProperty('modeSwitch')==2) {
  $obj->callMethod('switch');
 } else {
  $obj->setProperty('modeSwitch',2);
  $obj->callMethod('logic');
 }
 break;
case 3: // Time
 // После выбора Time возврат на Off если было Off, On или Time
 // Возврат на Auto если было выбрано ранее
 $m=$obj->getProperty('modeSwitch');
 if (in_array($m, [0, 1, 3])) { $s="sg('$n.modeSwitch',0); cm('$n.turnOff');"; }
 if ($m == 2) { $s="sg('$n.modeSwitch',2); cm('$n.logic');"; }
 // Установить таймер активности в комнате.
 setTimeOut($n.'_work',$s, 5*60);
 $obj->setProperty('modeSwitch',3);
 $obj->callMethod('turnOn');
}
Обратите внимание, в коде есть имя объекта реле testRelay. В строке установки таймера время включения реле 5*60. Например у меня это берется их режимов энергопотребления. Для простоты примера тут напишем прямо в коде элемента.
Рассмотрим как работает код. $params['VALUE'] содержит значение нажатой кнопки.
Если мы нажали Off, то записываем в modeSwitch 0 и выключаем реле. On - по аналогии.
2 - Auto. Тут вся хитрость. Если это повторное нажатие кнопки, то инвертируем состояние реле. Если до этого был выбран другой режим, то запускаем метод logic, который решит, нужно ли реле работать. Если у вас логика находится в другом месте, то тут нужно будет вызвать код, в котором принимается решение.
3 - Time. Если ранее был выбран режим On или Off, то по истечении таймера выбираем режим Off. Если ранее был Auto, то его и вернем, но проверим логику. Если повторно нажать на кнопку Time, то таймер будет пересоздан, и возврата на предыдущий режим не будет. Полезно при сознательном уходе с режима Auto, если мы не хотим, чтобы реле включилось потом по условиям логики.

Всё уже должно работать! Кроме условий логики, к которым я обещал вернуться в конце.
Код метода logic в объекте реле. Я взял самый простой пример. Разберем его работу.
Если modeSwitch 0 или 1, то ничего не проверяем. Реле будет включено или выключено в родительском коде метода. Если modeSwitch не задан, то код всё равно будет работать, т.к. я использую его и для некоторых объектов, у которых нет переключателей в меню. Далее комментарии в коде всё объясняют.

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

// прервать выполнение если modeSwitch число и оно <2
$ms=$this->getProperty('modeSwitch');
if (is_numeric($ms) && $ms<2) { return; }

// Проверка свойств объектов, которые могут изменить решение
$ot = $this->object_title;  
$f = 0; // Предполагаем, что реле будет выключено

// включить при активности в комнате когда стемнело
if (gg('HallArea.SomebodyHere')) {
 if (gg('HallArea.Luminiscence') < 40) {
  $f = 1;
}}

// включить при существовании таймера
if (timeOutExists($ot.'_work')) { $f = 1; }

// выполнить 
$s=$this->getProperty('status');
if ($f>$s) { $this->callMethod('turnOn'); }
if ($f<$s) { $this->callMethod('turnOff'); }
Последний раз редактировалось Bagir Чт авг 11, 2022 10:10 am, всего редактировалось 3 раза.
За это сообщение автора Bagir поблагодарили (всего 3):
Sergey.Chek (Ср авг 10, 2022 1:26 pm) • xor (Ср авг 10, 2022 7:54 pm) • gil777 (Пт авг 19, 2022 2:43 pm)
Рейтинг: 3.49%
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Аватара пользователя
xor
Сообщения: 2038
Зарегистрирован: Сб ноя 22, 2014 8:45 pm
Благодарил (а): 284 раза
Поблагодарили: 629 раз

Re: Элемент Поле выбора (radio)

Сообщение xor » Ср авг 10, 2022 9:42 pm

case 3:
$m=$obj->getProperty('modeSwitch');
$m=$obj->getProperty('modeSwitch');
? задвоилась строчка
За это сообщение автора xor поблагодарил:
Bagir (Чт авг 11, 2022 10:18 am)
Рейтинг: 1.16%
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Элемент Поле выбора (radio)

Сообщение Bagir » Чт авг 11, 2022 10:18 am

xor писал(а):
Ср авг 10, 2022 9:42 pm
задвоилась строчка
Да, под утро не увидел, пока копировал ))
Там у меня добавлен код получения времени таймера из объектов комнат. В верхнем примере я его убрал, чтобы не путать, и просто указал 5 минут (5*60).

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

case 3: // Time
 /* Установить таймер активности в комнате.
    Свойство объекта комнаты класса Rooms может быть не задано вовсе,
    тогда таймаут активности будет принят как 10 минут.
    Задано простым числом, или задано последовательностью из 5 чисел,
    разделенных ; для разных режимов работы энергопотребления
 */   
 $idl = gg('HallArea.IdleDelay');  // ИМЯ ОБЪЕКТА КОМНАТЫ!
 if (strpos($idl, ';')) {
   $activity_timeout=explode(";", $idl);
   $activity_timeout= $activity_timeout[(int)gg('EconomMode.status')+2];
 } elseif ($idl) {
   $activity_timeout=(int)$idl;
 } else {
   $activity_timeout=10*60;
 }
 
 // После выбора Time возврат на Off если было Off, On или Time
 // Возврат на Auto если было выбрано ранее
 $m=$obj->getProperty('modeSwitch');
 if (in_array($m, [0, 1, 3])) { $s="sg('$n.modeSwitch',0); cm('$n.turnOff');"; }
 if ($m == 2) { $s="sg('$n.modeSwitch',2); cm('$n.logic');"; }
 setTimeOut($n.'_work',$s, $activity_timeout);
 $obj->setProperty('modeSwitch',3);
 $obj->callMethod('turnOn');
Вам этот код не пригодится, но идея очень может быть. В объектах комнат есть свойство HallArea.IdleDelay установленное например 60;180;300;600;600 значение берется исходя из выбранного режима экономии EconomMode.status Его значение может быть у меня -2 до 2, от сюда и +2 в коде.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Ответить