Usb web notifier в подсветку

от автора

К сожалению, довелось мне простудиться, застрять дома на три дня, и от безудержного веселья начать перебирать «долгий ящик». В оном ящике я обнаружил «usb уведомитель» от фирмы CBR. Девайс предназначен, для оповещения о входящих сообщений на email, посредством изменения цветовой гаммы.
Не знаю, повезло мне, или наоборот, но девайс отказался исполнять свои непосредственные функции. Он определился как HID совместимое устройство, однако чудо-софт работать не захотел.

Сначала я подумал о написании софта, который бы повторял заявленный функционал, но основательно подумав, понял, что «уведомитель» мне нужен как собаке пятая нога. С другой стороны внешний вид светодиода в капельке мне приглянулся и я решил сделать из устройства обыкновенный ночник-подсветку.
Для начала необходимо было узнать какие же байты отвечают за смену цвета (не забываем это же все-таки HID). Никакой внятной документации не нашлось и пришлось действовать эмпирическим путем (научный метод «пальцем в небо»). Для таких изысканий есть замечательный софт SimpleHIDWrite. Я думал, что на подбор команд у меня уйдет приличное время, однако все оказалось очень просто. Ставим ReportID 00, отправляем 01 00 00 00 00 и наш чудо-девайс окрашивается в красный цвет. Список остальных управляющих байтов на смену цвета приведен ниже:

  • 00 00 00 00 00 — выключить
  • 01 00 00 00 00 — красный
  • 02 00 00 00 00 — зеленый
  • 03 00 00 00 00 — светло-зеленый
  • 04 00 00 00 00 — фиолетовый
  • 05 00 00 00 00 — сиреневый
  • 06 00 00 00 00 — синий
  • 07 00 00 00 00 — светло-синий

Отлично, теперь осталось дело за малым, написать небольшую оболочку для управления устройством. Так как никакого GUI не предвидеться, решил сделать управление девайсом в виде windows службы на c#. Реализация обмена данными между хостом и HID-устройством с использованием HidLibrary выглядит следующим образом:

 // vendor id, является неизменным, можно узнать из диспетчера устройств в свойствах. private int vid = 0x1294; //получаем список устройства с указанным vid'ом var devs = HidDevices.Enumerate(vid).ToList(); //выбираем устройство, num_devices. параметр из .config var dev = devs[device_num]; if(dev != null) {       //создаем масиив с управляющими байтами       var data = new byte[5];       //в obj находится байт для смены цвета       data[0] = (byte)(int)obj;            //создаем Report, т.е. хост отдает команду HID_SET_REPORT       var report = dev.CreateReport();       //подготавливаем Report       report.Data = data;       //и отправляем      dev.WriteReport(report);                  } 

Теперь необходимо определиться как и когда менять цвет, сначала хотел просто по таймеру, но это оказалось скучным, решил сделать по уровню звука с аудио-входа (подразумевается, что есть микрофон или вебка с микрофоном). Для этого использовал NAudio. Как управляться с данной библиотекой расписано здесь , я лишь приведу обработчик, который отвечает за определение пика уровня звука. В принципе код позаимствован в большей части из статьи по ссылке.

//инициализируем аудио-вход 0, с частотой 8000 Гц и моно-каналом var dev = new WaveIn(WaveCallbackInfo.FunctionCallback()); dev.DeviceNumber = 0; //подписываемся на событие обработки данных с аудио-входа dev.DataAvailable += dev_DataAvailable; dev.WaveFormat = new WaveFormat(8000, 1); dev.StartRecording();  void dev_DataAvailable(object sender, WaveInEventArgs e) {     //получаем максимальный пик из входящего буффера     var max = getValueMax(e.Buffer, e.BytesRecorded);     //если больше заданного уровня                 if(max > _trigger)     {          if(ChangeLevelVolumeMax != null)          {                    //инициализируем событие, на смену цвета               ChangeLevelVolumeMax(this, e);          }      }  }  private float getValueMax(byte[] buffer, int lenght)  {      //массив уровней      List<float> l_sample32 = new List<float>();      //определяем уровень, между двумя соседствующими значениями      for (int index = 0; index < lenght; index += 2)      {           float sample32 = (float)(short)((buffer[index + 1] << 8) |                                         buffer[index + 0]) / 32768f;          l_sample32.Add(sample32);       }             //выбираем максимальный       var max = l_sample32.Max();       return max; } 

Ну и выше приведенный код упаковываем в оболочку windows службы:

protected override void OnStart(string[] args) {    //USB Notifier    device = new cApi(cSettings.Usb);               //Audio           audio = new cAudio(cSettings.Audio,            cSettings.Rate,            cSettings.Chanel,            cSettings.Trigger);    audio.ChangeLevelVolumeMax += audio_ChangeLevelVolumeMax;                base.OnStart(args);           }  void audio_ChangeLevelVolumeMax(object sender, NAudio.Wave.WaveInEventArgs e) {     //смена цвета     device.setNextColor();              }         protected override void OnStop() {      device.Off();      device.Dispose();      audio.Dispose();        base.OnStop();  } 

Дальше осталось создать развертывание службы с помощью Wix. За подробностями пожалуйте на гит. Ну и напоследок видео:

ссылка на оригинал статьи http://habrahabr.ru/post/232729/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *