Работая из дома и будучи поклонником Мэрилина Мэнсона, я обычно пропускаю стук в дверь. У нас есть дверной звонок, но он не так эффективен, как шумоподавление в моих наушниках.
Мои наушники подключены к телефону, что означает, что я могу пропустить кого-то у двери, но никогда не пропущу звонок. Как насчет того, чтобы создать умный дверной звонок, который будет звонить на мой телефон, когда кто-то подойдет к двери?
Мы будем использовать Node.js для создания бэкенда, чтобы взаимодействовать с Twilio, и создадим приложение для Android, которое будет работать на Raspberry Pi и служить нашим умным дверным звонком.
— Номер телефона Twilio. Зарегистрируйтесь бесплатно здесь.
— Android Things, запущенный на Raspberry Pi 3. Узнайте, как это сделать, в этом блоге.
— Android Studio.
— Установленный Node.js и ваш любимый редактор. Я буду использовать Visual Studio Code.
— Соединительные провода типа «папа-папа» и «папа-мама». Приобретите их здесь.
— Макетная плата на 400 точек. Приобретите её здесь.
— Резистор 1K Ω (коричневый, черный, красный, золотой). Запаситесь резисторами разных номиналов, они всегда пригодятся.
— Тактильная кнопка для использования в качестве триггера. Приобретите их разных цветов для большего удовольствия.
Начнем с создания бэкенда нашего приложения. Он использует API Twilio для звонка на наш номер, когда кто-то нажимает на дверной звонок.
Откройте новое окно терминала и создайте новую папку под названием `Doorbell`. Я обычно создаю свои проекты в `~/Projects/JavaScript`.
Теперь у вас должен быть файл `package.json` и папка `node_modules`, в которой будут библиотеки `twilio` и `express` среди прочих.
В папке `Doorbell` создайте новый файл `index.js` и откройте его в вашем любимом редакторе. В этом файле создайте базовое приложение Express, чтобы убедиться, что ваша настройка готова к работе.
Под существующим маршрутом «/» мы создадим еще два маршрута. Один из них будет генерировать TwiML с голосовым сообщением, а другой будет инициировать звонок с нашего номера Twilio на наш реальный номер телефона.
Обратите внимание, как мы установили `greetingUrl` в качестве внутреннего запроса внутри нашего приложения. Когда звонок начинается, Twilio делает запрос к `/call`, и наше приложение сообщает Twilio, откуда получить TwiML.
Я использую переменные окружения для установки учетных данных аккаунта и номеров телефонов. Мой коллега Доминик написал статью о том, как установить переменные окружения в Windows, macOS и Linux. Если вы не хотите этого делать, вы можете заменить значения `process.env.TWILIO_ACCOUNT_SID`, `process.env.TWILIO_AUTH_TOKEN`, `process.env.MY_NUMBER` и `process.env.TWILIO_NUMBER` на свои токены и номера телефонов, которые можно получить на панели управления Twilio.
Наш бэкенд готов, но попытка его запустить прямо сейчас приведет к ошибке, так как мы говорим Twilio обращаться к приложению, которое работает только на нашем локальном компьютере. Мы можем это исправить, запустив его с помощью ngrok. Мой коллега Кевин написал статью о том, как тестировать вебхуки локально с помощью ngrok.
Остановите и снова запустите приложение Node, а в новом окне терминала выполните команду:
Это даст вам URL для переадресации, который вы можете скопировать и вставить в браузер.
Переход по этому URL в браузере откроет страницу «Hello World», но если вы перейдете по маршруту `/call`, ваш телефон должен зазвонить, и вы получите сообщение о том, что «кто-то у двери».
Теперь давайте посмотрим, как использовать этот API с нашим приложением для Android Things.
Теперь, когда у нас работает бэкенд API, давайте подключим оборудование так, чтобы при нажатии кнопки наше приложение для Android Things отправляло запрос к нашему API, чтобы наши телефоны зазвонили.
Для этого мы будем использовать 3 пина на Raspberry Pi 3: BCM6 (31) как пин общего ввода-вывода, 5V (2) для питания и GND (39) как землю.
Также подключим нашу кнопку и резистор к макетной плате следующим образом:
Давайте посмотрим, что нужно для отслеживания нажатия кнопки и реакции на него с помощью вызова API.
Откройте Android Studio и создайте новый проект под названием Doorbell. Я храню все свои проекты для Android Things в `~/Projects/Android/Things`. Вы также можете посмотреть весь код этого проекта в этом репозитории.
Убедитесь, что минимальный SDK этого проекта — 24 или выше, так как Android Things совместим только начиная с Nougat.
Далее выберите `Empty Activity` и нажмите «Finish» на следующем экране, чтобы создать пустую активность.
Начнем с добавления некоторых зависимостей в наш новый проект Android и изменения манифеста, чтобы приложение имело нужные разрешения и, что самое важное, запускалось автоматически при включении Raspberry Pi. Это важно, так как у нас не будет интерфейса для запуска приложения на Raspberry Pi.
Откройте файл `build.gradle` уровня приложения и добавьте следующие зависимости:
Сначала мы добавляем Android Things и драйвер кнопки, который позволяет взаимодействовать с аппаратной кнопкой. Затем добавляем Retrofit, который значительно упростит потребление API нашего дверного звонка. Позвольте Gradle выполнить синхронизацию.
Откройте `AndroidManifest.xml` и запросите разрешение на `INTERNET`. Оно необходимо для выполнения внешних HTTP-запросов из приложения.
В манифесте добавьте новый фильтр намерений под существующим `.MainActivity`, чтобы приложение запускалось автоматически при загрузке.
Retrofit использует интерфейсы для генерации кода, который будет взаимодействовать с API. Создайте новый Java-класс `Doorbell` типа `Interface` рядом с `MainActivity` в пакете doorbell.
Внутри интерфейса `Doorbell` добавьте запрос `GET` к API дверного звонка.
Мы передаем `call` как атрибут к `@GET`, так как он напрямую соответствует маршруту нашего Node-приложения, который в данном случае — «/call».
Теперь откройте `MainActivity` и добавьте следующие переменные в начало класса:
Вы можете разрешить зависимости, нажав `Alt+Enter`, но будьте внимательны при разрешении `Button`, так как у вас будет несколько вариантов, и вам следует выбрать `com.google.android.things.contrib.driver.button.Button`.
Убедитесь, что вы изменили `BASE_URL` на URL, который вы получили от вашего сервера или ngrok, если вы запускаете приложение локально.
Под методом `onCreate` создайте новый метод под названием `initialiseDoorbellButton`. Этот метод зарегистрирует нашу физическую кнопку и добавит слушатель событий для нажатия кнопки.
Давайте создадим слушатель событий для нажатия кнопки.
В методе `onCreate` добавьте вызов `initialiseDoorbellButton();`, чтобы зарегистрировать кнопку и слушатель событий при запуске приложения.
Запустите приложение, нажав Run или `CTRL+R`. Если ваш Raspberry Pi не отображается в списке подключенных устройств, вернитесь в терминал и выполните команду `adb connect Android.local`. Теперь ваш Raspberry Pi должен появиться в списке.
После завершения сборки и установки приложения нажмите кнопку на макетной плате, и вы должны увидеть сообщение в `Android Monitor` каждый раз, когда вы нажимаете кнопку.
Отлично! Теперь мы интегрировали внешнее оборудование с нашим приложением для Android. Но звонки все еще не поступают.
В `MainActivity` добавьте вызов Retrofit внутри метода `onCreate` для выполнения запросов к API нашего дверного звонка.
Теперь мы хотим вызывать метод `startCall` в `mDoorbellApi` каждый раз, когда кто-то нажимает кнопку. Вернитесь к `Button.OnButtonEventListener` и под логом «нажатие кнопки» добавьте вызов нашего API.
Мы логируем идентификатор звонка или сообщение об ошибке в зависимости от результата нашего запроса к API.
Запустите приложение снова, и ваш телефон должен зазвонить, когда вы нажмете кнопку.
Теперь у нас есть умный дверной звонок, который будет звонить нам каждый раз, когда кто-то подходит к двери. Я знаю, что больше никогда не пропущу доставку посылки.
А как насчет использования камеры, чтобы также получать MMS-сообщение с фотографией человека, звонящего в дверь?
Свяжитесь со мной в Twitter по адресу @marcos_placona или по электронной почте marcos@twilio.com и расскажите, что вы создаете.