Свет по датчику движения с дополнительными условиями.



  • Здравствуйте.

    Дополнительные условия следующие:

    1. Нужно, чтобы сценарий не срабатывал, если свет включен выключателем на стене (чтобы не отключался по таймеру)
    2. Чтобы сценарий не срабатывал, если включен режим охраны.
      На основе шаблона сделал сценарий.
    const lamp = Device("ActorD", "Светильник");
    const sw = Device("SensorD", "Выключатель");
    const motion = Device("SensorD", "Датчик движения"); 
    const SAF = Device("ActorD","Охрана"); 
    
    
    // Запустим сценарий при сработке датчика движения, если светильник не горит, режим охраны отключен, выключатель выключен. 
    startOnChange([motion], motion.isOn() && lamp.isOff() && sw.isOFF() && SAF.isOFF());
    
    script ({
    
        start() {
          lamp.on();
          // взводим таймер, чтобы отключить 
          this.startTimer("T1", 180, "turnOff");       
        },
         
        // Функция, которая сработает, когда таймер досчитает - отключаем и выходим
        turnOff() {
          lamp.off();
          // this.exit();  Эту команду можно не ставить, сценарий и сам завершится
        }
    });
    

    Сценарий не запустился ни разу. Хотя датчик присутствия срабатывает. Пи уменьшении количества условий он начинает иногда срабатывать.

    ПОменял скрипт на следующий

    const lamp = Device("ActorD", "Светильник");
    const sw = Device("SensorD", "Выключатель");
    const motion = Device("SensorD", "Датчик движения"); 
    const SAF = Device("ActorD","Охрана"); 
    
    
    // Запустим сценарий при сработке датчика движения, если светильник не горит, режим охраны отключен, выключатель выключен. 
    startOnChange([motion], motion.isOn());
    
    script ({
    
        start() {
          if ((SAF.value === 0) && (sw.value === 0) && (lamp.value === 0)) {
          lamp.on();
          // взводим таймер, чтобы отключить 
          this.startTimer("T1", 180, "turnOff");       
              }
          },
         
        // Функция, которая сработает, когда таймер досчитает - отключаем и выходим
        turnOff() {
          lamp.off();
          // this.exit();  Эту команду можно не ставить, сценарий и сам завершится
        }
    });
    

    Скрипт запускается, но.
    Запустить второй раз сразу после выключения света по таймеру не получается.
    Второй рах скрипт срабатывает только через какое-то время, которое мне определить не удалось.
    Датчик движения срабатывает, а свет не включается, если он только что выключился.

    Что может влиять? К факту выключения света привязат скрипт включения ветнилятора на 2 минуты.
    Может быть из-за него?

    const lamp = Device("ActorD", "Светильник");
    const vent = Device("ActorD","Вентилятор"); 
    
    
    // Запустим сценарий при сработке датчика движения, если светильник не горит, режим охраны отключен, выключатель выключен. 
    startOnChange([lamp], lamp.isOff() && vent.isOff());
    
    script ({
    
        start() {
          vent.on();
          // взводим таймер, чтобы отключить 
          this.startTimer("T1", 120, "turnOff");       
        },
         
        // Функция, которая сработает, когда таймер досчитает - отключаем и выходим
        turnOff() {
          vent.off();
          // this.exit();  Эту команду можно не ставить, сценарий и сам завершится
        }
    });
    

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



  • И еще вопрос.

    Как при включенном по датчику движения свете по повторному срабатыванию датчика движения обнулять таймер?

    При условии if ((SAF.value === 0) && (sw.value === 0) && (lamp.value == 1)) проверить, что таймер запущен, и обнулить его (тот же самый таймер).



  • @Erik Добрый день

    На основе шаблона сделал сценарий.

    ...
    startOnChange([motion], motion.isOn() && lamp.isOff() && sw.isOFF() && SAF.isOFF());
    

    Сценарий не запустился ни разу. Хотя датчик присутствия срабатывает. При уменьшении количества условий он начинает иногда срабатывать.

    Это условие не работает, так как синтаксис sw.isOFF() не опознается. Большие/малые буквы в JavaScript очень важны!! Должно быть sw.isOff()

    ПОменял скрипт на следующий

    startOnChange([motion], motion.isOn());
    
    script ({
    
        start() {
          if ((SAF.value === 0) && (sw.value === 0) && (lamp.value === 0)) {
          lamp.on();
          // взводим таймер, чтобы отключить 
          this.startTimer("T1", 180, "turnOff");       
              }
          },
         
        // Функция, которая сработает, когда таймер досчитает - отключаем и выходим
        turnOff() {
          lamp.off();
          // this.exit();  Эту команду можно не ставить, сценарий и сам завершится
        }
    });
    

    Скрипт запускается, но.
    Запустить второй раз сразу после выключения света по таймеру не получается.
    Второй рах скрипт срабатывает только через какое-то время, которое мне определить не удалось.
    Датчик движения срабатывает, а свет не включается, если он только что выключился.

    Что может влиять? К факту выключения света привязат скрипт включения ветнилятора на 2 минуты.
    Может быть из-за него?
    Таймеры в скриптах по разному обозвать? ...

    Нет, связи между экземплярами сценария даже по одному мультисценарию никакой нет. У вас сценарии управляют разными устройствами, то есть полностью независимы.
    Скорее не проходит проверка условия со строгим равенством
    Замените условие на один из трех вариантов (любой)

     if (SAF.isOff() && sw.isOff() && lamp.isOff()) { 
    // ИЛИ
     if (!SAF.value && !sw.value && !lamp.value) {
    // ИЛИ
     if ((SAF.value == 0) && (sw.value == 0) && (lamp.value == 0)) { 
    


  • Участник @intrapro написал в Свет по датчику движения с дополнительными условиями.:

    lamp.value == 0)

    Не дает исправить на ==
    alt text

    Ну и спустя какое то время он выполняется. Только сразу после выключения почему-то нет.
    Поэтому не понятно, почему проверка в одном случае проходит, во втором нет.



  • Участник @Erik написал

    И еще вопрос.

    Как при включенном по датчику движения свете по повторному срабатыванию датчика движения обнулять таймер?

    При условии if ((SAF.value === 0) && (sw.value === 0) && (lamp.value == 1)) проверить, что таймер запущен, и обнулить его (тот же самый таймер).

    Для этого нужно добавить внутрь сценария "слушателя событий"

    script({
        start() {
          if ((SAF.value === 0) && (sw.value === 0) && (lamp.value === 0)) {
             lamp.on();
             // взводим таймер, чтобы отключить 
             this.startTimer("T1", 180, "turnOff");       
            
            // Добавляем слушателей - следим за датчиком движения и светильником
            this.addListener(motion, "onMotion");
            this.addListener(lamp, "onLamp");
          }
        },
        
        onMotion() {
          // Если движение возобновилось - сбрасываем таймер
          if (motion.isOn() )  {
            this.stopTimer("T1");
          }  
           // Если движение прекратилось - взводим таймер (после повторных движений)
          if (motion.isOff() && this.timer.T1 == "off")  {
            this.startTimer("T1",  180, "turnOff");
          }  
        },
        
         onLamp() {
          // Светильник выключили другим способом - выходим
           if (lamp.isOff()) this.exit();
         },
         
        // Функция, которая сработает, когда таймер досчитает - отключаем и выходим
        turnOff() {
          lamp.off();
          this.exit(); // Здесь exit нужен, так как есть активные слушатели и сценарий сам не завершится
        }
    });
    

    Более подробно про механизм работы сценариев - https://ih-systems.com/ru/about-scenes/
    Если коротко:

    • Если внутри сценария просто последовательность действий, он отработает и сразу завершится (станет не активным). При следующем запуске он опять начнется со start(). Большая часть сценариев работает именно так и 99,9% времени находятся в неактивном состоянии.

    • Если сценарий взводит таймеры и/или устанавливает слушателя событий устройства, то он остается активным, следит за своими таймерами и устройствами «изнутри» и выполняет действия как реакцию на отслеживаемые события. Стартовое событие не работает, так как сценарий уже активен.. В рабочих сценариях в левом столбце у сценариев, активных в данный момент, стоит зеленая галочка.
      Чтобы завершить такой сценарий, нужно выполнить команду this.exit().
      При завершении сценария все его таймеры и слушатели удаляются. При следующем запуске опять выполнится start()



  • @Erik Это warning, можете его игнорировать, если вы все же остановились на этом варианте 🙂 Строгое равенство предполагает ноль как число. Возможно в каком-то случае ноль приходит как строка или булево значение.



  • Участник @intrapro написал в Свет по датчику движения с дополнительными условиями.:

    @Erik Это warning, можете его игнорировать, если вы все же остановились на этом варианте 🙂 Строгое равенство предполагает ноль как число. Возможно в каком-то случае ноль приходит как строка или булево значение.

    Почему потом срабатывает то? кто его трансформирует из строки в число?



  • @Erik Вы можете посмотреть в отладчике сценария и добавить логирование:

     start() {
        this.log(`SAF=${SAF.value}   sw=${sw.value}  lamp=${lamp.value}`); // используется обратная кавычка!
    
        if ((SAF.value === 0) && (sw.value === 0) && (lamp.value === 0)) {
             lamp.on();
             .....
        } else {
           this.log('Условия не выполнены');
        }
    },
    

    Собственно, для того чтобы не возникало таких вопросов существуют функции isOff() и isOn()



  • Участник @intrapro написал в [Свет по датчику движения с дополнительными условиями.]

    Для этого нужно добавить внутрь сценария "слушателя событий"

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

    Добавил еще слушатель на выключатель. Если включить выключатель, все таймеры выключатся, и отключения не произойдет.

    /** 
    * @name Свет в комнате по движению  
    * @desc  
    * @version 4  
    */
    
    const Lamp = Device("ActorD", "Светильник");
    const Sw = Device("SensorD", "Выключатель");
    const Motion = Device("SensorD", "Датчик движения"); 
    const SAF = Device("ActorD","Охрана"); 
    
    // Запустим сценарий при сработке датчика движения, если светильник не горит, режим охраны отключен, выключатель выключен. 
    startOnChange([Motion], Motion.isOn() && Lamp.isOff() && Sw.isOff() && SAF.isOff());
    
    script({
        start() {
             Lamp.on();
             // взводим таймер, чтобы отключить 
             this.startTimer("T1", 180, "turnOff");       
            
            // Добавляем слушателей - следим за датчиком движения и светильником
            this.addListener(Motion, "onMotion");
            this.addListener(Lamp, "onLamp");
            this.addListener(Sw, "onSw");
        },
        
        onMotion() {
          // Если движение возобновилось - сбрасываем таймер
          if (Motion.isOn() )  {
            this.stopTimer("T1");
          }  
           // Если движение прекратилось - взводим таймер (после повторных движений)
          if (Motion.isOff() && this.timer.T1 == "off")  {
            this.startTimer("T1",  180, "turnOff");
          }  
        },
        
         onLamp() {
          // Светильник выключили другим способом - выходим
           if (Lamp.isOff()) this.exit();
         },
         
         onSw() {
          // Светильник выключили другим способом - выходим
            if (Sw.isOn() )  {
            this.stopTimer("T1");
          this.exit();
            }
         },
    
        // Функция, которая сработает, когда таймер досчитает - отключаем и выходим
        turnOff() {
          Lamp.off();
          this.exit(); // Здесь exit нужен, так как есть активные слушатели и сценарий сам не завершится
        }
    });
    

Log in to reply