Управление Raspberry через websockets
Raspberry Pi снискали огромную популярность по всему миру. Однако многие из любителей-разработчиков сталкиваются с проблемой доступа к устройству из интернета. Как правило приходится необходимо колдовать с DDNS или докупать статический IP адрес. Оба варианта предполагают настройка роутера, что не для всех и не всегда доступно. Кроме того — откртытие прямого доступа к устройству из интрента несет в себе определнные риски безопасности.
Крайне распространенным способом решения этой проблемы является использование промежуточного сервера, через который сервер и клиент подключаются друг к другую.
Схема крайне широко используется в различных пакетах удаленного доступа: VNCViewer, AmmyyAdmin и т.д.
Вариант 1-DDNS
Вариант 2 — статический IP адрес
Вариант 3 — использование промежуточного сервера
Эту схему подключения можно реализовать через протокол MQTT over Websockets, но мне было инетесно реализовать что-то значительно более простое, JSON-ориентированое, расширяемое, без ограничений протокола на размер сообщения и с более очевидной моделью безопасности.
Выбор протокола был очевиден. WebSocket уже давно поддерживается браузерами и большинством платформ и языков программирования.
Модель шины данных тривиальна:
WebSocket cервер поддерживает неограниченное количество каналов. Каждый канал может быть как открытым, так и защищенным паролем. Канал существует только пока у нему подключен хотя-бы один клиент. Никакие жанные на сервере не принципиально не хранятся. Пароль задается первым клиентом подключившемся к каналу. Клиенты без пароля/с неправильным паролем в канал допущены не будут.
Канал является контейнером для сообщений. Сообщения бывают трех типов: адресные сообщения (команды), которые предназначены для одного или нескольких получателей, ответные сообщения и широковещательные сообщения которые будут получены всеми клиентами подключенными к каналу.
Такая схема позволяет относительно безопасно использовать общие хабы для многих потребителей т.к. нет никакой необходимости в настройках, генерации пользователей на сервере (как в MQTT), генерации ключей доступа и пр.
Сообщения нигде не сохраняются, не логируются и передаются по защищенному протоколу wss.
Сообщения — это типизированные JSON объекты. Бинарная информация передается как Base64 encoded string.
Код проекта доступен на GitHub, а действующий хаб вы можете найти здесь.
Проект состоит из WebSocket сервера на .net, web-приложения-клиента, которая подключается к серверу и python приложения для raspberry pi.
Веб-приложение — далеко не единственно возможный способ взаимодействия с websocket-сервером. Например, можно легко написать облачный клиент, который будет «слушать» события веб камеры и сохранять картинки в какое-нибудь облачное хранилище.
Архитектура позволяет подключать неограниченное число raspberry pi и клиентов на один канал.
Например если вы захотите построить некую систему безопасности/управления климатом/умным домом — вы можете все raspberry «посадить» на один канал и отправлять команды сразу всем или нектором инстансам.
Широковещательные события «broadcast» получат все участники сети.
Несколько слов о возможностях приложения
- Удаленный доступ к файловой системе. Можно смотреть, скачивать и загружать картинки, звуковые файлы и прочие файлы. Довольно удобно, чтобы не таскать весь свой многотерабатный архив фоток на телефоне. Ну или если нужно что-то поискать в архивах.
- PiCamera позволяет получать изображение как по запросу так и в режиме веб камеры. Наряду с получением звука с микрофона может использоваться как дешевое решение для безопасности. Требует подключенной pi-камеры.
- Отправка звукозаписей на raspberry или получение записи с микрофона. Можно использовать как для каких-то задач безопасности, так и для голосового взаимодействия с котами или детьми. Требует подключения к телевизору/колонке и микрофону соответсвенно.
- Включение/выключение/получение фокуса телевизора. CEC протокол позволяет управлять телевизором через HDMI кабель. Необходимо установить cec-client на raspberry.
- Отображение звуковой и текстовой информации на телевизоре. Эта функция включает включение и получение фокуса в телевизоре и отображение текстового сообщения, сопровождаемое звуковым сигналом. Удобно, если надо удаленно заставить детей делать уроки.
- Удаленное отображение картинки. Если вы хотитет сделать сюрприз своим родым и внезапно вывести на семейный телевизор фотографию ваших приключений — то эта функция как раз для этого. Выбираете любую картинку ПК или телефона и отправляете на raspberry.
- Получение данных о влажности, температур. Raspberry рассылает Broadcast сообщение с заданной перодичнсотью. Помимо влажности и температуры сообщение содержит информацию о температуре и загрузук процессора, загрузке диска и памяти. Совместно удаленным управлением портами ввода-вывода можно использовать в качестве дистанционного управления климатом в помещении. Для измерения температуры необходим датчик DHT11 ($1).
- Управление портами ввода-вывода. Позволяет как считать информацию с выбранных GPIO портов, так и вывести на них сигнал. Можно получать статус переключаетелей, зажигать лампочки, звонить в звоночки, а через реле управлять какими-то более серьезными приборами.
- Удаленный запуск комманд позволяет выолнять на raspberry любые shell команды. Например запустить просмотр фоотоальбома или фильма. Если такая возможность кажется вам небезопасной — эту функцию можно отключить.
To be continued…