Умное зеркало своими руками

в 13:15, , рубрики: diy или сделай сам, MagicMirror, Raspberry Pi, Блог компании RUVDS.com, разработка, Разработка для интернета вещей, Разработка на Raspberry Pi

Кому нужно умное зеркало? Много кому. Я, когда такое увидел, тут же захотел выбросить наш календарь с маркерной доской. Майкл Тиув проделал потрясающую работу по созданию отличной расширяемой платформы для умных зеркал, которая позволяет всем желающим самостоятельно делать такие зеркала. Если вам эта тема интересна — загляните на сайт проекта MagicMirror.

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

Для тех, кто раньше с умными зеркалами не сталкивался, опишу в двух словах суть проекта. За зеркалом, прозрачным с одной стороны, размещают монитор. При идеальном освещении всё, что на экране выведется чёрным, будет выглядеть как зеркало. А всё белое (или имеющее другой высококонтрастный цвет) будет просвечивать сквозь зеркало. Мне хотелось сделать нечто вроде информационной панели для всей семьи, на которую выводились бы календари, списки покупок, сведения о погоде. Я подумывал и о том, чтобы встроить в это зеркало AlexaPi (подробнее об этом я расскажу позже). Я заинтересовал жену рассказом о том, как это зеркало улучшит нашу жизнь и поможет быстрее справляться с делами, и принялся за работу.

Умное зеркало своими руками - 1


Умное зеркало

Материалы

▍Стекло (зеркало)

Я воспользовался зеркалом Pilkington Mirrorpane. Оно оказалось самой дорогой частью проекта (200 канадских долларов). Я, читая разные материалы на тему умных зеркал, узнал, что хорошего эффекта люди добивались, используя плёнку, прозрачную с одной стороны, на акриловом стекле. В одной местной фирме мне отрезали подходящий кусок 6-миллиметрового зеркала Pilkington Mirrorpane. При правильном освещении оно отлично справляется со своей задачей. Если освещение оказывается слишком ярким, то картинку с монитора, который находится за зеркалом, видно хуже. Производитель рекомендует соотношение между освещённостью задней и передней части зеркала в 8:1. В таких условиях зеркало должно давать хорошие результаты. Кроме того, это зеркало имеет янтарный оттенок. Выглядит он приятно, но выбирая такое зеркало надо учитывать то, что изменить его цвет не удастся.

▍Дисплей

В качестве дисплея для этого проекта я использовал 39″ LED TV Insignia NS-39D400NA14. Стоит он 150 канадских долларов. Я столкнулся с проблемами, которые касались команд HDMI CEC для включения и выключения дисплея, но смог эти проблемы обойти (подробнее об этом я расскажу ниже).

▍Дерево

Я — столяр-любитель. Рамку для зеркала я сделал из того, что нашлось под рукой. Это была фанера, облицованная орехом. Дерева в этом проекте, на самом деле, не так много, да и облицовка из ореха особой роли не играет, но мне нравится работать с этим материалом.

▍Raspberry Pi 3

Плата Raspberry Pi 3 в подобном проекте пригодится тем, кто собирается пользоваться встроенным Wi-Fi-модулем. Подобные проекты делают и на основе Raspberry Pi 2, и даже на Raspberry Pi Zero.

▍Источник питания

CanaKit 2.5A Raspberry Pi Micro USB

▍USB-микрофон

SunFounder USB 2.0 Mini Microphone и удлинительный USB-кабель для него

▍Датчик движения

Aukru HC-SR501

▍Светодиод

Здесь я использовал RGB-светодиод.

Части проекта, напечатанные на 3D-принтере

Те части проекта, которые надо напечатать на 3D-принтере, я, в основном, спроектировал сам. Ниже приведён список ссылок на соответствующие файлы. Вы можете свободно ими пользоваться.

Сборка компонентов

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

Умное зеркало своими руками - 2

Соединение компонентов проекта

Рамка для зеркала

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

Создание рамки для зеркала

Настройка системы

Я не задумывал этот раздел как исчерпывающее руководство по настройке умных зеркал. Тут я расскажу лишь о самом главном. А именно, я установил Raspbian Stretch Lite, а потом следовал этому руководству.

Сначала я поэкспериментировал с множеством модулей для MagicMirror, созданных энтузиастами. А уже потом отобрал самое важное. Если вы будете идти моим путём, то советую хотя бы попробовать MMM-EyeCandy.

В итоге я установил следующие модули, которыми пользуюсь до сих пор:

По умолчанию всё настроено так, что умное зеркало будет заглядывать в репозитории всех установленных модулей и проверять, есть ли в них что-то новое. Мне казалось, что это хорошо, но в итоге я написал следующий скрипт, расположенный в /home/pi/myscripts/mm_update.sh, который автоматически, в полночь, обновляет модули.

#!/bin/bash
 
# Обновить модули
for d in /home/pi/MagicMirror/modules/* ; do (cd "$d" && git pull && npm install); done
# Обновить MM
cd "/home/pi/MagicMirror/"; git pull && npm install
# Перезапустить MM
sudo /sbin/shutdown -r now

Для того чтобы сделать этот скрипт исполняемым, воспользуемся командой chmod:

chmod +x /home/pi/myscripts/mmm_update.sh

Потом надо настроить crontab:

sudo crontab -e

В список заданий надо добавить следующую команду, которая будет запускать скрипт каждую полночь:

@midnight /home/pi/myscripts/mmm_update.sh

AlexaPi

AlexaPi — это потрясающий проект. Имеется и пара MagicMirror-модулей, созданных специально для работы с Alexa. Это — MMM-alexa и MMM-awesome-alexa. Мне очень хотелось, чтобы голосовой помощник Alexa оказался бы интегрирован с умным зеркалом, но с настройкой AlexaPi и соответствующих модулей MagicMirror возникло слишком много сложностей. Мне, кроме того, хотелось бы, чтобы помощник Alexa использовал бы отдельный светодиод. В итоге я просто установил AlexaPi, но не интегрировал возможности этого проекта в платформу MagicMirror. В ходе установки AlexaPi я пользовался этой инструкцией.

В моей AlexaPi-конфигурации используется недорогой USB-микрофон. Она, к сожалению, показывает далеко не самые лучшие результаты. Сейчас Alexa реагирует лишь на мужской голос. Возможно, ситуацию могут улучшить эксперименты с pocketsphinx или Snowboy. Ниже показана верхняя часть зеркала, на которой смонтирован светодиод и датчик движения.

Умное зеркало своими руками - 3

Верхняя часть зеркала со светодиодом и датчиком движения

Автоматическое включение и выключение зеркала по сигналу от датчика движения

В моём списке возможностей умного зеркала был один крайне важный пункт: зеркало должно выключаться тогда, когда рядом никого нет. Модуль MMM-PIR-Sensor отлично справляется с этой задачей. Особенно — если дисплей, используемый в проекте, поддерживает все команды HDMI CEC. Тот телевизор, что стоит за моим зеркалом, по неизвестным причинам, поддерживает лишь команду, имеющую отношение к состоянию устройства. В результате я решил проблему включения и выключения телевизора с помощью GPIO Raspberry Pi (PIN 15), воздействуя на кнопку питания телевизора так, что устройство считает, что на неё нажимает человек.

Умное зеркало своими руками - 4

Панель управления телевизором

После установки LIBCEC я создал Python-скрипт, работающий в виде демона. Он наблюдает за состоянием датчика движения и, когда надо, включает и выключает телевизор. Этот скрипт я поместил в файл /home/pi/myscripts/ty_manager.py.

</pre>
 
#!/usr/bin/env python
 
import os, sys, subprocess, time, argparse, logging, datetime
import RPi.GPIO as GPIO
 
from apscheduler.schedulers.background import BackgroundScheduler
 
PWR_PIN = 15
PIR_PIN = 14
isdisplayon = False
 
def monitor_checkstatus():
 global isdisplayon
 logging.debug('[*] CEC -> check current status of display')
 process_echo = subprocess.Popen(["echo", "pow", "0"], stdout=subprocess.PIPE, shell=False)
 process_cec = subprocess.Popen(["cec-client", "-s", "-d", "1"], stdin=process_echo.stdout,
 stdout=subprocess.PIPE, shell=False)
 process_echo.stdout.close()
 ret = process_cec.communicate()[0].splitlines()
 if 'on' in ret[1]:
 logging.debug("[*] Display is currently on")
 isdisplayon = True
 else:
 logging.debug("[*] Display is currently off")
 isdisplayon = False
 
def monitor_toggle():
 GPIO.output(15, GPIO.LOW)
 time.sleep(1)
 GPIO.output(15, GPIO.HIGH)
 
def main(argv):
 global isdisplayon
 parser = argparse.ArgumentParser( description='A Power managment daemon for issuing CEC commands' )
 parser.add_argument("-v", "--verbose", help="increase output verbosity",
 action="store_true")
 args = parser.parse_args()
 if args.verbose:
 logging.basicConfig(level=logging.DEBUG)
 logging.debug('[*] Launching powermanager.py in DEBUG mode')
 
GPIO.setwarnings(False)
 GPIO.setmode(GPIO.BCM)
 GPIO.setup(PWR_PIN, GPIO.OUT, initial=GPIO.HIGH)
 
scheduler = BackgroundScheduler()
 job = scheduler.add_job(monitor_checkstatus, 'interval', minutes=20)
 scheduler.start()
 
monitor_checkstatus()
 
GPIO.setmode(GPIO.BCM)
 GPIO.setup(PIR_PIN, GPIO.IN)
 
while True:
 # PIR triggered
 if GPIO.input(PIR_PIN):
 if not isdisplayon:
 logging.debug('[*] Motion detected, CEC -> Turning on display')
 monitor_toggle()
 isdisplayon = True
 else:
 if isdisplayon:
 logging.debug('[*] No motion, CEC -> Turning off display')
 monitor_toggle()
 isdisplayon = False
 time.sleep(1)
 
GPIO.cleanup()
 
if __name__ == "__main__":
 main(sys.argv)
<pre>

Потом я создал такой файл сервиса systemd:

[Unit]
Description=TV Power Manager Service
After=multi-user.target
 
[Service]
Type=idle
ExecStart=/home/pi/myscripts/tv_manager.py
 
[Install]
WantedBy=multi-user.target

После этого всё заработало так, как мне хотелось.

Планируете сделать умное зеркало?

Автор: ru_vds

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js