Сторонний проект Интернета вещей в моей компании начался, когда мы не смогли переустановить дверной замок, который достался от предыдущего арендатора. Это была одна из тех мелочей, о которых мы узнали после переезда в новый офис.
Обычно люди просто платят за новый замок. Но для нас это было слишком мелко, и никто не хотел дверной звонок. К тому же, мы инженеры — и хотели поиграть с каким-нибудь железом.
Цель была в том, чтобы открывать дверь телефоном или носимым гаджетом. Было несколько способов, как подойти к проблеме. В теории, мы могли использовать приложение, интеграцию в другую платформу или всё, что может отправить сигнал для открытия замка.
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)
Regis
23.06.2017 17:11Что будет, если AWS снова "приляжет"? Вы не сможете войти в офис?
kirillaristov
23.06.2017 21:14Да, делать замок, рассчитывая на постоянную стабильность двух каналов связи (телефон-облако, облако-офис) — это оптимистично.
А вот сделать бы это с помощью rfid, вклеенного в телефон — было бы и удобно и надежно.
nbytes
23.06.2017 21:15Это же перевод, плюс ко всему тут вроде есть реализация через BT, а вот что делать если приляжет электростанция.
bano-notit
23.06.2017 23:57Тогда, мой старый друг ;D, поможет стандартный метод с отвёрткой и молотком. Да и вообще говоря, там на фотографии даже есть замочная скважина, так что физический метод вполне сработает.
Germanets
26.06.2017 09:39Да и вообще говоря, там на фотографии даже есть замочная скважина, так что физический метод вполне сработает.
— управляемый замок, судя по статье — электромагнитный, а тот, что на двери — это уже второй, механический. Так что если вдруг всё это дело решит повиснуть и больше не открывать двери, а в офисе никого не будет — придётся искать обходные пути… Самый печальный вариант — отключать свет и ждать, пока разрядится аккумулятор на замке, если такой есть.bano-notit
27.06.2017 02:35Но метод с отвёрткой и молотком всё же сработает, дверь то стандартная офисная, а не семислойная гаражная с интереснейшим механизмом нескольких обратных засовов...
superconductor
24.06.2017 09:21Отличный троллинг на тему IoT и управления через смартфон! А если это не троллинг, то я поражен масштабами overengineering'а на тему удалённого открывания замка.
D3fl4t3
24.06.2017 10:29Интересно, и сколько времени проходит от момента нажатия кнопки до разблокировки двери? Даже секунда будет раздражать, если дверь открывают достаточно часто, и, как мне кажется, смарт-карты в этом плане гораздо удобнее.
VMichael
А зачем все это?
Следующий этап — как накатить патч на замок и что делать есть хакнули ваш замок?
TimsTims
Нет, следующий — собирать метрику входа / выхода людей, доставки пиццы, и датчика температуры. Анализ и прогнозирования изнашивания замка. Снятие пульса и температуры ладони с открывающего дверь человека и ведение его медицинской био-карты, а затем большой анализ всего этого и называние это big data, ведь люди любят все усложнять.
myrkoxx
Не знаю, как на счет вашего примера, но вот если бы эта штука автоматически открывала двери (именно открывала, не только замок) то било б огонь. Идешь такой с сумками, а тебе дверь раз и открылась когда подошел. Не надо ставить их на пол, доставать ключи из сумки/кармана.
VMichael
Ну это (открытие двери) не сложно сделать.