Как переусложнить дверной замок

https://medium.freecodecamp.com/how-to-over-engineer-a-door-lock-863b5d58dd0d
  • Перевод


Сторонний проект Интернета вещей в моей компании начался, когда мы не смогли переустановить дверной замок, который достался от предыдущего арендатора. Это была одна из тех мелочей, о которых мы узнали после переезда в новый офис.

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

Цель была в том, чтобы открывать дверь телефоном или носимым гаджетом. Было несколько способов, как подойти к проблеме. В теории, мы могли использовать приложение, интеграцию в другую платформу или всё, что может отправить сигнал для открытия замка.


Chima Open Door на Pebble и iOS

К настоящему моменту в нашем дверном эксперименте мы разработали решения для интеграции со Slack, нативные приложения iOS и Android, Apple Watch и Pebble. Остановлюсь подробнее на архитектуре мобильных приложений. Признаю, что финальный продукт слегка переусложнён, но мы так его любим!


Архитектура проекта нашего IoT дверного замка

Что конкретно происходит, когда вы нажимаете кнопку в своём приложении iOS/Android? Отправляется HTTP-запрос к облачному серверу, который является сигналом для отправки сообщения к демону дверного звонка через клиентский сервер, который затем указывает релейной плате открыть замок.

Традиционно дверной замок открывается нажатием кнопки рядом с дверью. Но современные технологии позволяют выйти за пределы непосредственной физической кнопки. Вдобавок к физической кнопке, которая сигнализирует Doorlock Daemon на диаграмме, мы добавили ещё два триггера: облачный триггер и Bluetooth Low Energy (BLE) триггер, благодаря нашему выбору железа.

В этой статье описывается облачный триггер, на который полагается ваш дверной замок.

С нажатия кнопки до записи, сохранённой на сервере Skygear



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

Две вещи происходят на облачном сервере. Во-первых, сохраняется запись. Мы выбрали сервер Skygear Cloud Database, который позволяет синхронизировать данные с облаком. Сервер ведёт лог запросов на открытие двери.

SKYDatabase *db = [[SKYContainer defaultContainer] publicCloudDatabase];
SKYRecord *openDoor = [SKYRecord recordWithRecordType:@"OpenDoor"];
[db saveRecord:openDoor completion:^(SKYRecord *record, NSError *error) {
    NSLog(@"saveOpenDoorRecordWithCompletion failed: %@", error);
    if (completion) {
        completion(error);
    }
}];

Как только запись сохранилась, срабатывает функция after_save из набора Skygear Cloud Functions, которая запускает в облаке наш код без необходимости развёртывания непосредственно на сервере.

Функция after_save вызывается самим фактом сохранения записи. Асинхронно вызывается def after_open_door_save(record, original_record, db):, когда сохраняется запись типа 'OpenDoor'. Эта функция публикует сообщение в канале 'xxx-channel'.

@skygear.after_save('OpenDoor', async=True)
def after_open_door_save(record, original_record, db):
    publish('xxx-channel', {
        'source': 'record-after-save',
        'data': record.get('data', None),
    })

Node Client и Clojure Server на Raspberry Pi


Следующий шаг — создать слушателя для запроса. Вот где пришло время клиента Node и сервера Clojure на Raspberry Pi. Клиент Node слушает сообщения на указанном канале сервера Skygear. Сервер Clojure — единственный, у кого есть право доступа к схеме Raspberry Pi 3. Клиент Node выдаёт запрос к серверу Clojure, как только получает сообщение.

Вот скрипт клиента Node, он содержит код, связанный с нашей конкретной конфигураций на Skygear. Указанные endPoint и API Key нужны для доступа к основному серверу на Skygear. skygear.on('xxx-channel', onReceiveOpenDoor) означает обратный вызов функции (onReceiveOpenDoor) при получении сообщения на канале 'xxx-channel'.

function onReceiveOpenDoor(data) {
  console.log('daemon-trigger-skygear: open door');
  exec(`curl localhost:8090 --header 'X-Source: Skygear'`);
}
 
skygear.config({
  endPoint: 'https://chimagun.skygeario.com/',
  apiKey: apiKey,
}).then(() => {
  skygear.loginWithUsername('xxx', 'xxx').then(() => {
    skygear.on('xxx-channel', onReceiveOpenDoor);
  });
});

Сервер Clojure напрямую контролирует контакты General Purpose Input/Output (GPIO) на Raspberry Pi. GPIO это штырьки на Raspberry Pi 3. Они подключены к внешней цепи, которая соединяется с дверным магнитом.



Вот код Clojure, который показывает, как Raspberry Pi открывает дверь. Когда сервер Clojure получает запрос от клиента Node, то открывает замок на три секунды. Но если в течение этих трёх секунд поступит новый запрос, то таймер переставляется ещё на три секунды. Когда время заканчивается, дверь опять запирается.

; listen on unlock-chan for unlock events
  ; if a new unlock event is received before the 3000ms timeout, the door is kept open.
  (go-loop [unlock nil]
           (when unlock
             (sh "gpio" "write" "1" "1")
             (loop [[trigger _] [unlock nil]]
               (when trigger
                 (log/info (str "Unlock triggered by " (:source trigger)))
                 (recur (alts! [unlock-chan (timeout 3000)]))))
             (sh "gpio" "write" "1" "0")
             (log/info "Door Locked"))
           (recur (<! unlock-chan)))
 
  ; http event listener
  (run-server (fn [req]
                (>!! unlock-chan {:source (or (get-in req [:headers "x-source"]) :network)})
                {:status 200})
              {:ip "127.0.0.1" :port 8090})

Примечание: Skygear использует американский AWS, тогда как дверь и Raspberry Pi находятся в Гонконге. Фактически, наш запрос 芝麻開門 (Chima Open Door) путешествует по всему миру, прежде чем достигнет двери.

Почему Raspberry Pi?


Вы можете спросить, почему мы выбрали именно Raspberry Pi. Мы рассматривали и платы Arduino, потому что у нас в офисе такие есть. Дело в том, что мы не могли использовать конкретную модель Arduino, поскольку хотели синхронизировать данные с Skygear JS SDK, а эта конкретная Arduino не позволяла установить сервер Node.

Кроме того, Raspberry Pi поддерживает Bluetooth Low Energy (это значит, что мы можем открывать дверь, используя третий метод, Bluetooth).


Raspberry Pi с Linux совместима с open-source бессерверной платформой Oursky



Дополнительные интеграции


Принимая во внимание, что приложение только для внутреннего использования, мы реализовали кастомную команду Slack /chima-open-door на открытие двери, поскольку каждый сотрудник Oursky имеет доступ к Slack.

Позже другие коллеги вовлеклись в проект и написали приложение WatchOS и приложение Android, которые мы выложили на внутренней платформе. Помимо нажатия кнопки внутри приложения, мы также обеспечиваем альтернативные способы открытия двери, такие как прикосновение iOS 3D, расширение Today, виджет Android и даже интеграция с Pebble, поскольку некоторые из наших разработчиков носят такие часы.



Вот так всё сделано! Прежде чем вы погрузитесь в разработку, учтите два фактора: обратный ток (в данном случае для Raspberry Pi) и безопасность каждой из ваших интеграций. Например, мы также интегрировали доступ Bluetooth-приложения через Bluetooth Low Energy (BLE), что является самостоятельно реализуемым вариантом двухфакторной аутентификации. Среди других интеграций можете рассмотреть уведомления, когда дверь открыта (звонок, светодиод).

Если хотите узнать о любой из упомянутых технологий, не стесняйтесь выходить на контакт!

Хочу выразить благодарность моим коллегам Дэвиду Нг, Борису (akiroz), Брайану (b壹貳參肆零零) и Мэю Юнгу за работу над Android-приложением, реализацию схемы и Clojure, приложение Pebble и текст этой статьи, соответственно. Это командная работа!



Ссылки на репозитории/файлы
CloudCode
Клиент iOS
Клиент Android
Клиент Pebble
Поделиться публикацией

Комментарии 22

    +4
    А зачем все это?
    Следующий этап — как накатить патч на замок и что делать есть хакнули ваш замок?
      0
      Нет, следующий — собирать метрику входа / выхода людей, доставки пиццы, и датчика температуры. Анализ и прогнозирования изнашивания замка. Снятие пульса и температуры ладони с открывающего дверь человека и ведение его медицинской био-карты, а затем большой анализ всего этого и называние это big data, ведь люди любят все усложнять.
        0
        Не знаю, как на счет вашего примера, но вот если бы эта штука автоматически открывала двери (именно открывала, не только замок) то било б огонь. Идешь такой с сумками, а тебе дверь раз и открылась когда подошел. Не надо ставить их на пол, доставать ключи из сумки/кармана.
          0
          Ну это (открытие двери) не сложно сделать.
      +1

      Теперь весь мир сможет узнать, что вы открыли дверь. :D

        0

        Что будет, если AWS снова "приляжет"? Вы не сможете войти в офис?

          0

          Да, делать замок, рассчитывая на постоянную стабильность двух каналов связи (телефон-облако, облако-офис) — это оптимистично.
          А вот сделать бы это с помощью rfid, вклеенного в телефон — было бы и удобно и надежно.

            0
            Это же перевод, плюс ко всему тут вроде есть реализация через BT, а вот что делать если приляжет электростанция.
              0
              с ноги
                0
                или предвидить клемы для подключения внешнего акумулятора
                0

                Тогда, мой старый друг ;D, поможет стандартный метод с отвёрткой и молотком. Да и вообще говоря, там на фотографии даже есть замочная скважина, так что физический метод вполне сработает.

                  0
                  Да и вообще говоря, там на фотографии даже есть замочная скважина, так что физический метод вполне сработает.
                  — управляемый замок, судя по статье — электромагнитный, а тот, что на двери — это уже второй, механический. Так что если вдруг всё это дело решит повиснуть и больше не открывать двери, а в офисе никого не будет — придётся искать обходные пути… Самый печальный вариант — отключать свет и ждать, пока разрядится аккумулятор на замке, если такой есть.
                    0

                    Но метод с отвёрткой и молотком всё же сработает, дверь то стандартная офисная, а не семислойная гаражная с интереснейшим механизмом нескольких обратных засовов...

              0

              Отличный троллинг на тему IoT и управления через смартфон! А если это не троллинг, то я поражен масштабами overengineering'а на тему удалённого открывания замка.

                0

                Интересно, и сколько времени проходит от момента нажатия кнопки до разблокировки двери? Даже секунда будет раздражать, если дверь открывают достаточно часто, и, как мне кажется, смарт-карты в этом плане гораздо удобнее.

                  0
                  Здорово написали ;) я думал, что слишком толсто, но таки повелись :)
                    0
                    замок с вайфаем — это еще не IoT
                      0

                      А у меня у одного не работают ссылки на gitlab?

                        0
                        В итоге Вы получили дверь, которую не открыть ключом, и которая откроется автоматически при пропаже напряжения в офисе?
                          0
                          Уж лучше такой вариант, чем самодельные непродуманные схемы, в которых есть источник резервного питания)
                          0
                          А можете дополнить пост или прикрепить к комментарием электрические схемы подключения и питания замка, кнопок, Raspberry Pi и т.д.?
                            0
                            Увидел, что перевод, вопрос отпал.

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                          Самое читаемое