using HidSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace smsdemo.HidSharp
{
public class DreamCheekyLED : LEDBase
{
#region Constant and readonly values
public const int DefaultVendorID = 0x1D34;
public const int DefaultProductID = 0x0004;
//Colors are capped at 60, so scale accordingly
//Initialization values and test colors
public const byte MaxColorValue = 60;
public static readonly byte[] Init01 = { 0x1F, 0x02, 0x00, 0x5F, 0x00, 0x00, 0x1F, 0x03 };
public static readonly byte[] Init02 = { 0x00, 0x02, 0x00, 0x5F, 0x00, 0x00, 0x1F, 0x04 };
public static readonly byte[] Init03 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x05 };
public static readonly byte[] Init04 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
public static readonly byte[] CmdRed = { 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x05 };
public static readonly byte[] CmdGreen = { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x05 };
public static readonly byte[] CmdBlue = { 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x1F, 0x05 };
public static readonly byte[] CmdOff = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x05 };
#endregion
private AutoResetEvent WriteEvent = new AutoResetEvent(false);
#region Constructors
///
/// Default constructor. Will used VendorID=0x1D34 and ProductID=0x0004. Will throw exception if no USBLED is found.
///
/// Zero based device index if you have multiple devices plugged in.
public DreamCheekyLED(int deviceIndex = 0) : this(DefaultVendorID, DefaultProductID, deviceIndex)
{
}
///
/// Create object using VendorID and ProductID. Will throw exception if no USBLED is found.
///
/// Example to 0x1D34
/// Example to 0x0004
/// Zero based device index if you have multiple devices plugged in.
public DreamCheekyLED(int vendorID, int productID, int deviceIndex = 0)
{
Trace.WriteLine("Instantiating HidDeviceLoader...");
Loader = new HidDeviceLoader();
Trace.WriteLine(string.Format("Enumerating HID USB Devices (VendorID {0}, ProductID {1})...", vendorID, productID));
var devices = new List(Loader.GetDevices(vendorID, productID));
if (deviceIndex >= devices.Count)
{
throw new ArgumentOutOfRangeException("deviceIndex", string.Format("deviceIndex={0} is invalid. There are only {1} devices connected.", deviceIndex, devices.Count));
}
HidLED = devices[deviceIndex];
if (!init())
{
throw new Exception(string.Format("Cannot find USB HID Device with VendorID=0x{0:X4} and ProductID=0x{1:X4}", vendorID, productID));
}
}
///
/// Create object using Device path. Example: DreamCheekyLED(@"\\?\hid#vid_1d34&pid_0004#6&1067c3dc&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}").
///
/// Example: @"\\?\hid#vid_1d34&pid_0004#6&1067c3dc&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
public DreamCheekyLED(string devicePath)
{
Trace.WriteLine("Instantiating HidDeviceLoader...");
Loader = new HidDeviceLoader();
Trace.WriteLine("Enumerating all USB Devices...");
var devices = Loader.GetDevices();
Trace.WriteLine("Searching for device at {0}...", devicePath);
foreach (var device in devices)
{
Trace.WriteLine("Enumerating all USB Devices..." + device.DevicePath);
if (device.DevicePath.Contains("vid_1d34"))
{
HidLED = device;
Trace.WriteLine("CheekyLED found at {0}...", device.DevicePath);
}
}
if (!init())
{
throw new Exception(string.Format("Cannot find USB HID Device with devicePath={0}", devicePath));
}
}
///
/// Private init function for constructors.
///
/// True if success, false otherwise.
private bool init()
{
WriteEvent.Reset();
if (HidLED == default(HidDevice))
{
return false; //Device not found, return false.
}
//Device is valid
Trace.WriteLine("Init HID device: " + HidLED.ProductName + "\r\n");
return true;
}
#endregion
///
/// Sends initialization commands to USB LED device so it is ready to change colors. LED will be turned off after calling Initialize.
/// NOTE: Write command will automatically call Initialize.
///
/// True if successfull, false otherwise
internal override bool Initialize()
{
bool bReturn = base.Initialize();
if (bReturn)
{
//Note: Write will automatically open the device if needed.
bReturn &= Write(Init01);
bReturn &= Write(Init02);
bReturn &= Write(Init03);
bReturn &= Write(Init04);
}
return bReturn;
}
public override bool Write(byte[] data)
{
if (!initialized)
{
Initialize();
}
var windowsData = new byte[9];
data.CopyTo(windowsData, 1);
Stream.Write(windowsData);
return true;
}
public override bool SetColor(Color color)
{
Trace.WriteLine("\r\nSetColor: {0}", color.Name);
return SetColor(color.R, color.G, color.B);
}
///
/// Set color using RGB. Values should range 0-255 and will be scaled to match USBLED output.
///
/// 0-255
/// 0-255
/// 0-255
/// True if sucessfull
public override bool SetColor(byte red, byte green, byte blue)
{
Trace.WriteLine(string.Format("\r\nSetColor (RGB): ({0},{1},{2})", red, green, blue));
byte[] data = CmdOff.Clone() as byte[];
// var t = (byte)(((float)Red / 255F)*60F);
//Scale color values
data[0] = (byte)(red / 255F * MaxColorValue);
data[1] = (byte)(green / 255F * MaxColorValue);
data[2] = (byte)(blue / 255F * MaxColorValue);
return Write(data);
}
}
}