
Когда обошли почти все магазины, стало ясно что проще всего сделать такую мебель самим. Можно смастерить индивидуальную не только габаритами, но и функциями полку и сэкономить свободное пространство в комнате.
Обсудив что будем делать, мы с Надин разделились: она вооружилась электролобзиком, шуруповертом, краской и достала с лоджии остатки фанеры. А я чуть позже засел за настройку Raspberry PI и программирование.
Кому интересно узнать только о настройке интернет-радио и разработке ПО, я расскажу про секрет стабильной работы bcm2835 с музыкальным демоном, про Apache Camel и разработку MPD компонента для него.
Надин делала наиболее сложную и кропотливую часть — столярные работы, пайку, монтаж. Рекомендую посмотреть tutorial, который длится около часа! В реальности работы на 3-4 часа.
Все начинается с модели или эскиза, квадратный лист фанеры 52х52см размечен на 2 прямоугольника 18х52см. Остаток ~15х52см потом тоже пригодился на третью полочку.

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

Припаять светодиодную ленту не составит труда, если использовать жидкий флюс на основе канифоли и наносить его на контакты перед лужением припоем ПОС-61. Чтобы подсветка работала, важно не перепутать полярность проводов питания GND, +5V между лентами. На контакт D(IN) ленты подается управляющий сигнал с выхода на контроллере SP002E, помеченного D. Более простой вариант без пайки — если найти зажимные клемники для светодиодной ленты, но на 3х контактную ленту не нашли в продаже в городе.
Для питания подсветки и колонок Надя использовала USB провод колонки, подпаяв к нему питание контроллера. Колонки с питанием по USB стоят в розницу около 400р. Для изоляции проводников в ход пошла и термоусадочная трубка и изолента.

Для сборки полочек Надин использовала два варианта крепежа — саморезы по дереву для фиксации уголков, Raspberry и и клеевой пистолет чтобы закрепить профиль со светодиодной лентой и колонки на полочках. При попытке повесить на стену, уголки заменили на более прочные.
Светодиодное освещение и Smart pixel RGB (WS2812B)
Светодиодная ленты с RGB LED чипами WS2812B за 500р в розницу, ее потребовался метр.
Паять не сложно: используется всего три провода, без синхросигнала. Учтите, что эта лента не будет работать без контроллера. Для питания нужен любой блок питания на 5В 1А с USB разъемом. Кстати, для управляющего сигнала на ленте что у меня, хватало 3.3В так что возможно подключать к GPIO ARM контроллеров без преобразователя уровня.

Можно управлять светодиодной лентой WS2812B с помощью Raspberry PI GPIO но при этом будут проблемы с воспроизведением музыки, через встроенный аудио выход так как используется то же ШИМ генератор SoC, что и для аудио порта. Поэтому вариант был сразу отброшен, как не работающий для интернет радио.

Проще управлять этой лентой контроллером светодиодов SP002E c МК STM8 на борту — за 270р в российской рознице. Будет интересно попробовать собрать контроллер для этой ленты на из запасов STM32 с подключением по USB для передачи значений пикселей. Нашел несколько проектов библиотек на github. Есть идея сделать cветомузыку — запишу в свой TODO list.
Установка и настройка интернет-радио
Можно рассмотреть несколько вариантов для удаленного воспроизведения музыки:
- Bluetooth A2DP — это то что реализовано в Bluetooth колонках, где сжатие звука происходит с потерями. Этот вариант не подошел, так как Raspberry PI превратится просто в «удаленный» динамик, а музыку надо «стримить» с другого устройства.
- PulseAudio по сети — подход похож A2DP, но и требует настройки module-native-protocol-tcp и клиента.
- Music Player Daemon(MPD) — идеально подходит для автономного воспроизведения интернет радио или плейлиста с локального диска/NAS.
Так как нужно автономное интернет-радио, выбор — MPD! Менять треки в MPD, управлять плейлистами и громкостью можно как с Android клиентов, например MPD Control, так и с помощью desktop приложений или веб интерфейса.
Как я уже говорил про bcm2835 и его конфликты с GPIO функциями и ШИМ контроллером — это достаточно шумное и проблематичное звуковое устройство. Единственное достоинство — оно встроенное и не надо покупать USB Audio, сопоставимое по стоимости с Raspberry.
Обязательно должны быть сконфигурированы mixer_type, mixer_device, mixer_control, mixer_index. До того как это сделал, демон вис при попытке переключить трек и приходилось перезапускать процесс.
Установку производил на Raspbian под суперпользователем:

Запускаем команду:
apt-get install mpd
Для работы встроенного аудио Raspberry PI 3 необходимо добавить параметры в конфигурацию /etc/mpd.conf:
audio_output { type "alsa" name "My ALSA Device" device "hw:0,0" # optional mixer_type "software" # optional mixer_device "default" # optional mixer_control "PCM" # optional mixer_index "0" # optional } bind_to_address "192.168.1.68" port "6600" auto_update "yes"
Где «192.168.1.68» — адрес Raspbery в локальной сети.

Управляем музыкой из camel-mpd: разработка компонента для Apache Camel
Java и JVM достаточно распространенная платформ автоматизации «интернета вещей» на IoT шлюзах. Поэтому разработка MPD компонента для Camel позволит интегрировать управление музыкой в существующее ПО автоматизации. И конечно же в мою любимую сигнализацию для холодильника!
- Apache Camel отлично работает с Eclipse SmartHome и Kura
- OpenHub2 работает в рантайме Eclipse SmartHome.
- «Как разработать приложение для автоматизации почти не умея программировать». Это скорее про разработку софта для IoT шлюзов.
Код компонента доступен в github репозитарии camel-mpd и как артефакт com.github.igor-suhorukov:camel-mpd:1.0 в центральном maven репозитарии. Для работы с протоколом Music Player Daemon я выбрал библиотеку net.thejavashop:javampd:6.0.0. Судя по комитам эта библиотека поддерживается, с отличным качеством кода, если судить по метрикам статического анализа! Моя часть работы — создание camel компонента, endpoint а так же наследников producer и consumer.
Пару слов об архитектуре Camel
Компонент — фабрика Endpoint, у компонента есть связанный с ним протокол/схема. Почти все в Camel — Universal Resource Identifier. Примеры: http, hdfs, smtps, irc, webcam. Теперь и mpd!

Компоненты объеденены в маршруты (Route) трансформации данных. Route записывается на одном из доступных domain-specific language(DSL): java, scala, groovy, spring/blueprint xml
Route можно визуализировать, например с помощью

Consumer в DSL это конструкция «from» в начале маршрута
Producer в DSL это конструкция «to»
Exchange — это сообщение которое создается и обрабатывается маршрутом. Содержит тело сообщения (body) и заголовки(headers).

Создать заготовку компонента apache camel можно с помощью maven:
mvn archetype:generate \ -DarchetypeGroupId=org.apache.camel.archetypes \ -DarchetypeArtifactId=camel-archetype-component \ -DarchetypeVersion=2.20.2 \ -DgroupId=myGroupId \ -DartifactId=myArtifactId
Чтобы контекст Apache Camel смог найти компонент по его протоколу в файле src/main/resources/META-INF/services/org/apache/camel/component/mpd должен быть указан класс компонента
class=com.github.igorsuhorukov.mpd.MpdClientComponent
Класс MpdClientComponent это фабрика — создает и инициализирует экземпляры класса com.github.igorsuhorukov.mpd.MpdEndpoint. MpdEndpoint при запросе из route создает экземпляр Consumer, и его сообщения передаются компонентом в Route. Consumer выдает в маршрут значения:
- volume — текущее значение громкости, в интервале [0,100].
- current возвращает информацию о текущей песне.
- playlist возвращает PlayList в виде списка.
- total — общую продолжительность музыки из плейлиста.
- elapsed — сколько прослушано по времени.
- error сообщение, последней возникшей ошибки.
Producer — завершает Route в контексте Camel и позволяет отдавать команды MPD:
- play — запуск воспроизведения.
- stop — остановка воспроизведения.
- next — выбор следующей песни.
- previous — запуск предыдущей песни.
- randomize — активирует переход на следующую песню в случайном порядке.
- unrandomize — включает последовательное воспроизведение плейлиста.
- volume — устанавливает громкость воспроизведения в интервале от 0 до 100
- song — позволяет добавить одну или список песен в плейлист. Причем это либо путь в файловой системе, либо интернет-радио по протоколу http. Тело сообщения для этой функции либо строка, либо объект org.bff.javampd.song.MPDSong. Другой вариант — список из строк или список объектов MPDSong.
С этим компонентом можно будет работать через интеграцию с java.net.URL из проекта camel-url-handler.
Пока я программировал camel-mpd и монтировал видео, Надин было не остановить и смастерила себе еще и стул-тумбочку.

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

Почти Happy End

Полочку с подсветкой установили в проём между подоконником и полом, рядом с батареей отопления. Интернет радио работает в фоне, подсветка сверкает да и кошка довольна — больше простора для бега по столу. Вещи со стола теперь разместились на полочке. А подарок на 8 марта я все еще не придумал, Надин почти все сделала сама…

