Подключение контроллера MegaD-328

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

Модератор: immortal

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

Re: Подключение контроллера MegaD-328

Сообщение Bagir » Ср дек 10, 2014 8:39 pm

Я еще поигрался с копкой и разными нажатиями. Если очень часто наживать, то Мега может не успеть обработать все нажатия и отпускания, и не сообщит серверу. При этом во временной переменной получится запись, несоответствующая ни одной группе case последнего блока switch ($dt). Тогда прозвучит слово "непонятно". Но это увы не все. Может получиться так, что последнее сообщение от Меги будет о нажатии. Тогда по истечению таймера код посчитает это удержанием. А удержания то нет... И при следующем нажатии запись во временную переменную будет продолжена, а не начата заново, и потом при сравнении опять будет "непонятно". Решение есть. Надо при каждом начале нажатий новой комбинации просто для верности чистить временную переменную. С наименьшими затратами на обработку, можно добавить код сброса временной переменной

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

          // Сбросить временную переменную
          registerEvent($ot.'_'.$params['pt'].'_clicks', $details='1', $expire_in=1);
в момент, когда происходит событие нажатия и таймер не существует. Это и будет начало новой комбинации. Таким образом, даже если Мега не успела обработать комбинацию нажатий, то мы в любом случае не рискуем следующей комбинацией. Она точно будет писаться "с чистого листа".
Полный код всей группы caseПоказать

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

  case 3: // P&R //Задача - Получить любые комбинации
    // Получаем детали события
    $dt = registeredEventDetails($ot.'_'.$params['pt'].'_clicks');
    
    // Параметр doit будет добавлен при последующем рекурсивном вызове для окончания обработки комбинации нажатия
    if (!isset($params['doit'])) { 
      // Добавить состояние (нажата/отпущена) и записать в детали события
      registerEvent($ot.'_'.$params['pt'].'_clicks', $details=$dt.$ms, $expire_in=1);
      // Если таймер не существует 
      if (!timeOutExists($ot.'_'.$params['pt'].'_press')) {
        // Нажата или отпущена
        if ($ms) {
          // Сбросить временную переменную
          registerEvent($ot.'_'.$params['pt'].'_clicks', $details='1', $expire_in=1);
          // создать таймер с рекурсивным вызовом
          setTimeOut($ot.'_'.$params['pt'].'_press', "cm($ot.'.incomingMessage', array('pt'=>".$params['pt'].", 'doit'=>1));", 1);
        } else {
          // сразу рекурсивный вызов
          callMethod($ot.'.incomingMessage', array('pt'=>$params['pt'], 'doit'=>1));
        }  
      }

    } else { // параметр doit есть. Значит это рекурсивный вызов для окончания обработки комбинации нажатия
      // если справа 1 (то есть последнее действие нажал)
      if (substr($dt, -1)) {
        registerEvent($ot.'_'.$params['pt'].'_clicks', $details=$dt.'-', $expire_in=1);
      } else {
        registerEvent($ot.'_'.$params['pt'].'_clicks', $details='', $expire_in=1); // тут можно просто удалять
      }  
      /* Закомментировать или удалить этот блок switch после отладки */
      switch ($dt) {  //1-нажал 0-отпустил
      case '10':      say('нажатие');                  break;
      case '1010':    say('двойное нажатие');          break;
      case '101010':  say('тройное нажатие');          break;
      case '1':       say('удержание');                break;
      case '101':     say('удержание после двойного'); break;
      case '10101':   say('удержание после тройного'); break;
      case '1-0':     say('отпустил');                 break;
      case '101-0':   say('отпустил после двойного');  break;
      case '10101-0': say('отпустил после тройного');  break;
      default:        say('непонятно');             break;
      }

      // ВЫПОЛНИТЬ нужный метод с передачей ему кода комбинации $dt
    }
    break;
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 375 раз

Отлов разных нажатий для режима P

Сообщение Bagir » Ср дек 10, 2014 9:13 pm

А вот и вариант для режима P. Начало я оставил точно такое же как и у кода с режимом P&R. А вот кусок кода, который выполняется после рекурсивного вызова будет совсем другой. Тут уже не нужно сравнивать, а достаточно просто посчитать количество циферок во временной переменной. Надо заметить, что в режиме P Мега видит нажатия лучше. Это и понятно, сообщений то в два раза меньше. Лично у меня получалось весьма стабильно накликивать до 6 нажатий за секунду. Конечно на практике наврятли кто то решит повесить на 6 нажатий какое то действие. Все таки 3 клика это предел границы функционала и удобства.
Но подобные игры навели на мысль, где можно это использовать. Это же пин код!
группа case для режима PПоказать

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

  case 3: // P //Задача - Определить простое, двойное или тройное нажатие
    // Получаем детали события
    $dt = registeredEventDetails($ot.'_'.$params['pt'].'_clicks');
    
    // Параметр doit будет добавлен только при последующем рекурсивном вызове для окончания обработки комбинации нажатия
    if (!isset($params['doit'])) { 
      // Добавить состояние (нажата/отпущена) и записать в детали события
      registerEvent($ot.'_'.$params['pt'].'_clicks', $details=$dt.$ms, $expire_in=1);
      // Если таймер не существует 
      if (!timeOutExists($ot.'_'.$params['pt'].'_press')) {
        // Нажата или отпущена
        if ($ms) {
          // Сбросить временную переменную
          registerEvent($ot.'_'.$params['pt'].'_clicks', $details='1', $expire_in=1);
          // создать таймер с рекурсивным вызовом
          setTimeOut($ot.'_'.$params['pt'].'_press', "cm($ot.'.incomingMessage', array('pt'=>".$params['pt'].", 'doit'=>1));", 1);
        } else {
          // сразу рекурсивный вызов
          callMethod($ot.'.incomingMessage', array('pt'=>$params['pt'], 'doit'=>1));
        }  
      }

    } else { // параметр doit есть. Значит это рекурсивный вызов для окончания обработки комбинации нажатия
      // Очистить временную переменную
      registerEvent($ot.'_'.$params['pt'].'_clicks', $details='', $expire_in=1); // тут можно просто удалять
      // Посчитать количество циферок
      $dt = strlen($dt);
      say($dt.' нажатий');

      // ВЫПОЛНИТЬ нужный метод с передачей ему $dt как число нажатий
    }
    break; 
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 375 раз

Дверной звонок + ПинКод на открытие двери

Сообщение Bagir » Чт дек 11, 2014 12:30 am

У меня кнопка дверного звонка подключена к МД. При нажатии звучит рингтон звонка, и камера домофона делает фотку. Часто приходится выходить в сад. В это время дома может кто то оставаться, а может никого и не быть, но если я далеко не ухожу, то и нет смысла запирать дверь на глухой замок и ставить сигнализацию. Но и просто так оставлять открытой дверь тоже нельзя. Мало ли кто там шарахается, а за домом мне не видно. Именно на такой слечай и хотелось какюю нибудь простенькую экспресс открывалку двери, чтобы не таскать с собой карточку. Конечно хочется по фото. Смотришь в камеру, жмешь кнопку звонка, а дальше либо звенит звонок, либо открывается дверь, если фотка опознана и лицо есть в базе. Но уы, ничего я не нашел. Сравнение лиц на фотографиях вероятно дело будущего. Хотя странно. Телефоны уже это давно делают, и причем вполне хорошо, а для компа варианты не находятся. Думал про сканер отпечатков пальца. Уличные варианты стоят весьма дорого. Так что решил пока на это дело забить. Но есть идея! Использовать пин код на кнопке звонка. Конечно гость может его подслучать. Но гость так же момет увидеть кнопки на наборнике. К тому же никто не мешает при наборе добавить в начало несколько ложных случайных цифр, а в конце вбить правильные. Да и можно создать второй пин код, который бы отменял первый, как два набора ключей в дверях. Такой режим весьма сгодится, если объект не на охране. А вообще, вариант с простеньким пинкодом намного лучше варианта просто с открытой дверью.
Заценяйте, я результатом весьма доволен.
Дверной звонок + ПинКод на открытиеПоказать

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

  case 3: // P // Звонок + ПинКод
  /* 
  Пинкод задуман длинной в 3 цифры. Это можно легко изменить при жлании. 
  При наборе цифры 3 и более звонок не включается.
  Последняя цифра пинкода может быть 2, и если пин правильный, то звонок не включится
  */
    // Получаем детали события
    $dt = registeredEventDetails($ot.'_'.$params['pt'].'_pin');

    // Параметр doit будет добавлен только при последующем рекурсивном вызове когда отработает таймер
    if (!isset($params['doit'])) { 
      // Если таймер существует 
      if (timeOutExists($ot.'_'.$params['pt'].'_press')) {     
        // Удалить таймер
        ClearTimeOut($ot.'_'.$params['pt'].'_press');  
        // Добавляем +1  
        $dt = $dt+1;

      } else {
        // Взять две последние цифры
        // Если есть способ проще, ПОПРАВЬТЕ!
        if (strlen($dt)>2) { $dt = substr($dt, -2); }
        // к двум последним цифрам ВП приклеиваем 1
        $dt = $dt.'1';
      }
      // записать детали в событие
      registerEvent($ot.'_'.$params['pt'].'_pin', $details=$dt, $expire_in=1);
      // создаем таймер  
      setTimeOut($ot.'_'.$params['pt'].'_press', "cm($ot.'.incomingMessage', array('pt'=>".$params['pt'].", 'doit'=>1));", 1);

    } else { // параметр doit есть. Значит это рекурсивный вызов для проверки пинкода или включения звонка
      // Проверяем пинкод * * * * * * * * 
      if ($dt == 342) {
        // Очистить временную переменную (чтобы пин лишний раз не был виден в X-Ray)
        registerEvent($ot.'_'.$params['pt'].'_pin', $details='', $expire_in=1); // тут можно просто удалять Event
        // Событие правильный пин код
        say('пин код');
      } else {
        // Если набранная цифра меньше 3, включаем звонок      
        if (substr($dt, -1)<3) {
          // Событие Звонок
          say('звонок');
        }      
      }
    }
    break;
За это сообщение автора Bagir поблагодарил:
odinvolk (Пт фев 02, 2018 9:37 am)
Рейтинг: 1.16%
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
zelevova
Сообщения: 291
Зарегистрирован: Вт ноя 18, 2014 11:43 pm
Откуда: Краснодарский край
Благодарил (а): 32 раза
Поблагодарили: 68 раз

Re: Дверной звонок + ПинКод на открытие двери

Сообщение zelevova » Чт дек 11, 2014 10:10 am

Bagir писал(а):Конечно хочется по фото. Смотришь в камеру, жмешь кнопку звонка, а дальше либо звенит звонок, либо открывается дверь, если фотка опознана и лицо есть в базе. Но уы, ничего я не нашел. Сравнение лиц на фотографиях вероятно дело будущего. Хотя странно. Телефоны уже это давно делают, и причем вполне хорошо, а для компа варианты не находятся
Посмотри в сторону http://ab-log.ru/smart-house/video_came ... -detection

На тему проверки доступности меги: может просто в incomingMessage указывать что мега жива и запускать таймер что бы при любом срабатывании или опросе порта подтверждалось что она жива, тогда не надо ее регулярно опрашивать.
Majordomo (GitHub) на cubietruck + MegaD + 1-wire
CONNECT: http://connect.smartliving.ru/profile/311
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 375 раз

Re: Подключение контроллера MegaD-328

Сообщение Bagir » Чт дек 11, 2014 2:36 pm

OpenCV + FANN, давненько я уже пробовал подбить клинья к этим библиотекам. Возможно стоит попробовать еще раз. Может быть кто то и раскрутить это тему. Интересно, как это все будет работать на винде.
Перезапускать таймер при получении любого сообщения от Меги - идея хорошая. Но подойдет она только если с Мегой идет частый обмен сообщениями. У меня не все такие. Например к одной Меге я могу вообще несколько часов не обработаться, и она мне ничего не пришлет. Конечно когда будут задействованы больше портов, то и обмен сообщениями пойдет веселей. Так что способ интересный, но не всем подойдет. Хотя можно объединить эти способы. Тогда можно сильно увеличить временной интервал опроса температуры.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
zelevova
Сообщения: 291
Зарегистрирован: Вт ноя 18, 2014 11:43 pm
Откуда: Краснодарский край
Благодарил (а): 32 раза
Поблагодарили: 68 раз

Re: Подключение контроллера MegaD-328

Сообщение zelevova » Пн дек 15, 2014 12:36 pm

Что то у меня датчик освещенности неровно работает.
Пришлось для АЦП портов сделать как у разработчика Меги, а именно в getData скорректировал следующий текст:
СпойлерПоказать

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

// Запрос данных у Меги
if($params['port'] == 14 || $params['port'] == 15) {
    // Опрашиваем датчик несколько раз, берем значение, близкое к минимальному
    for ( $i = 0; $i < 5; $i++ )
    {
        $cur_val[] = trim(file_get_contents($cmdUrl, 0, $ctx));
        sleep(3);
    }
    sort($cur_val);
    $dt = $cur_val[1];
} else {
    $dt = trim(file_get_contents($cmdUrl, 0, $ctx));
}
У кого то еще есть такие проблемы?
Majordomo (GitHub) на cubietruck + MegaD + 1-wire
CONNECT: http://connect.smartliving.ru/profile/311
zelevova
Сообщения: 291
Зарегистрирован: Вт ноя 18, 2014 11:43 pm
Откуда: Краснодарский край
Благодарил (а): 32 раза
Поблагодарили: 68 раз

Re: Подключение контроллера MegaD-328

Сообщение zelevova » Пн дек 15, 2014 1:00 pm

Еще можно код:

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

$alive_timeout=(int)$this->getProperty('aliveTimeOut');
if (!$alive_timeout) { $alive_timeout=15*60; }
clearTimeOut($ot."_check_alive");
setTimeOut($ot."_check_alive","callMethod('".$ot.".getData(), array('port'=>'tget')',0);",$alive_timeout); 
Вставить в incomingMessage и тогда после первого опроса меги или прихода от нее сообщения она сама себя по таймеру будет проверять на живучесть и не придется регулярно ее опрашивать. Как такая идея?

PS: Код примерный пока не придумал куда именно его вставить.
Majordomo (GitHub) на cubietruck + MegaD + 1-wire
CONNECT: http://connect.smartliving.ru/profile/311
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 375 раз

Re: Подключение контроллера MegaD-328

Сообщение Bagir » Пн дек 15, 2014 1:27 pm

Проверка самой себя по таймауту после последнего обмена сообщениями - штука крайне интересная! Надо будет оформить как один из возможных вариантов на выбор. Получать данные температуры мне тоже интересно, но так часто вроде и не нужно. И так база данных пухнет. Так что при таком варианте, я бы мог намного реже запрашивать данные температуры Меги, а в промежутках код Меги будет проверять ее сам по таймауту.

На счет АЦП портов. Работают они так то нормально. И если датчик хороший и провод короткий, то большого разбега в показаниях не будет. Но при других условиях ситуация хуже. У меня сейчас два датчика. Освещенности и газа. Освещенность вообще грубо работает. К вечеру показания прыгают от 0 до 5. А это вообще никуда не годится. Но как вариант, Я просто спрашиваю данные почаще, а потом беру из базы среднее значение за определенный период времени. Пока это устраивает. Но у объекта должна быть включена история. А для этого его приходится запихивать в подкласс.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
zelevova
Сообщения: 291
Зарегистрирован: Вт ноя 18, 2014 11:43 pm
Откуда: Краснодарский край
Благодарил (а): 32 раза
Поблагодарили: 68 раз

Re: Подключение контроллера MegaD-328

Сообщение zelevova » Пн дек 15, 2014 1:48 pm

Я пока на самописном ядре сидел, подсмотрел у Андрея. У него алгоритм такой и мне он помог избавиться от скачков когда на улице совсем темно, а датчик может показывать временные просветления до 5 - 10% и лишнюю информацию в базу не писать.
Датчик газа только повесил, еще не могу понять его показания.

Ты отличный класс написал. Хотелось бы время от времени синхронизировать основные изменения с ним. :)
Majordomo (GitHub) на cubietruck + MegaD + 1-wire
CONNECT: http://connect.smartliving.ru/profile/311
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 375 раз

Re: Подключение контроллера MegaD-328

Сообщение Bagir » Пн дек 15, 2014 4:34 pm

zelevova писал(а):Ты отличный класс написал. Хотелось бы время от времени синхронизировать основные изменения с ним. :)
Спасибо )) Я часто в коннект все скидываю. От туда можно взять любой кусок кода. А то обновлять весь класс конечно неудобно. Много чего теряется из своих настроек. Да и класс уже вполне нормальный. В дальнейшем наврятли будет что то сильно меняться. Просто будут добавляться разные полезности, такие как отлов разных нажатий, набор пин кода и т.д. Это все по отдельности я и тут выкладываю, и в коннекте есть. Так что полное обновление можно уже и не делать.
На счет временного просветления да, тоже было. И с этим ничего не поделать. Слишком уж велика цена деления у датчика, и четко поймать момент сумерек довольно сложно. Варианта два. Либо как у тебя, несколько раз опросить порт и взять среднее, либо периодически почаще опрашивать и брать среднее уже из базы данных. Лишние записи при этом конечно будут. Ну пока что полет нормальный. Опрашиваю каждые 5 минут, а среднее беру за 15 минут. Как меньше 1, значит темно, и будет разрешение для включения прожекторов при движении. А вот слабенький свет у крыльца планирую включать пораньше. Посмотрим, как получится на деле.
Такая же ситуация у меня и с датчиком газа в воздуховоде приточной вентиляции. Опрашиваю каждую минуту, чтобы вовремя закрыть заслонку.
В связи с этим давно есть просьба для Сергея. Сейчас минимальный период записей в историю 1 день. Хотелось бы получить альтернативу в количествах записей. Например для датчика света я бы поставил 10 записей. Это позволило бы мне писать чаще и не задумываться о размерах базы данных. Но я пока что не представляю как сейчас устроен механизм удаления старых записей, и как часто он запускается.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Ответить