- PVSM.RU - https://www.pvsm.ru -

Умный будильник на .NET

Недавно я начал интересоваться идеей «Умного дома». Мне кажется, было бы очень удобно управлять освещением из собственных приложений. Иметь возможность задать время включения/отключения света или описать любой сценарий управления электроприборами.
Я обратил свое внимание на систему Noolite [1]. Она дает возможность беспроводного управления электроприборами. В своей серии она имеет различные силовые блоки, разные виды пультов управления. Среди продукции Noolite есть адаптер Pc118.

image

Он позволяет управлять силовыми блоками серии через USB. Noolite предоставляет подробную и доступную документацию к устройству. Нашей целью было написать приложение, которое позволяет взаимодействовать с системой управления освещением через этот адаптер.

Что хотели сделать

Мы попробовали реализовать сценарий «плавное включение» — постепенное увеличение яркости света, это могло бы, например, способствовать комфортному пробуждению утром. В статье Управление светом через браузер [2] подробно описано как работает наше web-приложение. Исходный код приложения доступен на Google Code [3].

В этой статье описана часть системы, которая отвечает за взаимодействие с USB-адаптером. А именно, идентификацию устройства, отправку команд, также приведен пример кода реализующий сценарий «плавного включение». Большую часть времени я разрабатываю на .NET, поэтому примеры кода будут на C#.

Принципы работы с USB на .NET

USB-устройства очень распространены сегодня. К сожалению, в .NET нет, доступного из коробки, компонента для работы с USB. Можно работать с USB при помощи класса FileStream. Есть сторонние библиотеки (в том числе open source), предоставляющие удобные обертки над FileStream. Мы использовали библиотеку HidLibrary [4]. Адаптер PC118 подключается через USB и с ним можно работать как с HID устройством [5]. Для идентификации устройства и получения к нему доступа, нужно указать два его идентификатора — ID вендора (Vendor ID, VID) и ID продукта (Product ID, PID). Эти значения можно узнать из документации [6] к устройству.
Класс HidDevices из библиотеки HidLibrary имеет статический метод Enumerate. Этот метод возвращает список найденных HID устройств с возможностью фильтрации списка по PID и VID. Выбираем нужное устройство (я брал первое из отфильтрованного списка) и устанавливаем с ним соединение, вызывая метод OpenDevice.

var device = HidDevices.Enumerate(VENDOR_ID, PRODUCT_ID).FirstOrDefault();
if (device != null)
{
        device.OpenDevice();
}

Устройство готово к работе. Теперь мы можем отправлять на него команды.

Работа с адаптером

Команда для устройства представляет собой массив байтов.

var data = new byte[] { ... };

Их значения нужно установить в соответствии с параметрами отправляемой команды: тип команды (например, вкл/выкл/установить уровень яркости), канал (адаптер PC118 может отправлять команды в 8 каналов с номерами от 0 до 7), значение уровня яркости (если выбрана команда установки яркости). Подробно об этом написано в документации.

В нашем приложении используется несколько команд:
— включить нагрузку (On)
— выключить нагрузку (Off)
— переключить состояние нагрузки (Switch)
— установить яркость (SetLevel).

Чтобы отправить команду на устройство, нужно вызвать метод WriteFeatureData и передать ему сформированный массив:

device.WriteFeatureData(data);

В документации есть примечание: «В зависимости от используемой библиотеки, перед отправкой 8-ми байт может потребоваться отправить первый байт со значением 0».
Во время экспериментов выяснилось, что это именно наш случай. Для корректной отправки команды в начало массива нужно добавлять дополнительный нулевой байт (отправлять на адаптер массивы по 9 байт, а не по 8, как написано в инструкции). Судя по всему, это особенность библиотеки HidLibrary.
Также оказалось, что между отправлениями команд необходимо делать паузу 200 мс., иначе адаптер выполняет только первую команду. Длительность задержки была определена экспериментальным путем.

Что получилось

После того, как мы научились посылать команды на адаптер, все было обернуто в класс, реализующий интерфейс IDisposable, и описаны enum для типов команд. Вы можете скачать скомпилированную DLL и с ее помощью управлять светом из собственных приложений на .NET. Например, код для плавного включения света может выглядеть так:

using (var adapter = new Pc118Adapter())
{
	if (adapter.OpenDevice())
	{
		// 40 - это минимальный уровень, при котором лампочка начинает светиться
		for (var level = 40; level  < 100; i++)
		{
			adapter.SendCommand(
				Pc118Command.SetLevel, // команда
				2, // канал
				level // уровень яркости 
			);
			Thread.Sleep(60000);	// останавливаемся на минуту
		}
	}
}

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

Заключение

Нам было интересно наблюдать за результатом. Надеюсь, статья была кому-то полезна. Может быть, она поможет появиться новым интересным сценариям по управлению светом и приборами в доме.

Спасибо за внимание!

Автор: smatveev

Источник [7]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/umny-j-dom/32684

Ссылки в тексте:

[1] Noolite: http://www.noo.com.by/sistema-noolite.html

[2] Управление светом через браузер: http://habrahabr.ru/post/174329/

[3] Google Code: https://code.google.com/p/th-noolite/

[4] HidLibrary: https://github.com/mikeobrien/HidLibrary

[5] HID устройством: http://ru.wikipedia.org/wiki/USB_HID

[6] документации: http://www.noo.com.by/assets/files/software/PC118_HID_API.pdf

[7] Источник: http://habrahabr.ru/post/176141/