diff --git a/src/Sleddog.Blink1.ExplicitTests/Blink1ConnectorTests.cs b/src/Sleddog.Blink1.ExplicitTests/Blink1ConnectorTests.cs index 062fc85..a7f0618 100644 --- a/src/Sleddog.Blink1.ExplicitTests/Blink1ConnectorTests.cs +++ b/src/Sleddog.Blink1.ExplicitTests/Blink1ConnectorTests.cs @@ -2,38 +2,38 @@ namespace Sleddog.Blink1.ExplicitTests { - public class Blink1ConnectorTests - { - //[RequireBlinkHardware] - //public void CanIdentify() - //{ - // Assert.DoesNotThrow(() => Blink1Connector.Identify(TimeSpan.FromSeconds(1))); - //} - - [RequireBlinkHardware] - public void ScanFindsDevices() - { - var devices = Blink1Connector.Scan(); - - Assert.NotEmpty(devices); - } - - [RequireNoBlinkHardware] - public void ScanWithNoDevicesFindsNone() - { - var devices = Blink1Connector.Scan(); - - Assert.Empty(devices); - } - - [RequireBlinkHardware] - public void ConnectToSpecificDevice() - { - var serialNumber = "0x1A002944"; - - var device = Blink1Connector.Connect(serialNumber); - - Assert.NotNull(device); - } - } + public class Blink1ConnectorTests + { + //[RequireBlinkHardware] + //public void CanIdentify() + //{ + // Assert.DoesNotThrow(() => Blink1Connector.Identify(TimeSpan.FromSeconds(1))); + //} + + [RequireBlinkHardware] + public void ScanFindsDevices() + { + var devices = Blink1Connector.Scan(); + + Assert.NotEmpty(devices); + } + + [RequireNoBlinkHardware] + public void ScanWithNoDevicesFindsNone() + { + var devices = Blink1Connector.Scan(); + + Assert.Empty(devices); + } + + [RequireBlinkHardware] + public void ConnectToSpecificDevice() + { + var serialNumber = "0x1A002944"; + + var device = Blink1Connector.Connect(serialNumber); + + Assert.NotNull(device); + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1.ExplicitTests/Blink1Fixture.cs b/src/Sleddog.Blink1.ExplicitTests/Blink1Fixture.cs index 5b2921b..99ad9ab 100644 --- a/src/Sleddog.Blink1.ExplicitTests/Blink1Fixture.cs +++ b/src/Sleddog.Blink1.ExplicitTests/Blink1Fixture.cs @@ -3,20 +3,19 @@ namespace Sleddog.Blink1.ExplicitTests { - public class Blink1Fixture : IDisposable - { - private readonly IBlink1 blink1; + // ReSharper disable once ClassNeverInstantiated.Global + public class Blink1Fixture : IDisposable where TBlinkType : IBlink1 + { + public TBlinkType Device { get; } - public Blink1Fixture() - { - blink1 = Blink1Connector.Scan().FirstOrDefault(b => !(b is IBlink1Mk2)); - } + public Blink1Fixture() + { + Device = (TBlinkType) Blink1Connector.Scan().FirstOrDefault(b => b is TBlinkType); + } - public IBlink1 Device => blink1; - - public void Dispose() - { - blink1?.Dispose(); - } - } + public void Dispose() + { + Device?.Dispose(); + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1.ExplicitTests/Blink1Mk2WorkbenchTests.cs b/src/Sleddog.Blink1.ExplicitTests/Blink1Mk2WorkbenchTests.cs new file mode 100644 index 0000000..b421991 --- /dev/null +++ b/src/Sleddog.Blink1.ExplicitTests/Blink1Mk2WorkbenchTests.cs @@ -0,0 +1,144 @@ +using System; +using System.Drawing; +using System.Threading; +using Xunit; + +namespace Sleddog.Blink1.ExplicitTests +{ + public class Blink1Mk2WorkbenchTests : IClassFixture> + { + private readonly IBlink1Mk2 blink1; + private const string LowestSerialNumber = "0x20001000"; + private const string HighestSerialNumber = "0x20003710"; + + public Blink1Mk2WorkbenchTests(Blink1Fixture fixture) + { + blink1 = fixture.Device; + } + + [RequireBlink1Mk2Hardware] + public void SetAllPatterns() + { + blink1.Save(new Blink1Preset(Color.Cyan, TimeSpan.FromSeconds(1)), 0); + blink1.Save(new Blink1Preset(Color.DarkCyan, TimeSpan.FromSeconds(1)), 1); + blink1.Save(new Blink1Preset(Color.CadetBlue, TimeSpan.FromSeconds(1)), 2); + blink1.Save(new Blink1Preset(Color.SteelBlue, TimeSpan.FromSeconds(1)), 3); + blink1.Save(new Blink1Preset(Color.DodgerBlue, TimeSpan.FromSeconds(1)), 4); + blink1.Save(new Blink1Preset(Color.MediumBlue, TimeSpan.FromSeconds(1)), 5); + blink1.Save(new Blink1Preset(Color.DarkBlue, TimeSpan.FromSeconds(1)), 6); + blink1.Save(new Blink1Preset(Color.Green, TimeSpan.FromSeconds(1)), 7); + blink1.Save(new Blink1Preset(Color.SeaGreen, TimeSpan.FromSeconds(1)), 8); + blink1.Save(new Blink1Preset(Color.MediumSeaGreen, TimeSpan.FromSeconds(1)), 9); + blink1.Save(new Blink1Preset(Color.SpringGreen, TimeSpan.FromSeconds(1)), 10); + blink1.Save(new Blink1Preset(Color.LightGreen, TimeSpan.FromSeconds(1)), 11); + } + + [RequireBlink1Mk2Hardware] + public void ReadSerialReadsValidSerialNumber() + { + var actual = blink1.SerialNumber; + + Assert.InRange(actual, LowestSerialNumber, HighestSerialNumber); + } + + [RequireBlink1Mk2Hardware] + public void ReadPresetReturnsValidPreset() + { + var actual = blink1.ReadPreset(0); + + Assert.NotNull(actual); + } + + [RequireBlink1Mk2Hardware()] + public void SavePresetWritesToDevice() + { + var expected = new Blink1Preset(Color.FromArgb(255, 50, 100, 200), TimeSpan.FromSeconds(2.5)); + + blink1.EnableGamma = false; + + blink1.Save(expected, 0); + + var actual = blink1.ReadPreset(0); + + Assert.Equal(expected, actual); + } + + [RequireBlink1Mk2Hardware] + public void SetColor() + { + var actual = blink1.Set(Color.Blue); + + Assert.True(actual); + } + + [RequireBlink1Mk2Hardware] + public void ShowColor() + { + var showColorTime = TimeSpan.FromSeconds(2); + + var actual = blink1.Show(Color.Chartreuse, showColorTime); + + Thread.Sleep(showColorTime); + + Assert.True(actual); + } + + [RequireBlink1Mk2Hardware] + public void FadeToColor() + { + var fadeDuration = TimeSpan.FromSeconds(2); + + var actual = blink1.Fade(Color.Red, fadeDuration); + + Thread.Sleep(fadeDuration); + + Assert.True(actual); + } + + [RequireBlink1Mk2Hardware] + public void SetPreset0AndPlayIt() + { + var presetDuration = TimeSpan.FromSeconds(2); + + var preset = new Blink1Preset(Color.DarkGoldenrod, presetDuration); + + blink1.Save(preset, 0); + + blink1.Play(0); + + Thread.Sleep(presetDuration); + + blink1.Pause(); + } + + [RequireBlink1Mk2Hardware] + public void PoliceBlinking() + { + for (var i = 0; i < 100; i++) + { + blink1.Fade(Color.Blue, TimeSpan.FromMilliseconds(25), (LEDPosition) (i % 2)); + blink1.Fade(Color.Red, TimeSpan.FromMilliseconds(25), (LEDPosition) (i % 2 + 1)); + + Thread.Sleep(200); + } + + blink1.Set(Color.Black); + } + + [RequireBlink1Mk2Hardware] + public void TurnOff() + { + blink1.Set(Color.Black); + } + + [RequireBlink1Mk2Hardware] + public void EnableInactivityMode() + { + blink1.EnableInactivityMode(TimeSpan.FromMilliseconds(50)); + + Thread.Sleep(TimeSpan.FromMilliseconds(150)); + + blink1.DisableInactivityMode(); + } + } +} \ No newline at end of file diff --git a/src/Sleddog.Blink1.ExplicitTests/Blink1Mk3WorkbenchTests.cs b/src/Sleddog.Blink1.ExplicitTests/Blink1Mk3WorkbenchTests.cs new file mode 100644 index 0000000..dcbac43 --- /dev/null +++ b/src/Sleddog.Blink1.ExplicitTests/Blink1Mk3WorkbenchTests.cs @@ -0,0 +1,142 @@ +using System; +using System.Drawing; +using System.Threading; +using Xunit; + +namespace Sleddog.Blink1.ExplicitTests +{ + public class Blink1Mk3WorkbenchTests : IClassFixture> + { + private readonly IBlink1Mk3 blink1; + + public Blink1Mk3WorkbenchTests(Blink1Fixture fixture) + { + blink1 = fixture.Device; + } + + [RequireBlink1Mk3Hardware] + public void SetAllPatterns() + { + blink1.Save(new Blink1Preset(Color.Cyan, TimeSpan.FromSeconds(1)), 0); + blink1.Save(new Blink1Preset(Color.DarkCyan, TimeSpan.FromSeconds(1)), 1); + blink1.Save(new Blink1Preset(Color.CadetBlue, TimeSpan.FromSeconds(1)), 2); + blink1.Save(new Blink1Preset(Color.SteelBlue, TimeSpan.FromSeconds(1)), 3); + blink1.Save(new Blink1Preset(Color.DodgerBlue, TimeSpan.FromSeconds(1)), 4); + blink1.Save(new Blink1Preset(Color.MediumBlue, TimeSpan.FromSeconds(1)), 5); + blink1.Save(new Blink1Preset(Color.DarkBlue, TimeSpan.FromSeconds(1)), 6); + blink1.Save(new Blink1Preset(Color.Green, TimeSpan.FromSeconds(1)), 7); + blink1.Save(new Blink1Preset(Color.SeaGreen, TimeSpan.FromSeconds(1)), 8); + blink1.Save(new Blink1Preset(Color.MediumSeaGreen, TimeSpan.FromSeconds(1)), 9); + blink1.Save(new Blink1Preset(Color.SpringGreen, TimeSpan.FromSeconds(1)), 10); + blink1.Save(new Blink1Preset(Color.LightGreen, TimeSpan.FromSeconds(1)), 11); + } + + [RequireBlink1Mk3Hardware] + public void ReadSerialReadsValidSerialNumber() + { + var actual = blink1.SerialNumber; + + Assert.StartsWith("0x3", actual); + } + + [RequireBlink1Mk3Hardware] + public void ReadPresetReturnsValidPreset() + { + var actual = blink1.ReadPreset(0); + + Assert.NotNull(actual); + } + + [RequireBlink1Mk3Hardware()] + public void SavePresetWritesToDevice() + { + var expected = new Blink1Preset(Color.FromArgb(255, 50, 100, 200), TimeSpan.FromSeconds(2.5)); + + blink1.EnableGamma = false; + + blink1.Save(expected, 0); + + var actual = blink1.ReadPreset(0); + + Assert.Equal(expected, actual); + } + + [RequireBlink1Mk3Hardware] + public void SetColor() + { + var actual = blink1.Set(Color.Blue); + + Assert.True(actual); + } + + [RequireBlink1Mk3Hardware] + public void ShowColor() + { + var showColorTime = TimeSpan.FromSeconds(2); + + var actual = blink1.Show(Color.Chartreuse, showColorTime); + + Thread.Sleep(showColorTime); + + Assert.True(actual); + } + + [RequireBlink1Mk3Hardware] + public void FadeToColor() + { + var fadeDuration = TimeSpan.FromSeconds(2); + + var actual = blink1.Fade(Color.Red, fadeDuration); + + Thread.Sleep(fadeDuration); + + Assert.True(actual); + } + + [RequireBlink1Mk3Hardware] + public void SetPreset0AndPlayIt() + { + var presetDuration = TimeSpan.FromSeconds(2); + + var preset = new Blink1Preset(Color.DarkGoldenrod, presetDuration); + + blink1.Save(preset, 0); + + blink1.Play(0); + + Thread.Sleep(presetDuration); + + blink1.Pause(); + } + + [RequireBlink1Mk3Hardware] + public void PoliceBlinking() + { + for (var i = 0; i < 100; i++) + { + blink1.Fade(Color.Blue, TimeSpan.FromMilliseconds(25), (LEDPosition) (i % 2)); + blink1.Fade(Color.Red, TimeSpan.FromMilliseconds(25), (LEDPosition) (i % 2 + 1)); + + Thread.Sleep(200); + } + + blink1.Set(Color.Black); + } + + [RequireBlink1Mk3Hardware] + public void TurnOff() + { + blink1.Set(Color.Black); + } + + [RequireBlink1Mk3Hardware] + public void EnableInactivityMode() + { + blink1.EnableInactivityMode(TimeSpan.FromMilliseconds(50)); + + Thread.Sleep(TimeSpan.FromMilliseconds(150)); + + blink1.DisableInactivityMode(); + } + } +} \ No newline at end of file diff --git a/src/Sleddog.Blink1.ExplicitTests/Blink1Tests.cs b/src/Sleddog.Blink1.ExplicitTests/Blink1Tests.cs index cee18cd..994c4d9 100644 --- a/src/Sleddog.Blink1.ExplicitTests/Blink1Tests.cs +++ b/src/Sleddog.Blink1.ExplicitTests/Blink1Tests.cs @@ -5,137 +5,136 @@ namespace Sleddog.Blink1.ExplicitTests { - public class Blink1Tests : IClassFixture - { - private const string LowestSerialNumber = "0x1A001000"; - private const string HighestSerialNumber = "0x1A002FFF"; + public class Blink1Tests : IClassFixture> + { + private readonly IBlink1 blink1; + private const string LowestSerialNumber = "0x1A001000"; + private const string HighestSerialNumber = "0x1A002FFF"; - private readonly IBlink1 blink1; + public Blink1Tests(Blink1Fixture data) + { + blink1 = data.Device; + } - public Blink1Tests(Blink1Fixture data) - { - blink1 = data.Device; - } + [RequireBlink1Hardware] + public void SetAllPatterns() + { + blink1.Save(new Blink1Preset(Color.Cyan, TimeSpan.FromSeconds(5)), 0); + blink1.Save(new Blink1Preset(Color.DarkCyan, TimeSpan.FromSeconds(5)), 1); + blink1.Save(new Blink1Preset(Color.CadetBlue, TimeSpan.FromSeconds(5)), 2); + blink1.Save(new Blink1Preset(Color.SteelBlue, TimeSpan.FromSeconds(5)), 3); + blink1.Save(new Blink1Preset(Color.DodgerBlue, TimeSpan.FromSeconds(5)), 4); + blink1.Save(new Blink1Preset(Color.MediumBlue, TimeSpan.FromSeconds(5)), 5); + blink1.Save(new Blink1Preset(Color.DarkBlue, TimeSpan.FromSeconds(5)), 6); + blink1.Save(new Blink1Preset(Color.Green, TimeSpan.FromSeconds(5)), 7); + blink1.Save(new Blink1Preset(Color.SeaGreen, TimeSpan.FromSeconds(5)), 8); + blink1.Save(new Blink1Preset(Color.MediumSeaGreen, TimeSpan.FromSeconds(5)), 9); + blink1.Save(new Blink1Preset(Color.SpringGreen, TimeSpan.FromSeconds(5)), 10); + blink1.Save(new Blink1Preset(Color.LightGreen, TimeSpan.FromSeconds(5)), 11); + } - [RequireBlink1Hardware] - public void SetAllPatterns() - { - blink1.Save(new Blink1Preset(Color.Cyan, TimeSpan.FromSeconds(5)), 0); - blink1.Save(new Blink1Preset(Color.DarkCyan, TimeSpan.FromSeconds(5)), 1); - blink1.Save(new Blink1Preset(Color.CadetBlue, TimeSpan.FromSeconds(5)), 2); - blink1.Save(new Blink1Preset(Color.SteelBlue, TimeSpan.FromSeconds(5)), 3); - blink1.Save(new Blink1Preset(Color.DodgerBlue, TimeSpan.FromSeconds(5)), 4); - blink1.Save(new Blink1Preset(Color.MediumBlue, TimeSpan.FromSeconds(5)), 5); - blink1.Save(new Blink1Preset(Color.DarkBlue, TimeSpan.FromSeconds(5)), 6); - blink1.Save(new Blink1Preset(Color.Green, TimeSpan.FromSeconds(5)), 7); - blink1.Save(new Blink1Preset(Color.SeaGreen, TimeSpan.FromSeconds(5)), 8); - blink1.Save(new Blink1Preset(Color.MediumSeaGreen, TimeSpan.FromSeconds(5)), 9); - blink1.Save(new Blink1Preset(Color.SpringGreen, TimeSpan.FromSeconds(5)), 10); - blink1.Save(new Blink1Preset(Color.LightGreen, TimeSpan.FromSeconds(5)), 11); - } + [RequireBlink1Hardware] + public void ReadSerialReadsValidSerialNumber() + { + var actual = blink1.SerialNumber; - [RequireBlink1Hardware] - public void ReadSerialReadsValidSerialNumber() - { - var actual = blink1.SerialNumber; + Assert.InRange(actual, LowestSerialNumber, HighestSerialNumber); + } - Assert.InRange(actual, LowestSerialNumber, HighestSerialNumber); - } + [RequireBlink1Hardware] + public void ReadPresetReturnsValidPreset() + { + var actual = blink1.ReadPreset(0); - [RequireBlink1Hardware] - public void ReadPresetReturnsValidPreset() - { - var actual = blink1.ReadPreset(0); + Assert.NotNull(actual); + } - Assert.NotNull(actual); - } + [RequireBlink1Hardware] + public void SavePresetWritesToDevice() + { + var expected = new Blink1Preset(Color.DarkSlateGray, TimeSpan.FromSeconds(1.5)); - [RequireBlink1Hardware] - public void SavePresetWritesToDevice() - { - var expected = new Blink1Preset(Color.DarkSlateGray, TimeSpan.FromSeconds(1.5)); + blink1.EnableGamma = false; - blink1.EnableGamma = false; + blink1.Save(expected, 0); - blink1.Save(expected, 0); + var actual = blink1.ReadPreset(0); - var actual = blink1.ReadPreset(0); + Assert.Equal(expected, actual); + } - Assert.Equal(expected, actual); - } + [RequireBlink1Hardware] + public void SetColor() + { + var actual = blink1.Set(Color.Blue); - [RequireBlink1Hardware] - public void SetColor() - { - var actual = blink1.Set(Color.Blue); + Assert.True(actual); + } - Assert.True(actual); - } + [RequireBlink1Hardware] + public void ShowColor() + { + var showColorTime = TimeSpan.FromSeconds(2); - [RequireBlink1Hardware] - public void ShowColor() - { - var showColorTime = TimeSpan.FromSeconds(2); + var actual = blink1.Show(Color.Chartreuse, showColorTime); - var actual = blink1.Show(Color.Chartreuse, showColorTime); + Thread.Sleep(showColorTime); - Thread.Sleep(showColorTime); + Assert.True(actual); + } - Assert.True(actual); - } + [RequireBlink1Hardware] + public void FadeToColor() + { + var fadeDuration = TimeSpan.FromSeconds(2); - [RequireBlink1Hardware] - public void FadeToColor() - { - var fadeDuration = TimeSpan.FromSeconds(2); + var actual = blink1.Fade(Color.Red, fadeDuration); - var actual = blink1.Fade(Color.Red, fadeDuration); + Thread.Sleep(fadeDuration); - Thread.Sleep(fadeDuration); + Assert.True(actual); + } - Assert.True(actual); - } + [RequireBlink1Hardware] + public void SetPreset0AndPlayIt() + { + var presetDuration = TimeSpan.FromSeconds(2); - [RequireBlink1Hardware] - public void SetPreset0AndPlayIt() - { - var presetDuration = TimeSpan.FromSeconds(2); + var preset = new Blink1Preset(Color.DarkGoldenrod, presetDuration); - var preset = new Blink1Preset(Color.DarkGoldenrod, presetDuration); + blink1.Save(preset, 0); - blink1.Save(preset, 0); + blink1.Play(0); - blink1.Play(0); + Thread.Sleep(presetDuration); - Thread.Sleep(presetDuration); + blink1.Pause(); + } - blink1.Pause(); - } + [RequireBlink1Hardware] + public void PlayPreset() + { + blink1.Play(0); - [RequireBlink1Hardware] - public void PlayPreset() - { - blink1.Play(0); + Thread.Sleep(TimeSpan.FromSeconds(5)); - Thread.Sleep(TimeSpan.FromSeconds(5)); + blink1.Pause(); + } - blink1.Pause(); - } + [RequireBlink1Hardware] + public void TurnOff() + { + blink1.Set(Color.Black); + } - [RequireBlink1Hardware] - public void TurnOff() - { - blink1.Set(Color.Black); - } + [RequireBlink1Hardware] + public void EnableInactivityMode() + { + blink1.EnableInactivityMode(TimeSpan.FromMilliseconds(50)); - [RequireBlink1Hardware] - public void EnableInactivityMode() - { - blink1.EnableInactivityMode(TimeSpan.FromMilliseconds(50)); + Thread.Sleep(TimeSpan.FromMilliseconds(150)); - Thread.Sleep(TimeSpan.FromMilliseconds(150)); - - blink1.DisableInactivityMode(); - } - } + blink1.DisableInactivityMode(); + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1.ExplicitTests/Blink1mk2Fixture.cs b/src/Sleddog.Blink1.ExplicitTests/Blink1mk2Fixture.cs deleted file mode 100644 index 704c979..0000000 --- a/src/Sleddog.Blink1.ExplicitTests/Blink1mk2Fixture.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Linq; - -namespace Sleddog.Blink1.ExplicitTests -{ - public class Blink1Mk2Fixture : IDisposable - { - private readonly IBlink1Mk2 blink1; - - public Blink1Mk2Fixture() - { - blink1 = Blink1Connector.Scan().FirstOrDefault(b => (b is IBlink1Mk2)) as IBlink1Mk2; - } - - public IBlink1Mk2 Device => blink1; - - public void Dispose() - { - blink1?.Dispose(); - } - } -} \ No newline at end of file diff --git a/src/Sleddog.Blink1.ExplicitTests/Blink1mk2Tests.cs b/src/Sleddog.Blink1.ExplicitTests/Blink1mk2Tests.cs index de95406..52f56c9 100644 --- a/src/Sleddog.Blink1.ExplicitTests/Blink1mk2Tests.cs +++ b/src/Sleddog.Blink1.ExplicitTests/Blink1mk2Tests.cs @@ -5,147 +5,55 @@ namespace Sleddog.Blink1.ExplicitTests { - public class Blink1Mk2Tests : IClassFixture - { - private const string LowestSerialNumber = "0x20001000"; - private const string HighestSerialNumber = "0x20003710"; + public class Blink1Mk2Tests : IClassFixture> + { + private readonly IBlink1Mk2 blink1; - private readonly IBlink1Mk2 blink1; + public Blink1Mk2Tests(Blink1Fixture fixture) + { + blink1 = fixture.Device; + } - public Blink1Mk2Tests(Blink1Mk2Fixture fixture) - { - blink1 = fixture.Device; - } + [RequireBlink1Mk2Hardware] + public void FadeTopToColor() + { + var fadeDuration = TimeSpan.FromSeconds(2); - [RequireBlink1Mk2Hardware] - public void SetAllPatterns() - { - blink1.Save(new Blink1Preset(Color.Cyan, TimeSpan.FromSeconds(5)), 0); - blink1.Save(new Blink1Preset(Color.DarkCyan, TimeSpan.FromSeconds(5)), 1); - blink1.Save(new Blink1Preset(Color.CadetBlue, TimeSpan.FromSeconds(5)), 2); - blink1.Save(new Blink1Preset(Color.SteelBlue, TimeSpan.FromSeconds(5)), 3); - blink1.Save(new Blink1Preset(Color.DodgerBlue, TimeSpan.FromSeconds(5)), 4); - blink1.Save(new Blink1Preset(Color.MediumBlue, TimeSpan.FromSeconds(5)), 5); - blink1.Save(new Blink1Preset(Color.DarkBlue, TimeSpan.FromSeconds(5)), 6); - blink1.Save(new Blink1Preset(Color.Green, TimeSpan.FromSeconds(5)), 7); - blink1.Save(new Blink1Preset(Color.SeaGreen, TimeSpan.FromSeconds(5)), 8); - blink1.Save(new Blink1Preset(Color.MediumSeaGreen, TimeSpan.FromSeconds(5)), 9); - blink1.Save(new Blink1Preset(Color.SpringGreen, TimeSpan.FromSeconds(5)), 10); - blink1.Save(new Blink1Preset(Color.LightGreen, TimeSpan.FromSeconds(5)), 11); - } + var actual = blink1.Fade(Color.Red, fadeDuration, LEDPosition.Top); - [RequireBlink1Mk2Hardware] - public void ReadSerialReadsValidSerialNumber() - { - var actual = blink1.SerialNumber; + Thread.Sleep(fadeDuration); - Assert.InRange(actual, LowestSerialNumber, HighestSerialNumber); - } + Assert.True(actual); + } - [RequireBlink1Mk2Hardware] - public void ReadPresetReturnsValidPreset() - { - var actual = blink1.ReadPreset(0); + [RequireBlink1Mk2Hardware] + public void FadeBottomToColor() + { + var fadeDuration = TimeSpan.FromSeconds(2); - Assert.NotNull(actual); - } + var actual = blink1.Fade(Color.Red, fadeDuration, LEDPosition.Bottom); - [RequireBlink1Mk2Hardware(Skip = "Current issue with color comparison, but it is right")] - public void SavePresetWritesToDevice() - { - var expected = new Blink1Preset(Color.FromArgb(255, 50, 100, 200), TimeSpan.FromSeconds(1.5)); + Thread.Sleep(fadeDuration); - blink1.EnableGamma = false; + Assert.True(actual); + } - blink1.Save(expected, 0); + [RequireBlink1Mk2Hardware] + public void FadeToColor() + { + var fadeDuration = TimeSpan.FromSeconds(2); - var actual = blink1.ReadPreset(0); + var actual = blink1.Fade(Color.Red, fadeDuration, LEDPosition.Both); - Assert.Equal(expected, actual); - } + Thread.Sleep(fadeDuration); - [RequireBlink1Mk2Hardware] - public void SetColor() - { - var actual = blink1.Set(Color.Blue); + Assert.True(actual); + } - Assert.True(actual); - } - - [RequireBlink1Mk2Hardware] - public void ShowColor() - { - var showColorTime = TimeSpan.FromSeconds(2); - - var actual = blink1.Show(Color.Chartreuse, showColorTime); - - Thread.Sleep(showColorTime); - - Assert.True(actual); - } - - [RequireBlink1Mk2Hardware] - public void FadeToColor() - { - var fadeDuration = TimeSpan.FromSeconds(2); - - var actual = blink1.Fade(Color.Red, fadeDuration); - - Thread.Sleep(fadeDuration); - - Assert.True(actual); - } - - [RequireBlink1Mk2Hardware] - public void SetPreset0AndPlayIt() - { - var presetDuration = TimeSpan.FromSeconds(2); - - var preset = new Blink1Preset(Color.DarkGoldenrod, presetDuration); - - blink1.Save(preset, 0); - - blink1.Play(0); - - Thread.Sleep(presetDuration); - - blink1.Pause(); - } - - [RequireBlink1Mk2Hardware] - public void PlayPreset() - { - blink1.Play(0, 11, 0); - } - - [RequireBlink1Mk2Hardware] - public void PoliceBlinking() - { - for (var i = 0; i < 100; i++) - { - blink1.Fade(Color.Blue, TimeSpan.FromMilliseconds(25), (LEDPosition) (i%2)); - blink1.Fade(Color.Red, TimeSpan.FromMilliseconds(25), (LEDPosition) (i%2 + 1)); - - Thread.Sleep(200); - } - - blink1.Set(Color.Black); - } - - [RequireBlink1Mk2Hardware] - public void TurnOff() - { - blink1.Set(Color.Black); - } - - [RequireBlink1Mk2Hardware] - public void EnableInactivityMode() - { - blink1.EnableInactivityMode(TimeSpan.FromMilliseconds(50)); - - Thread.Sleep(TimeSpan.FromMilliseconds(150)); - - blink1.DisableInactivityMode(); - } - } + [RequireBlink1Mk2Hardware] + public void PlayPreset() + { + blink1.Play(0, 0, 2); + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1.ExplicitTests/BlinkHardwareScannerAttribute.cs b/src/Sleddog.Blink1.ExplicitTests/BlinkHardwareScannerAttribute.cs index 62909a8..7e3d31b 100644 --- a/src/Sleddog.Blink1.ExplicitTests/BlinkHardwareScannerAttribute.cs +++ b/src/Sleddog.Blink1.ExplicitTests/BlinkHardwareScannerAttribute.cs @@ -3,16 +3,15 @@ namespace Sleddog.Blink1.ExplicitTests { - public abstract class BlinkHardwareScannerAttribute : ExplicitFactAttribute - { - private const int VendorId = 0x27B8; - private const int ProductId = 0x01ED; + public abstract class BlinkHardwareScannerAttribute : ExplicitFactAttribute + { + protected readonly HidDevice[] Devices; + private const int VendorId = 0x27B8; + private const int ProductId = 0x01ED; - protected readonly HidDevice[] Devices; - - protected BlinkHardwareScannerAttribute() - { - Devices = HidDevices.Enumerate(VendorId, ProductId).ToArray(); - } - } + protected BlinkHardwareScannerAttribute() + { + Devices = HidDevices.Enumerate(VendorId, ProductId).ToArray(); + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1.ExplicitTests/ExplicitFactAttribute.cs b/src/Sleddog.Blink1.ExplicitTests/ExplicitFactAttribute.cs index 8bb3636..a3fa9cc 100644 --- a/src/Sleddog.Blink1.ExplicitTests/ExplicitFactAttribute.cs +++ b/src/Sleddog.Blink1.ExplicitTests/ExplicitFactAttribute.cs @@ -3,14 +3,14 @@ namespace Sleddog.Blink1.ExplicitTests { - public class ExplicitFactAttribute : FactAttribute - { - protected ExplicitFactAttribute() - { - if (!Debugger.IsAttached) - { - Skip = "Only running in interactive mode"; - } - } - } + public class ExplicitFactAttribute : FactAttribute + { + protected ExplicitFactAttribute() + { + if (!Debugger.IsAttached) + { + Skip = "Only running in interactive mode"; + } + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1.ExplicitTests/RequireBlink1HardwareAttribute.cs b/src/Sleddog.Blink1.ExplicitTests/RequireBlink1HardwareAttribute.cs index 2b5a207..82c00d2 100644 --- a/src/Sleddog.Blink1.ExplicitTests/RequireBlink1HardwareAttribute.cs +++ b/src/Sleddog.Blink1.ExplicitTests/RequireBlink1HardwareAttribute.cs @@ -3,30 +3,37 @@ namespace Sleddog.Blink1.ExplicitTests { - public class RequireBlink1HardwareAttribute : RequireBlinkHardwareAttribute - { - public RequireBlink1HardwareAttribute() - { - var blink1Devices = (from d in Devices where IsDeviceWithinBlink1Range(d) select d).ToArray(); - - if (!blink1Devices.Any()) - { - Skip = "No Blink1 units connected"; - } - } - - private bool IsDeviceWithinBlink1Range(HidDevice device) - { - byte[] serialBytes; - - var readSerial = device.ReadSerialNumber(out serialBytes); - - if (!readSerial) - { - return false; - } - - return serialBytes[0] == 0x31; - } - } + public class RequireBlink1HardwareAttribute : RequireBlinkHardwareAttribute + { + private readonly byte versionByte; + + public RequireBlink1HardwareAttribute() : this(0x31) + { } + + protected RequireBlink1HardwareAttribute(byte versionByte) + { + this.versionByte = versionByte; + + var blink1Devices = (from d in Devices where IsDeviceWithinBlink1Range(d) select d).ToArray(); + + if (!blink1Devices.Any()) + { + Skip = "No matching blink1 units connected"; + } + } + + private bool IsDeviceWithinBlink1Range(HidDevice device) + { + byte[] serialBytes; + + var readSerial = device.ReadSerialNumber(out serialBytes); + + if (!readSerial) + { + return false; + } + + return serialBytes[0] == versionByte; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1.ExplicitTests/RequireBlink1Mk3HardwareAttribute.cs b/src/Sleddog.Blink1.ExplicitTests/RequireBlink1Mk3HardwareAttribute.cs new file mode 100644 index 0000000..0857694 --- /dev/null +++ b/src/Sleddog.Blink1.ExplicitTests/RequireBlink1Mk3HardwareAttribute.cs @@ -0,0 +1,8 @@ +namespace Sleddog.Blink1.ExplicitTests +{ + public class RequireBlink1Mk3HardwareAttribute : RequireBlink1HardwareAttribute + { + public RequireBlink1Mk3HardwareAttribute() : base(0x33) + { } + } +} \ No newline at end of file diff --git a/src/Sleddog.Blink1.ExplicitTests/RequireBlink1mk2HardwareAttribute.cs b/src/Sleddog.Blink1.ExplicitTests/RequireBlink1mk2HardwareAttribute.cs index 21e5099..4825147 100644 --- a/src/Sleddog.Blink1.ExplicitTests/RequireBlink1mk2HardwareAttribute.cs +++ b/src/Sleddog.Blink1.ExplicitTests/RequireBlink1mk2HardwareAttribute.cs @@ -1,32 +1,8 @@ -using System.Linq; -using HidLibrary; - namespace Sleddog.Blink1.ExplicitTests { - public class RequireBlink1Mk2HardwareAttribute : RequireBlinkHardwareAttribute - { - public RequireBlink1Mk2HardwareAttribute() - { - var blink1Devices = (from d in Devices where IsDeviceWithinBlink1mk2Range(d) select d).ToArray(); - - if (!blink1Devices.Any()) - { - Skip = "No Blink1mk2 units connected"; - } - } - - private bool IsDeviceWithinBlink1mk2Range(HidDevice device) - { - byte[] serialBytes; - - var readSerial = device.ReadSerialNumber(out serialBytes); - - if (!readSerial) - { - return false; - } - - return serialBytes[0] == 0x32; - } - } + public class RequireBlink1Mk2HardwareAttribute : RequireBlink1HardwareAttribute + { + public RequireBlink1Mk2HardwareAttribute() : base(0x32) + { } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1.ExplicitTests/RequireBlinkHardwareAttribute.cs b/src/Sleddog.Blink1.ExplicitTests/RequireBlinkHardwareAttribute.cs index cd51b3e..573c806 100644 --- a/src/Sleddog.Blink1.ExplicitTests/RequireBlinkHardwareAttribute.cs +++ b/src/Sleddog.Blink1.ExplicitTests/RequireBlinkHardwareAttribute.cs @@ -2,14 +2,14 @@ namespace Sleddog.Blink1.ExplicitTests { - public class RequireBlinkHardwareAttribute : BlinkHardwareScannerAttribute - { - public RequireBlinkHardwareAttribute() - { - if (!Devices.Any()) - { - Skip = "No Blink devices connected"; - } - } - } + public class RequireBlinkHardwareAttribute : BlinkHardwareScannerAttribute + { + public RequireBlinkHardwareAttribute() + { + if (!Devices.Any()) + { + Skip = "No Blink devices connected"; + } + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1.ExplicitTests/RequireNoBlinkHardwareAttribute.cs b/src/Sleddog.Blink1.ExplicitTests/RequireNoBlinkHardwareAttribute.cs index 0dd396c..5244fd3 100644 --- a/src/Sleddog.Blink1.ExplicitTests/RequireNoBlinkHardwareAttribute.cs +++ b/src/Sleddog.Blink1.ExplicitTests/RequireNoBlinkHardwareAttribute.cs @@ -2,14 +2,14 @@ namespace Sleddog.Blink1.ExplicitTests { - public class RequireNoBlinkHardwareAttribute : BlinkHardwareScannerAttribute - { - public RequireNoBlinkHardwareAttribute() - { - if (Devices.Any()) - { - Skip = "Blink1 devices connected"; - } - } - } + public class RequireNoBlinkHardwareAttribute : BlinkHardwareScannerAttribute + { + public RequireNoBlinkHardwareAttribute() + { + if (Devices.Any()) + { + Skip = "Blink1 devices connected"; + } + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1.ExplicitTests/Sleddog.Blink1.ExplicitTests.csproj b/src/Sleddog.Blink1.ExplicitTests/Sleddog.Blink1.ExplicitTests.csproj index c618b0d..eaf56a8 100644 --- a/src/Sleddog.Blink1.ExplicitTests/Sleddog.Blink1.ExplicitTests.csproj +++ b/src/Sleddog.Blink1.ExplicitTests/Sleddog.Blink1.ExplicitTests.csproj @@ -69,14 +69,16 @@ - - + + + + diff --git a/src/Sleddog.Blink1.ExplicitTests/app.config b/src/Sleddog.Blink1.ExplicitTests/app.config index e6bc3bf..c980e0a 100644 --- a/src/Sleddog.Blink1.ExplicitTests/app.config +++ b/src/Sleddog.Blink1.ExplicitTests/app.config @@ -1,28 +1,31 @@  + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Sleddog.Blink1.ExplicitTests/packages.config b/src/Sleddog.Blink1.ExplicitTests/packages.config index 16ea448..88884ab 100644 --- a/src/Sleddog.Blink1.ExplicitTests/packages.config +++ b/src/Sleddog.Blink1.ExplicitTests/packages.config @@ -1,12 +1,13 @@  + - - - - - - - - - + + + + + + + + + \ No newline at end of file diff --git a/src/Sleddog.Blink1.Tests/Blink1DurationTests.cs b/src/Sleddog.Blink1.Tests/Blink1DurationTests.cs index 7a58292..84665e6 100644 --- a/src/Sleddog.Blink1.Tests/Blink1DurationTests.cs +++ b/src/Sleddog.Blink1.Tests/Blink1DurationTests.cs @@ -6,106 +6,109 @@ namespace Sleddog.Blink1.Tests { - public class Blink1DurationTests - { - private static readonly Random Random = new Random(); - - [Theory, MemberData(nameof(HighTestData))] - public void HighIsSetCorrectlyFromTimeSpanCtorInput(uint timeInMilliseconds, byte expected) - { - var ts = TimeSpan.FromMilliseconds(timeInMilliseconds); - - var sut = new Blink1Duration(ts); - - var actual = sut.High; - - Assert.Equal(expected, actual); - } - - [Theory, MemberData(nameof(LowTestData))] - public void LowIsSetCorrectlyFromTimeSpanCtorInput(uint timeInMilliseconds, byte expected) - { - var ts = TimeSpan.FromMilliseconds(timeInMilliseconds); - - var sut = new Blink1Duration(ts); - - var actual = sut.Low; - - Assert.Equal(expected, actual); - } - - [Theory, MemberData(nameof(ImplicitTestData))] - public void ImplicitConversionToTimeSpan(uint timeInMilliseconds, uint expected) - { - var ts = TimeSpan.FromMilliseconds(timeInMilliseconds); - - var sut = new Blink1Duration(ts); - - TimeSpan actual = sut; - - Assert.Equal(expected, actual.TotalMilliseconds); - } - - public static IEnumerable HighTestData - { - get - { - yield return new object[] {0u, new byte()}; - - foreach (var val in GenerateSampleData()) - { - var expected = Convert.ToByte(CalculateOutcomeValue(val) >> 8); - - yield return new object[] {val, expected}; - } - } - } - - public static IEnumerable LowTestData - { - get - { - yield return new object[] {0u, new byte()}; - - foreach (var val in GenerateSampleData()) - { - var expected = Convert.ToByte(CalculateOutcomeValue(val) & 0xFF); - - yield return new object[] {val, expected}; - } - } - } - - public static IEnumerable ImplicitTestData - { - get - { - yield return new object[] {0u, 0u}; - yield return new object[] {250u, 250u}; - yield return new object[] {254u, 250u}; - yield return new object[] {255u, 260u}; - yield return new object[] {256u, 260u}; - - foreach (var val in GenerateSampleData()) - { - var expected = CalculateOutcomeValue(val)*10; - - yield return new object[] {val, expected}; - } - } - } - - private static uint CalculateOutcomeValue(uint val) - { - var blink1Duration = (double) val/10; - var roundedDuration = Math.Round(blink1Duration, 0, MidpointRounding.ToEven); - - return Convert.ToUInt32(roundedDuration); - } - - private static IEnumerable GenerateSampleData() - { - return Enumerable.Range(0, 15).Select(_ => (uint) Random.Next(0, 365000)); - } - } + public class Blink1DurationTests + { + private static readonly Random Random = new Random(); + + public static IEnumerable HighTestData + { + get + { + yield return new object[] {0u, new byte()}; + + foreach (var val in GenerateSampleData()) + { + var expected = Convert.ToByte(CalculateOutcomeValue(val) >> 8); + + yield return new object[] {val, expected}; + } + } + } + + public static IEnumerable LowTestData + { + get + { + yield return new object[] {0u, new byte()}; + + foreach (var val in GenerateSampleData()) + { + var expected = Convert.ToByte(CalculateOutcomeValue(val) & 0xFF); + + yield return new object[] {val, expected}; + } + } + } + + public static IEnumerable ImplicitTestData + { + get + { + yield return new object[] {0u, 0u}; + yield return new object[] {250u, 250u}; + yield return new object[] {254u, 250u}; + yield return new object[] {255u, 260u}; + yield return new object[] {256u, 260u}; + + foreach (var val in GenerateSampleData()) + { + var expected = CalculateOutcomeValue(val) * 10; + + yield return new object[] {val, expected}; + } + } + } + + [Theory] + [MemberData(nameof(HighTestData))] + public void HighIsSetCorrectlyFromTimeSpanCtorInput(uint timeInMilliseconds, byte expected) + { + var ts = TimeSpan.FromMilliseconds(timeInMilliseconds); + + var sut = new Blink1Duration(ts); + + var actual = sut.High; + + Assert.Equal(expected, actual); + } + + [Theory] + [MemberData(nameof(LowTestData))] + public void LowIsSetCorrectlyFromTimeSpanCtorInput(uint timeInMilliseconds, byte expected) + { + var ts = TimeSpan.FromMilliseconds(timeInMilliseconds); + + var sut = new Blink1Duration(ts); + + var actual = sut.Low; + + Assert.Equal(expected, actual); + } + + [Theory] + [MemberData(nameof(ImplicitTestData))] + public void ImplicitConversionToTimeSpan(uint timeInMilliseconds, uint expected) + { + var ts = TimeSpan.FromMilliseconds(timeInMilliseconds); + + var sut = new Blink1Duration(ts); + + TimeSpan actual = sut; + + Assert.Equal(expected, actual.TotalMilliseconds); + } + + private static uint CalculateOutcomeValue(uint val) + { + var blink1Duration = (double) val / 10; + var roundedDuration = Math.Round(blink1Duration, 0, MidpointRounding.ToEven); + + return Convert.ToUInt32(roundedDuration); + } + + private static IEnumerable GenerateSampleData() + { + return Enumerable.Range(0, 15).Select(_ => (uint) Random.Next(0, 365000)); + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1.Tests/Colors/ColorGeneratorTests.cs b/src/Sleddog.Blink1.Tests/Colors/ColorGeneratorTests.cs index c72f7a7..674da5f 100644 --- a/src/Sleddog.Blink1.Tests/Colors/ColorGeneratorTests.cs +++ b/src/Sleddog.Blink1.Tests/Colors/ColorGeneratorTests.cs @@ -5,33 +5,33 @@ namespace Sleddog.Blink1.Tests.Colors { - public class ColorGeneratorTests - { - [Theory] - [AutoData] - public void GenerateColorsReturnsTheGivenCountOfColors(int numberOfColors) - { - var sut = new ColorGenerator(); + public class ColorGeneratorTests + { + [Theory] + [AutoData] + public void GenerateColorsReturnsTheGivenCountOfColors(int numberOfColors) + { + var sut = new ColorGenerator(); - var colors = sut.GenerateColors(numberOfColors); + var colors = sut.GenerateColors(numberOfColors); - var expected = numberOfColors; - var actual = colors.Count; + var expected = numberOfColors; + var actual = colors.Count; - Assert.Equal(expected, actual); - } + Assert.Equal(expected, actual); + } - [Theory] - [AutoData] - public void GeneratedColorsAreDifferent(int numberOfColors) - { - var sut = new ColorGenerator(); + [Theory] + [AutoData] + public void GeneratedColorsAreDifferent(int numberOfColors) + { + var sut = new ColorGenerator(); - var expected = sut.GenerateColors(numberOfColors); + var expected = sut.GenerateColors(numberOfColors); - var actual = expected.Distinct(); + var actual = expected.Distinct(); - Assert.Equal(expected, actual); - } - } + Assert.Equal(expected, actual); + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1.Tests/Colors/GammaCorrectorTests.cs b/src/Sleddog.Blink1.Tests/Colors/GammaCorrectorTests.cs new file mode 100644 index 0000000..5c43cd9 --- /dev/null +++ b/src/Sleddog.Blink1.Tests/Colors/GammaCorrectorTests.cs @@ -0,0 +1,33 @@ +using System.Drawing; +using Sleddog.Blink1.Colors; +using Xunit; + +namespace Sleddog.Blink1.Tests.Colors +{ + public class GammaCorrectorTests + { + [Fact] + public void Decode() + { + var expected = Color.FromArgb(255, 50, 100, 200); + + var sut = new GammaCorrector(); + + var actual = sut.Decode(Color.FromArgb(255, 7, 33, 149)); + + Assert.Equal(expected, actual, new GoodEnoughColorComparer()); + } + + [Fact] + public void Encode() + { + var expected = Color.FromArgb(255, 7, 33, 149); + + var sut = new GammaCorrector(); + + var actual = sut.Encode(Color.FromArgb(255, 50, 100, 200)); + + Assert.Equal(expected, actual, new GoodEnoughColorComparer()); + } + } +} \ No newline at end of file diff --git a/src/Sleddog.Blink1.Tests/Colors/HSLTests.cs b/src/Sleddog.Blink1.Tests/Colors/HSLTests.cs index f2a0869..4c529bc 100644 --- a/src/Sleddog.Blink1.Tests/Colors/HSLTests.cs +++ b/src/Sleddog.Blink1.Tests/Colors/HSLTests.cs @@ -7,64 +7,64 @@ namespace Sleddog.Blink1.Tests.Colors { - public class HslTests - { - public static IEnumerable Hsl2Rgb - { - get - { - return new[] - { - new object[] {(ushort) 0, 0, 1, Color.FromArgb(255, 255, 255)}, - new object[] {(ushort) 0, 0, 0.502f, Color.FromArgb(128, 128, 128)}, - new object[] {(ushort) 0, 0, 0, Color.FromArgb(0, 0, 0)}, - new object[] {(ushort) 0, 1, 0.5f, Color.FromArgb(255, 0, 0)}, - new object[] {(ushort) 120, 1, 0.5f, Color.FromArgb(0, 255, 0)}, - new object[] {(ushort) 240, 1, 0.5f, Color.FromArgb(0, 0, 255)}, - new object[] {(ushort) 284, 0.807f, 0.224f, Color.FromArgb(78, 11, 103)}, - new object[] {(ushort) 210, 0.50f, 0.165f, Color.FromArgb(21, 42, 63)} - }; - } - } + public class HslTests + { + public static IEnumerable Hsl2Rgb + { + get + { + return new[] + { + new object[] {(ushort) 0, 0, 1, Color.FromArgb(255, 255, 255)}, + new object[] {(ushort) 0, 0, 0.502f, Color.FromArgb(128, 128, 128)}, + new object[] {(ushort) 0, 0, 0, Color.FromArgb(0, 0, 0)}, + new object[] {(ushort) 0, 1, 0.5f, Color.FromArgb(255, 0, 0)}, + new object[] {(ushort) 120, 1, 0.5f, Color.FromArgb(0, 255, 0)}, + new object[] {(ushort) 240, 1, 0.5f, Color.FromArgb(0, 0, 255)}, + new object[] {(ushort) 284, 0.807f, 0.224f, Color.FromArgb(78, 11, 103)}, + new object[] {(ushort) 210, 0.50f, 0.165f, Color.FromArgb(21, 42, 63)} + }; + } + } - [Theory] - [InlineData((ushort) 361, 0, 0)] - [InlineData((ushort) 0, 1.1f, 0)] - [InlineData((ushort) 0, 0, 1.1f)] - public void HslCtorBoundaryCheck(ushort hue, float saturation, float luminance) - { - Assert.Throws(() => new Hsl(hue, saturation, luminance)); - } + [Theory] + [InlineData((ushort) 361, 0, 0)] + [InlineData((ushort) 0, 1.1f, 0)] + [InlineData((ushort) 0, 0, 1.1f)] + public void HslCtorBoundaryCheck(ushort hue, float saturation, float luminance) + { + Assert.Throws(() => new Hsl(hue, saturation, luminance)); + } - [Theory] - [MemberData(nameof(Hsl2Rgb))] - public void HsltoRgbIsConvertedCorrectly(ushort hue, float saturation, float luminance, Color expected) - { - var sut = new Hsl(hue, saturation, luminance); + [Theory] + [MemberData(nameof(Hsl2Rgb))] + public void HsltoRgbIsConvertedCorrectly(ushort hue, float saturation, float luminance, Color expected) + { + var sut = new Hsl(hue, saturation, luminance); - Color actual = sut; + Color actual = sut; - Assert.Equal(expected, actual); - } + Assert.Equal(expected, actual); + } - [Theory] - [AutoData] - public void ZeroSaturationRendersColorFactoredByLuminance(ushort hue, float luminance) - { - var hueValue = (ushort) (hue % 360); - var luminanceValue = luminance % 1; + [Theory] + [AutoData] + public void ZeroSaturationRendersColorFactoredByLuminance(ushort hue, float luminance) + { + var hueValue = (ushort) (hue % 360); + var luminanceValue = luminance % 1; - var hsl = new Hsl(hueValue, 0, luminanceValue); + var hsl = new Hsl(hueValue, 0, luminanceValue); - Color actual = hsl; + Color actual = hsl; - var colorValue = luminanceValue / 1 * 255; + var colorValue = luminanceValue / 1 * 255; - var expectedColorValue = Convert.ToInt32(colorValue); + var expectedColorValue = Convert.ToInt32(colorValue); - var expected = Color.FromArgb(expectedColorValue, expectedColorValue, expectedColorValue); + var expected = Color.FromArgb(expectedColorValue, expectedColorValue, expectedColorValue); - Assert.Equal(expected, actual); - } - } + Assert.Equal(expected, actual); + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1.Tests/GoodEnoughColorComparer.cs b/src/Sleddog.Blink1.Tests/GoodEnoughColorComparer.cs new file mode 100644 index 0000000..5ad0301 --- /dev/null +++ b/src/Sleddog.Blink1.Tests/GoodEnoughColorComparer.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.Drawing; + +namespace Sleddog.Blink1.Tests +{ + public class GoodEnoughColorComparer : IEqualityComparer + { + public bool Equals(Color x, Color y) + { + return InRange(x.A, y.A - 1, y.A + 1) && + InRange(x.R, y.R - 1, y.R + 1) && + InRange(x.G, y.G - 1, y.G + 1) && + InRange(x.B, y.B - 1, y.B + 1); + } + + public int GetHashCode(Color color) + { + unchecked + { + return (color.A.GetHashCode() * 397) ^ color.R.GetHashCode() ^ color.G.GetHashCode() ^ color.B.GetHashCode(); + } + } + + private bool InRange(int value, int low, int high) + { + return low <= value && value <= high; + } + } +} \ No newline at end of file diff --git a/src/Sleddog.Blink1.Tests/Sleddog.Blink1.Tests.csproj b/src/Sleddog.Blink1.Tests/Sleddog.Blink1.Tests.csproj index b9e7a64..19ebf4e 100644 --- a/src/Sleddog.Blink1.Tests/Sleddog.Blink1.Tests.csproj +++ b/src/Sleddog.Blink1.Tests/Sleddog.Blink1.Tests.csproj @@ -76,6 +76,8 @@ + + diff --git a/src/Sleddog.Blink1.Tests/app.config b/src/Sleddog.Blink1.Tests/app.config index a5e1722..d2fccee 100644 --- a/src/Sleddog.Blink1.Tests/app.config +++ b/src/Sleddog.Blink1.Tests/app.config @@ -1,36 +1,39 @@  + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Sleddog.Blink1.Tests/packages.config b/src/Sleddog.Blink1.Tests/packages.config index c2ea542..fe02185 100644 --- a/src/Sleddog.Blink1.Tests/packages.config +++ b/src/Sleddog.Blink1.Tests/packages.config @@ -1,14 +1,15 @@  + - - - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/src/Sleddog.Blink1/Blink1.cs b/src/Sleddog.Blink1/Blink1.cs index b085faf..e436ce6 100644 --- a/src/Sleddog.Blink1/Blink1.cs +++ b/src/Sleddog.Blink1/Blink1.cs @@ -7,149 +7,172 @@ namespace Sleddog.Blink1 { - public class Blink1 : IBlink1, IDisposable - { - internal readonly Blink1CommandBus CommandBus; - protected readonly ushort NumberOfPresets; + public class Blink1 : IBlink1, IDisposable + { + internal readonly Blink1CommandBus CommandBus; + protected readonly ushort NumberOfPresets; - internal Blink1(Blink1CommandBus commandBus) : this(commandBus, 12) - { - } + internal Blink1(Blink1CommandBus commandBus) : this(commandBus, 12) + { } - internal Blink1(Blink1CommandBus commandBus, ushort numberOfPresets) - { - EnableGamma = true; + internal Blink1(Blink1CommandBus commandBus, ushort numberOfPresets) + { + EnableGamma = true; - CommandBus = commandBus; - NumberOfPresets = numberOfPresets; - } + CommandBus = commandBus; + NumberOfPresets = numberOfPresets; + } - public bool EnableGamma { get; set; } + public bool EnableGamma { get; set; } - public Version Version => CommandBus.SendQuery(new VersionQuery()); + public Version Version => CommandBus.SendQuery(new VersionQuery()); - public string SerialNumber => CommandBus.ReadSerial(); + public string SerialNumber => CommandBus.ReadSerial(); - public bool Blink(Color inputColor, TimeSpan interval, ushort times) - { - var timeOnInMilliseconds = Math.Min(interval.TotalMilliseconds / 4, 250); + public bool Blink(Color inputColor, TimeSpan interval, ushort times) + { + var timeOnInMilliseconds = Math.Min(interval.TotalMilliseconds / 4, 250); - var onTime = TimeSpan.FromMilliseconds(timeOnInMilliseconds); + var onTime = TimeSpan.FromMilliseconds(timeOnInMilliseconds); - var color = ProcessColor(inputColor); + var color = EncodeColor(inputColor); - var x = Observable.Timer(TimeSpan.Zero, interval).TakeWhile(count => count < times).Select(_ => color); - var y = Observable.Timer(onTime, interval).TakeWhile(count => count < times).Select(_ => Color.Black); + var x = Observable.Timer(TimeSpan.Zero, interval).TakeWhile(count => count < times).Select(_ => color); + var y = Observable.Timer(onTime, interval).TakeWhile(count => count < times).Select(_ => Color.Black); - x.Merge(y).Subscribe(c => CommandBus.SendCommand(new SetColorCommand(c))); + x.Merge(y).Subscribe(c => CommandBus.SendCommand(new SetColorCommand(c))); - return true; - } + return true; + } - public bool Set(Color inputColor) - { - var color = ProcessColor(inputColor); + public bool Set(Color inputColor) + { + var color = EncodeColor(inputColor); - return CommandBus.SendCommand(new SetColorCommand(color)); - } + return CommandBus.SendCommand(new SetColorCommand(color)); + } - public bool Fade(Color inputColor, TimeSpan fadeDuration) - { - var color = ProcessColor(inputColor); + public bool Fade(Color inputColor, TimeSpan fadeDuration) + { + var color = EncodeColor(inputColor); - return CommandBus.SendCommand(new FadeToColorCommand(color, fadeDuration)); - } + return CommandBus.SendCommand(new FadeToColorCommand(color, fadeDuration)); + } - public bool Show(Color inputColor, TimeSpan visibleTime) - { - var timer = ObservableExt.TimerMaxTick(1, TimeSpan.Zero, visibleTime); + public bool Show(Color inputColor, TimeSpan visibleTime) + { + var timer = ObservableExt.TimerMaxTick(1, TimeSpan.Zero, visibleTime); - var color = ProcessColor(inputColor); + var color = EncodeColor(inputColor); - var colors = new[] {color, Color.Black}.ToObservable(); + var colors = new[] {color, Color.Black}.ToObservable(); - colors.Zip(timer, (c, t) => new {Color = c, Count = t}) - .Subscribe(item => CommandBus.SendCommand(new SetColorCommand(item.Color))); + colors.Zip(timer, (c, t) => new {Color = c, Count = t}) + .Subscribe(item => CommandBus.SendCommand(new SetColorCommand(item.Color))); - return true; - } + return true; + } - public bool Save(Blink1Preset preset, ushort position) - { - if (position < NumberOfPresets) - { - if (EnableGamma) - { - var color = ProcessColor(preset.Color); + public bool Save(Blink1Preset preset, ushort position) + { + if (position < NumberOfPresets) + { + if (EnableGamma) + { + var color = EncodeColor(preset.Color); - var correctedPreset = new Blink1Preset(color, preset.Duration); + var correctedPreset = new Blink1Preset(color, preset.Duration); - return CommandBus.SendCommand(new SetPresetCommand(correctedPreset, position)); - } + return CommandBus.SendCommand(new SetPresetCommand(correctedPreset, position)); + } - return CommandBus.SendCommand(new SetPresetCommand(preset, position)); - } + return CommandBus.SendCommand(new SetPresetCommand(preset, position)); + } - var message = $"Unable to save a preset outside the upper count ({NumberOfPresets}) of preset slots"; + var message = $"Unable to save a preset outside the upper count ({NumberOfPresets}) of preset slots"; - throw new ArgumentOutOfRangeException(nameof(position), message); - } + throw new ArgumentOutOfRangeException(nameof(position), message); + } - public Blink1Preset ReadPreset(ushort position) - { - if (position < NumberOfPresets) - return CommandBus.SendQuery(new ReadPresetQuery(position)); + public Blink1Preset ReadPreset(ushort position) + { + if (position < NumberOfPresets) + { + var preset = CommandBus.SendQuery(new ReadPresetQuery(position)); - var message = $"Unable to read a preset from position {position} since there is only {NumberOfPresets} preset slots"; + if (EnableGamma) + { + var color = DecodeColor(preset.Color); - throw new ArgumentOutOfRangeException(nameof(position), message); - } + return new Blink1Preset(color, preset.Duration); + } - public bool Play(ushort startPosition) - { - if (startPosition < NumberOfPresets) - return CommandBus.SendCommand(new PlayPresetCommand(startPosition)); + return preset; + } - var message = $"Unable to play from position {startPosition} since there is only {NumberOfPresets} preset slots"; + var message = + $"Unable to read a preset from position {position} since there is only {NumberOfPresets} preset slots"; - throw new ArgumentOutOfRangeException(nameof(startPosition), message); - } + throw new ArgumentOutOfRangeException(nameof(position), message); + } - public bool Pause() - { - return CommandBus.SendCommand(new StopPresetCommand()); - } + public bool Play(ushort startPosition) + { + if (startPosition < NumberOfPresets) + return CommandBus.SendCommand(new PlayPresetCommand(startPosition)); - public bool EnableInactivityMode(TimeSpan waitDuration) - { - return CommandBus.SendCommand(new EnableInactivityModeCommand(waitDuration)); - } + var message = $"Unable to play from position {startPosition} since there is only {NumberOfPresets} preset slots"; - public bool DisableInactivityMode() - { - return CommandBus.SendCommand(new DisableInactivityModeCommand()); - } + throw new ArgumentOutOfRangeException(nameof(startPosition), message); + } - public void TurnOff() - { - Set(Color.Black); - } + public bool Pause() + { + return CommandBus.SendCommand(new StopPresetCommand()); + } - public void Dispose() - { - CommandBus?.Dispose(); - } + public bool EnableInactivityMode(TimeSpan waitDuration) + { + return CommandBus.SendCommand(new EnableInactivityModeCommand(waitDuration)); + } - private Color ProcessColor(Color inputColor) - { - if (EnableGamma) - { - var gammaCorrector = new GammaCorrector(); + public bool DisableInactivityMode() + { + return CommandBus.SendCommand(new DisableInactivityModeCommand()); + } - return gammaCorrector.Encode(inputColor); - } + public void TurnOff() + { + Set(Color.Black); + } - return inputColor; - } - } + public void Dispose() + { + CommandBus?.Dispose(); + } + + private Color EncodeColor(Color inputColor) + { + if (EnableGamma) + { + var gammaCorrector = new GammaCorrector(); + + return gammaCorrector.Encode(inputColor); + } + + return inputColor; + } + + private Color DecodeColor(Color inputColor) + { + if (EnableGamma) + { + var gammaCorrector = new GammaCorrector(); + + return gammaCorrector.Decode(inputColor); + } + + return inputColor; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Blink1Connector.cs b/src/Sleddog.Blink1/Blink1Connector.cs index 18e78f7..0fea799 100644 --- a/src/Sleddog.Blink1/Blink1Connector.cs +++ b/src/Sleddog.Blink1/Blink1Connector.cs @@ -16,7 +16,8 @@ public static class Blink1Connector private static readonly Dictionary deviceTypeMap = new Dictionary { {0x31, DeviceType.Blink1}, - {0x32, DeviceType.Blink1Mk2} + {0x32, DeviceType.Blink1Mk2}, + {0x33, DeviceType.Blink1Mk3} }; public static IBlink1 Connect(string serial) @@ -56,14 +57,7 @@ public static IEnumerable Scan() foreach (var device in deviceList) { - if (device.Item1 == DeviceType.Blink1) - { - yield return new Blink1(new Blink1CommandBus(device.Item2)); - } - else - { - yield return new Blink1Mk2(new Blink1CommandBus(device.Item2)); - } + yield return InstanceFactory(device.Item1, device.Item2); } } } @@ -90,6 +84,17 @@ from c in colors return blink1Identifiers; } + private static IBlink1 InstanceFactory(DeviceType deviceType, HidDevice device) + { + if (deviceType == DeviceType.Blink1) + return new Blink1(new Blink1CommandBus(device)); + + if (deviceType == DeviceType.Blink1Mk2) + return new Blink1Mk2(new Blink1CommandBus(device)); + + return new Blink1Mk3(new Blink1CommandBus(device)); + } + private static Tuple IdentityDevice(IHidDevice device) { device.ReadSerialNumber(out var output); @@ -142,7 +147,8 @@ private static DeviceType DetermineDeviceType(byte b) private enum DeviceType { Blink1, - Blink1Mk2 + Blink1Mk2, + Blink1Mk3 } } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Blink1Identifier.cs b/src/Sleddog.Blink1/Blink1Identifier.cs index 7837bed..5842164 100644 --- a/src/Sleddog.Blink1/Blink1Identifier.cs +++ b/src/Sleddog.Blink1/Blink1Identifier.cs @@ -2,15 +2,15 @@ namespace Sleddog.Blink1 { - public class Blink1Identifier - { - public IBlink1 Blink1 { get; } - public Color Color { get; } + public class Blink1Identifier + { + public IBlink1 Blink1 { get; } + public Color Color { get; } - public Blink1Identifier(IBlink1 blink1, Color color) - { - Blink1 = blink1; - Color = color; - } - } + public Blink1Identifier(IBlink1 blink1, Color color) + { + Blink1 = blink1; + Color = color; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Blink1Mk2.cs b/src/Sleddog.Blink1/Blink1Mk2.cs index e7c7432..530101e 100644 --- a/src/Sleddog.Blink1/Blink1Mk2.cs +++ b/src/Sleddog.Blink1/Blink1Mk2.cs @@ -5,53 +5,52 @@ namespace Sleddog.Blink1 { - public class Blink1Mk2 : Blink1, IBlink1Mk2 - { - internal Blink1Mk2(Blink1CommandBus commandBus) - : base(commandBus, 32) - { - } - - public new bool EnableGamma - { - get => base.EnableGamma; - set { } - } - - public bool Fade(Color color, TimeSpan fadeDuration, LEDPosition ledPosition) - { - var command = new FadeToColorCommand(color, fadeDuration, ledPosition); - - return CommandBus.SendCommand(command); - } - - public bool Play(ushort startPosition, ushort endPosition, ushort count) - { - var command = new PlayPresetCommand(startPosition, endPosition, count); - - return CommandBus.SendCommand(command); - } - - public bool SavePresets() - { - var command = new SavePresetsCommand(); - - return CommandBus.SendCommand(command); - } - - public bool EnabledInactivityMode(TimeSpan waitDuration, bool maintainState, ushort startPosition, - ushort endPosition) - { - var command = new EnableInactivityModeCommand(waitDuration, maintainState, startPosition, endPosition); - - return CommandBus.SendCommand(command); - } - - public PlaybackStatus ReadPlaybackStatus() - { - var query = new ReadPlaybackStateQuery(); - - return CommandBus.SendQuery(query); - } - } + public class Blink1Mk2 : Blink1, IBlink1Mk2 + { + internal Blink1Mk2(Blink1CommandBus commandBus) + : base(commandBus, 32) + { } + + public new bool EnableGamma + { + get => base.EnableGamma; + set { } + } + + public bool Fade(Color color, TimeSpan fadeDuration, LEDPosition ledPosition) + { + var command = new FadeToColorCommand(color, fadeDuration, ledPosition); + + return CommandBus.SendCommand(command); + } + + public bool Play(ushort startPosition, ushort endPosition, ushort count) + { + var command = new PlayPresetCommand(startPosition, endPosition, count); + + return CommandBus.SendCommand(command); + } + + public bool SavePresets() + { + var command = new SavePresetsCommand(); + + return CommandBus.SendCommand(command); + } + + public bool EnabledInactivityMode(TimeSpan waitDuration, bool maintainState, ushort startPosition, + ushort endPosition) + { + var command = new EnableInactivityModeCommand(waitDuration, maintainState, startPosition, endPosition); + + return CommandBus.SendCommand(command); + } + + public PlaybackStatus ReadPlaybackStatus() + { + var query = new ReadPlaybackStateQuery(); + + return CommandBus.SendQuery(query); + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Blink1Mk3.cs b/src/Sleddog.Blink1/Blink1Mk3.cs new file mode 100644 index 0000000..4ae81a2 --- /dev/null +++ b/src/Sleddog.Blink1/Blink1Mk3.cs @@ -0,0 +1,10 @@ +using Sleddog.Blink1.Internal; + +namespace Sleddog.Blink1 +{ + public class Blink1Mk3 : Blink1Mk2, IBlink1Mk3 + { + internal Blink1Mk3(Blink1CommandBus commandBus) : base(commandBus) + { } + } +} \ No newline at end of file diff --git a/src/Sleddog.Blink1/Blink1Preset.cs b/src/Sleddog.Blink1/Blink1Preset.cs index c7cba67..7b41f60 100644 --- a/src/Sleddog.Blink1/Blink1Preset.cs +++ b/src/Sleddog.Blink1/Blink1Preset.cs @@ -4,63 +4,69 @@ namespace Sleddog.Blink1 { - public class Blink1Preset - { - public Blink1Preset(Color color, TimeSpan duration) - { - Color = color; - PresetDuration = duration; - } + public class Blink1Preset + { + public Color Color { get; } - public Color Color { get; } + public TimeSpan Duration => PresetDuration; - public TimeSpan Duration => PresetDuration; + internal Blink1Duration PresetDuration { get; } - internal Blink1Duration PresetDuration { get; } + public Blink1Preset(Color color, TimeSpan duration) + { + Color = color; + PresetDuration = duration; + } - protected bool Equals(Blink1Preset other) - { - var equal = Color.R.Equals(other.Color.R) && - Color.G.Equals(other.Color.G) && - Color.B.Equals(other.Color.B) && - PresetDuration.Equals(other.PresetDuration); + protected bool Equals(Blink1Preset other) + { + var tollerance = 1; - return equal; - } + var equal = (Color.A - tollerance <= other.Color.A && other.Color.A <= Color.A + tollerance) && + (Color.R - tollerance <= other.Color.R && other.Color.R <= Color.R + tollerance) && + (Color.G - tollerance <= other.Color.G && other.Color.G <= Color.G + tollerance) && + (Color.B - tollerance <= other.Color.B && other.Color.B <= Color.B + tollerance) && + PresetDuration.Equals(other.PresetDuration); - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - if (ReferenceEquals(this, obj)) - { - return true; - } - if (obj.GetType() != GetType()) - { - return false; - } - return Equals((Blink1Preset) obj); - } + return equal; + } - public override int GetHashCode() - { - unchecked - { - return (Color.GetHashCode()*397) ^ (PresetDuration != null ? PresetDuration.GetHashCode() : 0); - } - } + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } - public static bool operator ==(Blink1Preset left, Blink1Preset right) - { - return Equals(left, right); - } + if (ReferenceEquals(this, obj)) + { + return true; + } - public static bool operator !=(Blink1Preset left, Blink1Preset right) - { - return !Equals(left, right); - } - } + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((Blink1Preset)obj); + } + + public override int GetHashCode() + { + unchecked + { + return (Color.GetHashCode() * 397) ^ (PresetDuration != null ? PresetDuration.GetHashCode() : 0); + } + } + + public static bool operator ==(Blink1Preset left, Blink1Preset right) + { + return Equals(left, right); + } + + public static bool operator !=(Blink1Preset left, Blink1Preset right) + { + return !Equals(left, right); + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Colors/ColorGenerator.cs b/src/Sleddog.Blink1/Colors/ColorGenerator.cs index 1b0b736..ee7f5f7 100644 --- a/src/Sleddog.Blink1/Colors/ColorGenerator.cs +++ b/src/Sleddog.Blink1/Colors/ColorGenerator.cs @@ -4,36 +4,36 @@ namespace Sleddog.Blink1.Colors { - internal class ColorGenerator - { - private static readonly Random Random = new Random(); + internal class ColorGenerator + { + private static readonly Random Random = new Random(); - public List GenerateColors(int colorCount) - { - var colors = new List(); + public List GenerateColors(int colorCount) + { + var colors = new List(); - var cellRange = 1f/colorCount; - var cellOffset = Random.NextDouble()*cellRange; + var cellRange = 1f / colorCount; + var cellOffset = Random.NextDouble() * cellRange; - for (var i = 0; i < colorCount; i++) - { - var newHue = cellRange*i + cellOffset; + for (var i = 0; i < colorCount; i++) + { + var newHue = cellRange * i + cellOffset; - if (newHue > 1) - { - newHue -= 1; - } + if (newHue > 1) + { + newHue -= 1; + } - newHue *= 360; + newHue *= 360; - var hue = Convert.ToUInt16(newHue); + var hue = Convert.ToUInt16(newHue); - var hslColor = new Hsl(hue, 0.3f, 0.4f); + var hslColor = new Hsl(hue, 0.3f, 0.4f); - colors.Add(hslColor); - } + colors.Add(hslColor); + } - return colors; - } - } + return colors; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Colors/GammaCorrector.cs b/src/Sleddog.Blink1/Colors/GammaCorrector.cs index 8b65101..a4fbec1 100644 --- a/src/Sleddog.Blink1/Colors/GammaCorrector.cs +++ b/src/Sleddog.Blink1/Colors/GammaCorrector.cs @@ -3,24 +3,41 @@ namespace Sleddog.Blink1.Colors { - internal class GammaCorrector - { - private static readonly double GammaValue = 2.2; - - public Color Encode(Color color) - { - var r = color.R; - var g = color.G; - var b = color.B; - - return Color.FromArgb(Encode(r), Encode(g), Encode(b)); - } - - private int Encode(int value) - { - var correctedValue = Math.Pow((value/(double) 255), GammaValue)*255; - - return (int) Math.Round(correctedValue); - } - } + internal class GammaCorrector + { + private static readonly double GammaValue = 2.2; + private static readonly double InverseGammaValue = 1 / GammaValue; + + public Color Encode(Color color) + { + var r = color.R; + var g = color.G; + var b = color.B; + + return Color.FromArgb(Encode(r), Encode(g), Encode(b)); + } + + public Color Decode(Color color) + { + var r = color.R; + var g = color.G; + var b = color.B; + + return Color.FromArgb(Decode(r), Decode(g), Decode(b)); + } + + private int Encode(int value) + { + var correctedValue = Math.Pow(value / (double) 255, GammaValue) * 255; + + return (int) Math.Round(correctedValue); + } + + private int Decode(int value) + { + var correctedValue = Math.Pow(value / (double) 255, InverseGammaValue) * 255; + + return (int) Math.Round(correctedValue); + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Colors/HSL.cs b/src/Sleddog.Blink1/Colors/HSL.cs index f16e85f..d352f29 100644 --- a/src/Sleddog.Blink1/Colors/HSL.cs +++ b/src/Sleddog.Blink1/Colors/HSL.cs @@ -3,90 +3,90 @@ namespace Sleddog.Blink1.Colors { - internal class Hsl - { - public ushort Hue { get; } - public float Saturation { get; } - public float Luminance { get; } + internal class Hsl + { + public ushort Hue { get; } + public float Saturation { get; } + public float Luminance { get; } - public Hsl(ushort hue, float saturation, float luminance) - { - if (hue > 360) - { - throw new ArgumentOutOfRangeException(nameof(hue)); - } + public Hsl(ushort hue, float saturation, float luminance) + { + if (hue > 360) + { + throw new ArgumentOutOfRangeException(nameof(hue)); + } - if (saturation < 0 || saturation > 1) - { - throw new ArgumentOutOfRangeException(nameof(saturation)); - } + if (saturation < 0 || saturation > 1) + { + throw new ArgumentOutOfRangeException(nameof(saturation)); + } - if (luminance < 0 || luminance > 1) - { - throw new ArgumentOutOfRangeException(nameof(luminance)); - } + if (luminance < 0 || luminance > 1) + { + throw new ArgumentOutOfRangeException(nameof(luminance)); + } - Hue = hue; - Saturation = saturation; - Luminance = luminance; - } + Hue = hue; + Saturation = saturation; + Luminance = luminance; + } - public static implicit operator Color(Hsl hsl) - { - var hue = hsl.Hue; - var saturation = hsl.Saturation; - var luminance = hsl.Luminance; + public static implicit operator Color(Hsl hsl) + { + var hue = hsl.Hue; + var saturation = hsl.Saturation; + var luminance = hsl.Luminance; - if (luminance.Equals(0)) - { - return Color.FromArgb(0, 0, 0); - } + if (luminance.Equals(0)) + { + return Color.FromArgb(0, 0, 0); + } - if (luminance.Equals(1)) - { - return Color.FromArgb(255, 255, 255); - } + if (luminance.Equals(1)) + { + return Color.FromArgb(255, 255, 255); + } - var chroma = (1 - Math.Abs(2*luminance - 1))*saturation; - var hSection = hue/60f; - var x = chroma*(1 - Math.Abs(hSection%2 - 1)); + var chroma = (1 - Math.Abs(2 * luminance - 1)) * saturation; + var hSection = hue / 60f; + var x = chroma * (1 - Math.Abs(hSection % 2 - 1)); - var rgbValues = Tuple.Create(0f, 0f, 0f); + var rgbValues = Tuple.Create(0f, 0f, 0f); - if (hSection >= 0 && hSection < 1) - { - rgbValues = Tuple.Create(chroma, x, 0f); - } - else if (hSection >= 1 && hSection < 2) - { - rgbValues = Tuple.Create(x, chroma, 0f); - } - else if (hSection >= 2 && hSection < 3) - { - rgbValues = Tuple.Create(0f, chroma, x); - } - else if (hSection >= 3 && hSection < 4) - { - rgbValues = Tuple.Create(0f, x, chroma); - } - else if (hSection >= 4 && hSection < 5) - { - rgbValues = Tuple.Create(x, 0f, chroma); - } - else if (hSection >= 5 && hSection < 6) - { - rgbValues = Tuple.Create(chroma, 0f, x); - } + if (hSection >= 0 && hSection < 1) + { + rgbValues = Tuple.Create(chroma, x, 0f); + } + else if (hSection >= 1 && hSection < 2) + { + rgbValues = Tuple.Create(x, chroma, 0f); + } + else if (hSection >= 2 && hSection < 3) + { + rgbValues = Tuple.Create(0f, chroma, x); + } + else if (hSection >= 3 && hSection < 4) + { + rgbValues = Tuple.Create(0f, x, chroma); + } + else if (hSection >= 4 && hSection < 5) + { + rgbValues = Tuple.Create(x, 0f, chroma); + } + else if (hSection >= 5 && hSection < 6) + { + rgbValues = Tuple.Create(chroma, 0f, x); + } - var m = luminance - 0.5f*chroma; + var m = luminance - 0.5f * chroma; - var modRgbValues = Tuple.Create(rgbValues.Item1 + m, rgbValues.Item2 + m, rgbValues.Item3 + m); + var modRgbValues = Tuple.Create(rgbValues.Item1 + m, rgbValues.Item2 + m, rgbValues.Item3 + m); - var r = (int) Math.Floor(modRgbValues.Item1*255); - var g = (int) Math.Floor(modRgbValues.Item2*255); - var b = (int) Math.Floor(modRgbValues.Item3*255); + var r = (int) Math.Floor(modRgbValues.Item1 * 255); + var g = (int) Math.Floor(modRgbValues.Item2 * 255); + var b = (int) Math.Floor(modRgbValues.Item3 * 255); - return Color.FromArgb(r, g, b); - } - } + return Color.FromArgb(r, g, b); + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Commands/DisableInactivityModeCommand.cs b/src/Sleddog.Blink1/Commands/DisableInactivityModeCommand.cs index 5c2abd8..f5b1e91 100644 --- a/src/Sleddog.Blink1/Commands/DisableInactivityModeCommand.cs +++ b/src/Sleddog.Blink1/Commands/DisableInactivityModeCommand.cs @@ -1,18 +1,17 @@ using System; using Sleddog.Blink1.Internal; -using Sleddog.Blink1.Internal.Interfaces; namespace Sleddog.Blink1.Commands { - internal class DisableInactivityModeCommand : IBlink1Command - { - public byte[] ToHidCommand() - { - return new[] - { - (byte) Blink1Commands.InactivityMode, - Convert.ToByte(false) - }; - } - } + internal class DisableInactivityModeCommand : Blink1Command + { + protected override byte[] HidCommandData() + { + return new[] + { + (byte) Blink1Commands.InactivityMode, + Convert.ToByte(false) + }; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Commands/EnableInactivityModeCommand.cs b/src/Sleddog.Blink1/Commands/EnableInactivityModeCommand.cs index 6d5a597..42709a2 100644 --- a/src/Sleddog.Blink1/Commands/EnableInactivityModeCommand.cs +++ b/src/Sleddog.Blink1/Commands/EnableInactivityModeCommand.cs @@ -1,42 +1,41 @@ using System; using Sleddog.Blink1.Internal; -using Sleddog.Blink1.Internal.Interfaces; namespace Sleddog.Blink1.Commands { - internal class EnableInactivityModeCommand : IBlink1Command - { - private readonly Blink1Duration waitDuration; - private readonly bool maintainState; - private readonly ushort startPosition; - private readonly ushort endPosition; + internal class EnableInactivityModeCommand : Blink1Command + { + private readonly ushort endPosition; + private readonly bool maintainState; + private readonly ushort startPosition; + private readonly Blink1Duration waitDuration; - public EnableInactivityModeCommand(Blink1Duration waitDuration) - { - this.waitDuration = waitDuration; - } + public EnableInactivityModeCommand(Blink1Duration waitDuration) + { + this.waitDuration = waitDuration; + } - public EnableInactivityModeCommand(Blink1Duration waitDuration, bool maintainState, ushort startPosition, - ushort endPosition) - { - this.waitDuration = waitDuration; - this.maintainState = maintainState; - this.startPosition = startPosition; - this.endPosition = endPosition; - } + public EnableInactivityModeCommand(Blink1Duration waitDuration, bool maintainState, ushort startPosition, + ushort endPosition) + { + this.waitDuration = waitDuration; + this.maintainState = maintainState; + this.startPosition = startPosition; + this.endPosition = endPosition; + } - public byte[] ToHidCommand() - { - return new[] - { - (byte) Blink1Commands.InactivityMode, - Convert.ToByte(true), - waitDuration.High, - waitDuration.Low, - Convert.ToByte(maintainState), - Convert.ToByte(startPosition), - Convert.ToByte(endPosition) - }; - } - } + protected override byte[] HidCommandData() + { + return new[] + { + (byte) Blink1Commands.InactivityMode, + Convert.ToByte(true), + waitDuration.High, + waitDuration.Low, + Convert.ToByte(maintainState), + Convert.ToByte(startPosition), + Convert.ToByte(endPosition) + }; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Commands/FadeToColorCommand.cs b/src/Sleddog.Blink1/Commands/FadeToColorCommand.cs index 437b1d8..1d5537c 100644 --- a/src/Sleddog.Blink1/Commands/FadeToColorCommand.cs +++ b/src/Sleddog.Blink1/Commands/FadeToColorCommand.cs @@ -1,39 +1,37 @@ using System; using System.Drawing; using Sleddog.Blink1.Internal; -using Sleddog.Blink1.Internal.Interfaces; namespace Sleddog.Blink1.Commands { - internal class FadeToColorCommand : IBlink1Command - { - private readonly Color color; - private readonly Blink1Duration duration; - private readonly LEDPosition ledPosition; + internal class FadeToColorCommand : Blink1Command + { + private readonly Color color; + private readonly Blink1Duration duration; + private readonly LEDPosition ledPosition; - public FadeToColorCommand(Color color, Blink1Duration duration) : this(color, duration, LEDPosition.Both) - { - } + public FadeToColorCommand(Color color, Blink1Duration duration) : this(color, duration, LEDPosition.Both) + { } - public FadeToColorCommand(Color color, Blink1Duration duration, LEDPosition ledPosition) - { - this.color = color; - this.duration = duration; - this.ledPosition = ledPosition; - } + public FadeToColorCommand(Color color, Blink1Duration duration, LEDPosition ledPosition) + { + this.color = color; + this.duration = duration; + this.ledPosition = ledPosition; + } - public byte[] ToHidCommand() - { - return new[] - { - (byte) Blink1Commands.FadeToColor, - color.R, - color.G, - color.B, - duration.High, - duration.Low, - Convert.ToByte(ledPosition) - }; - } - } + protected override byte[] HidCommandData() + { + return new[] + { + (byte) Blink1Commands.FadeToColor, + color.R, + color.G, + color.B, + duration.High, + duration.Low, + Convert.ToByte(ledPosition) + }; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Commands/PlayPresetCommand.cs b/src/Sleddog.Blink1/Commands/PlayPresetCommand.cs index b8b3276..f046f05 100644 --- a/src/Sleddog.Blink1/Commands/PlayPresetCommand.cs +++ b/src/Sleddog.Blink1/Commands/PlayPresetCommand.cs @@ -1,36 +1,34 @@ using System; using Sleddog.Blink1.Internal; -using Sleddog.Blink1.Internal.Interfaces; namespace Sleddog.Blink1.Commands { - internal class PlayPresetCommand : IBlink1Command - { - private readonly byte startPosition; - private readonly byte endPosition; - private readonly byte count; + internal class PlayPresetCommand : Blink1Command + { + private readonly byte count; + private readonly byte endPosition; + private readonly byte startPosition; - public PlayPresetCommand(ushort startPosition) : this(startPosition, 0, 0) - { - } + public PlayPresetCommand(ushort startPosition) : this(startPosition, 0, 0) + { } - public PlayPresetCommand(ushort startPosition, ushort endPosition, ushort count) - { - this.startPosition = Convert.ToByte(startPosition); - this.endPosition = Convert.ToByte(endPosition); - this.count = Convert.ToByte(count); - } + public PlayPresetCommand(ushort startPosition, ushort endPosition, ushort count) + { + this.startPosition = Convert.ToByte(startPosition); + this.endPosition = Convert.ToByte(endPosition); + this.count = Convert.ToByte(count); + } - public byte[] ToHidCommand() - { - return new[] - { - (byte) Blink1Commands.PresetControl, - Convert.ToByte(true), - startPosition, - endPosition, - count - }; - } - } + protected override byte[] HidCommandData() + { + return new[] + { + (byte) Blink1Commands.PresetControl, + Convert.ToByte(true), + startPosition, + endPosition, + count + }; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Commands/ReadPlaybackStateQuery.cs b/src/Sleddog.Blink1/Commands/ReadPlaybackStateQuery.cs index aad0f81..ed7c943 100644 --- a/src/Sleddog.Blink1/Commands/ReadPlaybackStateQuery.cs +++ b/src/Sleddog.Blink1/Commands/ReadPlaybackStateQuery.cs @@ -4,27 +4,27 @@ namespace Sleddog.Blink1.Commands { - public class ReadPlaybackStateQuery : IBlink1Query - { - public PlaybackStatus ToResponseType(byte[] responseData) - { - var isPlaying = Convert.ToBoolean(responseData[2]); + internal class ReadPlaybackStateQuery : Blink1Command, IBlink1Query + { + public PlaybackStatus ToResponseType(byte[] responseData) + { + var isPlaying = Convert.ToBoolean(responseData[2]); - var start = Convert.ToUInt16(responseData[3]); - var end = Convert.ToUInt16(responseData[4]); + var start = Convert.ToUInt16(responseData[3]); + var end = Convert.ToUInt16(responseData[4]); - var count = Convert.ToUInt16(responseData[5]); - var position = Convert.ToUInt16(responseData[6]); + var count = Convert.ToUInt16(responseData[5]); + var position = Convert.ToUInt16(responseData[6]); - return new PlaybackStatus(isPlaying, start, end, count, position); - } + return new PlaybackStatus(isPlaying, start, end, count, position); + } - public byte[] ToHidCommand() - { - return new[] - { - (byte) Blink1Commands.ReadPlaybackState - }; - } - } + protected override byte[] HidCommandData() + { + return new[] + { + (byte) Blink1Commands.ReadPlaybackState + }; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Commands/ReadPresetQuery.cs b/src/Sleddog.Blink1/Commands/ReadPresetQuery.cs index 9ac730e..4a54afd 100644 --- a/src/Sleddog.Blink1/Commands/ReadPresetQuery.cs +++ b/src/Sleddog.Blink1/Commands/ReadPresetQuery.cs @@ -5,35 +5,35 @@ namespace Sleddog.Blink1.Commands { - internal class ReadPresetQuery : IBlink1Query - { - private readonly byte position; + internal class ReadPresetQuery : Blink1Command, IBlink1Query + { + private readonly byte position; - public ReadPresetQuery(ushort position) - { - this.position = Convert.ToByte(position); - } + public ReadPresetQuery(ushort position) + { + this.position = Convert.ToByte(position); + } - public Blink1Preset ToResponseType(byte[] responseData) - { - var color = Color.FromArgb(responseData[2], responseData[3], responseData[4]); - var duration = new Blink1Duration(responseData[5], responseData[6]); + public Blink1Preset ToResponseType(byte[] responseData) + { + var color = Color.FromArgb(responseData[2], responseData[3], responseData[4]); + var duration = new Blink1Duration(responseData[5], responseData[6]); - return new Blink1Preset(color, duration); - } + return new Blink1Preset(color, duration); + } - public byte[] ToHidCommand() - { - return new[] - { - (byte) Blink1Commands.ReadPreset, - Convert.ToByte(0), - Convert.ToByte(0), - Convert.ToByte(0), - Convert.ToByte(0), - Convert.ToByte(0), - position - }; - } - } + protected override byte[] HidCommandData() + { + return new[] + { + (byte) Blink1Commands.ReadPreset, + Convert.ToByte(0), + Convert.ToByte(0), + Convert.ToByte(0), + Convert.ToByte(0), + Convert.ToByte(0), + position + }; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Commands/SavePresetsCommand.cs b/src/Sleddog.Blink1/Commands/SavePresetsCommand.cs index fae36e1..eb2820b 100644 --- a/src/Sleddog.Blink1/Commands/SavePresetsCommand.cs +++ b/src/Sleddog.Blink1/Commands/SavePresetsCommand.cs @@ -1,23 +1,20 @@ using System; using Sleddog.Blink1.Internal; -using Sleddog.Blink1.Internal.Interfaces; namespace Sleddog.Blink1.Commands { - internal class SavePresetsCommand : IBlink1Command - { - public byte[] ToHidCommand() - { - return new[] - { - (byte) Blink1Commands.SavePresetMk2, - Convert.ToByte(0xBE), - Convert.ToByte(0xEF), - Convert.ToByte(0xCA), - Convert.ToByte(0xFE), - Convert.ToByte(0x00), - Convert.ToByte(0x00) - }; - } - } + internal class SavePresetsCommand : Blink1Command + { + protected override byte[] HidCommandData() + { + return new[] + { + (byte) Blink1Commands.SavePresetMk2, + Convert.ToByte(0xBE), + Convert.ToByte(0xEF), + Convert.ToByte(0xCA), + Convert.ToByte(0xFE) + }; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Commands/SetColorCommand.cs b/src/Sleddog.Blink1/Commands/SetColorCommand.cs index 99d559d..062b0a8 100644 --- a/src/Sleddog.Blink1/Commands/SetColorCommand.cs +++ b/src/Sleddog.Blink1/Commands/SetColorCommand.cs @@ -1,27 +1,26 @@ using System.Drawing; using Sleddog.Blink1.Internal; -using Sleddog.Blink1.Internal.Interfaces; namespace Sleddog.Blink1.Commands { - internal class SetColorCommand : IBlink1Command - { - private readonly Color color; + internal class SetColorCommand : Blink1Command + { + private readonly Color color; - public SetColorCommand(Color color) - { - this.color = color; - } + public SetColorCommand(Color color) + { + this.color = color; + } - public byte[] ToHidCommand() - { - return new[] - { - (byte) Blink1Commands.SetColor, - color.R, - color.G, - color.B - }; - } - } + protected override byte[] HidCommandData() + { + return new[] + { + (byte) Blink1Commands.SetColor, + color.R, + color.G, + color.B + }; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Commands/SetPresetCommand.cs b/src/Sleddog.Blink1/Commands/SetPresetCommand.cs index eff9561..83d2296 100644 --- a/src/Sleddog.Blink1/Commands/SetPresetCommand.cs +++ b/src/Sleddog.Blink1/Commands/SetPresetCommand.cs @@ -1,35 +1,34 @@ using System; using Sleddog.Blink1.Internal; -using Sleddog.Blink1.Internal.Interfaces; namespace Sleddog.Blink1.Commands { - internal class SetPresetCommand : IBlink1Command - { - private readonly Blink1Preset preset; - private readonly byte position; + internal class SetPresetCommand : Blink1Command + { + private readonly byte position; + private readonly Blink1Preset preset; - public SetPresetCommand(Blink1Preset preset, ushort position) - { - this.preset = preset; - this.position = Convert.ToByte(position); - } + public SetPresetCommand(Blink1Preset preset, ushort position) + { + this.preset = preset; + this.position = Convert.ToByte(position); + } - public byte[] ToHidCommand() - { - var presetDuration = preset.PresetDuration; - var presetColor = preset.Color; + protected override byte[] HidCommandData() + { + var presetDuration = preset.PresetDuration; + var presetColor = preset.Color; - return new[] - { - (byte) Blink1Commands.SavePreset, - presetColor.R, - presetColor.G, - presetColor.B, - presetDuration.High, - presetDuration.Low, - position - }; - } - } + return new[] + { + (byte) Blink1Commands.SavePreset, + presetColor.R, + presetColor.G, + presetColor.B, + presetDuration.High, + presetDuration.Low, + position + }; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Commands/StopPresetCommand.cs b/src/Sleddog.Blink1/Commands/StopPresetCommand.cs index fdc029c..25778fc 100644 --- a/src/Sleddog.Blink1/Commands/StopPresetCommand.cs +++ b/src/Sleddog.Blink1/Commands/StopPresetCommand.cs @@ -1,18 +1,17 @@ using System; using Sleddog.Blink1.Internal; -using Sleddog.Blink1.Internal.Interfaces; namespace Sleddog.Blink1.Commands { - internal class StopPresetCommand : IBlink1Command - { - public byte[] ToHidCommand() - { - return new[] - { - (byte) Blink1Commands.PresetControl, - Convert.ToByte(false) - }; - } - } + internal class StopPresetCommand : Blink1Command + { + protected override byte[] HidCommandData() + { + return new[] + { + (byte) Blink1Commands.PresetControl, + Convert.ToByte(false) + }; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Commands/VersionQuery.cs b/src/Sleddog.Blink1/Commands/VersionQuery.cs index abd9635..c8d6537 100644 --- a/src/Sleddog.Blink1/Commands/VersionQuery.cs +++ b/src/Sleddog.Blink1/Commands/VersionQuery.cs @@ -4,22 +4,22 @@ namespace Sleddog.Blink1.Commands { - internal class VersionQuery : IBlink1Query - { - public Version ToResponseType(byte[] responseData) - { - var major = responseData[3] - '0'; - var minor = responseData[4] - '0'; + internal class VersionQuery : Blink1Command, IBlink1Query + { + public Version ToResponseType(byte[] responseData) + { + var major = responseData[3] - '0'; + var minor = responseData[4] - '0'; - return new Version(major, minor); - } + return new Version(major, minor); + } - public byte[] ToHidCommand() - { - return new[] - { - (byte) Blink1Commands.GetVersion - }; - } - } + protected override byte[] HidCommandData() + { + return new[] + { + (byte) Blink1Commands.GetVersion + }; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/IBlink1.cs b/src/Sleddog.Blink1/IBlink1.cs index b886b89..f910704 100644 --- a/src/Sleddog.Blink1/IBlink1.cs +++ b/src/Sleddog.Blink1/IBlink1.cs @@ -3,22 +3,22 @@ namespace Sleddog.Blink1 { - public interface IBlink1 - { - Version Version { get; } - string SerialNumber { get; } - bool EnableGamma { get; set; } - bool Blink(Color color, TimeSpan interval, ushort times); - bool Set(Color color); - bool Fade(Color color, TimeSpan fadeDuration); - bool Show(Color color, TimeSpan visibleTime); - bool Save(Blink1Preset preset, ushort position); - Blink1Preset ReadPreset(ushort position); - bool Play(ushort startPosition); - bool Pause(); - bool EnableInactivityMode(TimeSpan waitDuration); - bool DisableInactivityMode(); - void TurnOff(); - void Dispose(); - } + public interface IBlink1 + { + Version Version { get; } + string SerialNumber { get; } + bool EnableGamma { get; set; } + bool Blink(Color color, TimeSpan interval, ushort times); + bool Set(Color color); + bool Fade(Color color, TimeSpan fadeDuration); + bool Show(Color color, TimeSpan visibleTime); + bool Save(Blink1Preset preset, ushort position); + Blink1Preset ReadPreset(ushort position); + bool Play(ushort startPosition); + bool Pause(); + bool EnableInactivityMode(TimeSpan waitDuration); + bool DisableInactivityMode(); + void TurnOff(); + void Dispose(); + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/IBlink1Mk2.cs b/src/Sleddog.Blink1/IBlink1Mk2.cs index b446e57..6c5a7f5 100644 --- a/src/Sleddog.Blink1/IBlink1Mk2.cs +++ b/src/Sleddog.Blink1/IBlink1Mk2.cs @@ -3,12 +3,12 @@ namespace Sleddog.Blink1 { - public interface IBlink1Mk2 : IBlink1 - { - bool Fade(Color color, TimeSpan fadeDuration, LEDPosition ledPosition); - bool Play(ushort startPosition, ushort endPosition, ushort count); - PlaybackStatus ReadPlaybackStatus(); - bool EnabledInactivityMode(TimeSpan waitDuration, bool maintainState, ushort startPosition, ushort endPosition); - bool SavePresets(); - } + public interface IBlink1Mk2 : IBlink1 + { + bool Fade(Color color, TimeSpan fadeDuration, LEDPosition ledPosition); + bool Play(ushort startPosition, ushort endPosition, ushort count); + PlaybackStatus ReadPlaybackStatus(); + bool EnabledInactivityMode(TimeSpan waitDuration, bool maintainState, ushort startPosition, ushort endPosition); + bool SavePresets(); + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/IBlink1Mk3.cs b/src/Sleddog.Blink1/IBlink1Mk3.cs new file mode 100644 index 0000000..1affd88 --- /dev/null +++ b/src/Sleddog.Blink1/IBlink1Mk3.cs @@ -0,0 +1,5 @@ +namespace Sleddog.Blink1 +{ + public interface IBlink1Mk3 : IBlink1Mk2 + { } +} \ No newline at end of file diff --git a/src/Sleddog.Blink1/Internal/Blink1Command.cs b/src/Sleddog.Blink1/Internal/Blink1Command.cs new file mode 100644 index 0000000..b4b0229 --- /dev/null +++ b/src/Sleddog.Blink1/Internal/Blink1Command.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using Sleddog.Blink1.Internal.Interfaces; + +namespace Sleddog.Blink1.Internal +{ + internal abstract class Blink1Command : IBlink1Command + { + private readonly ReportId reportId; + + private static readonly Dictionary dataLengthMap = new Dictionary + { + {ReportId.One, 8}, + {ReportId.Two, 64} + }; + + protected Blink1Command() : this(ReportId.One) + { } + + protected Blink1Command(ReportId reportId) + { + this.reportId = reportId; + } + + public byte[] ToHidCommand() + { + var reportDataLength = dataLengthMap[reportId]; + + var dataBuffer = new byte[reportDataLength]; + + dataBuffer[0] = (byte) reportId; + + var commandData = HidCommandData(); + + var commandDataLength = Math.Min(reportDataLength - 1, commandData.Length); + + Array.Copy(commandData, 0, dataBuffer, 1, commandDataLength); + + return dataBuffer; + } + + protected abstract byte[] HidCommandData(); + } +} \ No newline at end of file diff --git a/src/Sleddog.Blink1/Internal/Blink1CommandBus.cs b/src/Sleddog.Blink1/Internal/Blink1CommandBus.cs index 70a620a..3842312 100644 --- a/src/Sleddog.Blink1/Internal/Blink1CommandBus.cs +++ b/src/Sleddog.Blink1/Internal/Blink1CommandBus.cs @@ -6,138 +6,125 @@ namespace Sleddog.Blink1.Internal { - internal class Blink1CommandBus : IDisposable - { - private readonly HidDevice hidDevice; - - public bool IsConnected => hidDevice.IsOpen; + internal class Blink1CommandBus : IDisposable + { + private readonly HidDevice hidDevice; + + public bool IsConnected => hidDevice.IsOpen; - public Blink1CommandBus(HidDevice hidDevice) - { - this.hidDevice = hidDevice; - } + public Blink1CommandBus(HidDevice hidDevice) + { + this.hidDevice = hidDevice; + } - internal string ReadSerial() - { - byte[] output; - - hidDevice.ReadSerialNumber(out output); + public void Dispose() + { + if (hidDevice != null && hidDevice.IsOpen) + { + hidDevice.CloseDevice(); + } + } - var chars = (from o in output where o != 0 select (char) o).ToArray(); + internal string ReadSerial() + { + byte[] output; + + hidDevice.ReadSerialNumber(out output); + + var chars = (from o in output where o != 0 select (char) o).ToArray(); + + return $"0x{string.Join(string.Empty, chars)}"; + } + + //internal bool SendCommand(IBlink1MultiCommand multiCommand) + //{ + // if (!IsConnected) + // { + // Connect(); + // } + + // var commandResults = (from hc in multiCommand.ToHidCommands() + // select WriteData(hc)) + // .ToList(); + + // return commandResults.Any(cr => cr == false); + //} + + //internal T SendQuery(IBlink1MultiQuery query) where T : class + //{ + // if (!IsConnected) + // { + // Connect(); + // } + + // var responseSegments = new List(); + + // var hidCommands = query.ToHidCommands().ToList(); + + // foreach (var hidCommand in hidCommands) + // { + // var commandSend = WriteData(hidCommand); + + // if (commandSend) + // { + // byte[] responseData; + + // var readData = hidDevice.ReadFeatureData(out responseData, Convert.ToByte(1)); + + // if (readData) + // { + // responseSegments.Add(responseData); + // } + // } + // } + + // if (responseSegments.Count == hidCommands.Count) + // { + // return query.ToResponseType(responseSegments); + // } + + // return default; + //} + + internal bool SendCommand(IBlink1Command command) + { + if (!IsConnected) + { + Connect(); + } + + var commandSend = hidDevice.WriteFeatureData(command.ToHidCommand()); + + return commandSend; + } + + internal T SendQuery(IBlink1Query query) where T : class + { + if (!IsConnected) + { + Connect(); + } + + var commandSend = hidDevice.WriteFeatureData(query.ToHidCommand()); + + if (commandSend) + { + byte[] responseData; + + var readData = hidDevice.ReadFeatureData(out responseData, Convert.ToByte(1)); + + if (readData) + { + return query.ToResponseType(responseData); + } + } + + return default; + } - return $"0x{string.Join(string.Empty, chars)}"; - } - - internal bool SendCommand(IBlink1MultiCommand multiCommand) - { - if (!IsConnected) - { - Connect(); - } - - var commandResults = (from hc in multiCommand.ToHidCommands() - select WriteData(hc)) - .ToList(); - - return commandResults.Any(cr => cr == false); - } - - internal T SendQuery(IBlink1MultiQuery query) where T : class - { - if (!IsConnected) - { - Connect(); - } - - var responseSegments = new List(); - - var hidCommands = query.ToHidCommands().ToList(); - - foreach (var hidCommand in hidCommands) - { - var commandSend = WriteData(hidCommand); - - if (commandSend) - { - byte[] responseData; - - var readData = hidDevice.ReadFeatureData(out responseData, Convert.ToByte(1)); - - if (readData) - { - responseSegments.Add(responseData); - } - } - } - - if (responseSegments.Count == hidCommands.Count) - { - return query.ToResponseType(responseSegments); - } - - return default; - } - - internal bool SendCommand(IBlink1Command command) - { - if (!IsConnected) - { - Connect(); - } - - var commandSend = WriteData(command.ToHidCommand()); - - return commandSend; - } - - internal T SendQuery(IBlink1Query query) where T : class - { - if (!IsConnected) - { - Connect(); - } - - var commandSend = WriteData(query.ToHidCommand()); - - if (commandSend) - { - byte[] responseData; - - var readData = hidDevice.ReadFeatureData(out responseData, Convert.ToByte(1)); - - if (readData) - { - return query.ToResponseType(responseData); - } - } - - return default; - } - - private bool WriteData(byte[] data) - { - var writeData = new byte[8]; - - writeData[0] = Convert.ToByte(1); - - var length = Math.Min(data.Length, writeData.Length - 1); - - Array.Copy(data, 0, writeData, 1, length); - - return hidDevice.WriteFeatureData(writeData); - } - - public void Connect() - { - hidDevice.OpenDevice(); - } - - public void Dispose() - { - if (hidDevice != null && hidDevice.IsOpen) - { - hidDevice.CloseDevice(); - } - } - } + public void Connect() + { + hidDevice.OpenDevice(); + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Internal/Blink1Commands.cs b/src/Sleddog.Blink1/Internal/Blink1Commands.cs index 8922895..0e46e6f 100644 --- a/src/Sleddog.Blink1/Internal/Blink1Commands.cs +++ b/src/Sleddog.Blink1/Internal/Blink1Commands.cs @@ -1,16 +1,30 @@ -namespace Sleddog.Blink1.Internal -{ - internal enum Blink1Commands : byte - { - Test = (byte) '!', - GetVersion = (byte) 'v', - SetColor = (byte) 'n', - FadeToColor = (byte) 'c', - InactivityMode = (byte) 'D', - PresetControl = (byte) 'p', - ReadPreset = (byte) 'R', - SavePreset = (byte) 'P', - SavePresetMk2 = (byte) 'W', - ReadPlaybackState = (byte) 'S', - } +namespace Sleddog.Blink1.Internal +{ + /* + * mk3 commands: https://github.com/todbot/blink1mk3/blob/master/firmware/firmware-v30x/main.c#L968 + */ + internal enum Blink1Commands : byte + { + Test = (byte) '!', + GetVersion = (byte) 'v', + SetColor = (byte) 'n', + FadeToColor = (byte) 'c', + InactivityMode = (byte) 'D', + PresetControl = (byte) 'p', + ReadPreset = (byte) 'R', + SavePreset = (byte) 'P', + SavePresetMk2 = (byte) 'W', + ReadPlaybackState = (byte) 'S', + ReadCurrentColor = (byte) 'r', + SetLed = (byte) 'l', + ReadEepromLocation = (byte) 'e', + WriteEepromLocation = (byte) 'E', + Write50ByteNote = (byte) 'F', + Read50ByteNote = (byte) 'f', + GoToBootloader = (byte) 'G', + LockGoToBootloader = (byte) 'L', + SetStartupParams = (byte) 'B', + GetStartupParams = (byte) 'b', + GetChipUniqueId = (byte) 'U' + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Internal/Blink1Duration.cs b/src/Sleddog.Blink1/Internal/Blink1Duration.cs index e799f37..95e1f9d 100644 --- a/src/Sleddog.Blink1/Internal/Blink1Duration.cs +++ b/src/Sleddog.Blink1/Internal/Blink1Duration.cs @@ -2,81 +2,81 @@ namespace Sleddog.Blink1.Internal { - internal class Blink1Duration - { - public byte High { get; } - public byte Low { get; } - - public Blink1Duration(TimeSpan duration) - { - var blinkTime = Convert.ToUInt32(duration.TotalMilliseconds/10); - - High = Convert.ToByte(blinkTime >> 8); - Low = Convert.ToByte(blinkTime & 0xFF); - } - - internal Blink1Duration(byte high, byte low) - { - High = high; - Low = low; - } - - protected bool Equals(Blink1Duration other) - { - return High == other.High && Low == other.Low; - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - - if (ReferenceEquals(this, obj)) - { - return true; - } - - if (obj.GetType() != GetType()) - { - return false; - } - - return Equals((Blink1Duration) obj); - } - - public override int GetHashCode() - { - unchecked - { - return (High.GetHashCode()*397) ^ Low.GetHashCode(); - } - } - - public static bool operator ==(Blink1Duration left, Blink1Duration right) - { - return Equals(left, right); - } - - public static bool operator !=(Blink1Duration left, Blink1Duration right) - { - return !Equals(left, right); - } - - public static implicit operator TimeSpan(Blink1Duration duration) - { - var low = duration.Low; - var high = duration.High; - - var blinkTime = Convert.ToUInt32((high << 8) | low); - - return TimeSpan.FromMilliseconds(blinkTime*10); - } - - public static implicit operator Blink1Duration(TimeSpan duration) - { - return new Blink1Duration(duration); - } - } + internal class Blink1Duration + { + public byte High { get; } + public byte Low { get; } + + public Blink1Duration(TimeSpan duration) + { + var blinkTime = Convert.ToUInt32(duration.TotalMilliseconds / 10); + + High = Convert.ToByte(blinkTime >> 8); + Low = Convert.ToByte(blinkTime & 0xFF); + } + + internal Blink1Duration(byte high, byte low) + { + High = high; + Low = low; + } + + protected bool Equals(Blink1Duration other) + { + return High == other.High && Low == other.Low; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((Blink1Duration) obj); + } + + public override int GetHashCode() + { + unchecked + { + return (High.GetHashCode() * 397) ^ Low.GetHashCode(); + } + } + + public static bool operator ==(Blink1Duration left, Blink1Duration right) + { + return Equals(left, right); + } + + public static bool operator !=(Blink1Duration left, Blink1Duration right) + { + return !Equals(left, right); + } + + public static implicit operator TimeSpan(Blink1Duration duration) + { + var low = duration.Low; + var high = duration.High; + + var blinkTime = Convert.ToUInt32((high << 8) | low); + + return TimeSpan.FromMilliseconds(blinkTime * 10); + } + + public static implicit operator Blink1Duration(TimeSpan duration) + { + return new Blink1Duration(duration); + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Internal/Interfaces/IBlink1Command.cs b/src/Sleddog.Blink1/Internal/Interfaces/IBlink1Command.cs index d901ed1..8f61816 100644 --- a/src/Sleddog.Blink1/Internal/Interfaces/IBlink1Command.cs +++ b/src/Sleddog.Blink1/Internal/Interfaces/IBlink1Command.cs @@ -1,7 +1,7 @@ namespace Sleddog.Blink1.Internal.Interfaces { - internal interface IBlink1Command - { - byte[] ToHidCommand(); - } + internal interface IBlink1Command + { + byte[] ToHidCommand(); + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Internal/Interfaces/IBlink1MultiCommand.cs b/src/Sleddog.Blink1/Internal/Interfaces/IBlink1MultiCommand.cs index a821690..df867b9 100644 --- a/src/Sleddog.Blink1/Internal/Interfaces/IBlink1MultiCommand.cs +++ b/src/Sleddog.Blink1/Internal/Interfaces/IBlink1MultiCommand.cs @@ -2,8 +2,8 @@ namespace Sleddog.Blink1.Internal.Interfaces { - internal interface IBlink1MultiCommand - { - IEnumerable ToHidCommands(); - } + //internal interface IBlink1MultiCommand + //{ + // IEnumerable ToHidCommands(); + //} } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Internal/Interfaces/IBlink1MultiQuery.cs b/src/Sleddog.Blink1/Internal/Interfaces/IBlink1MultiQuery.cs index f4083b3..72620ba 100644 --- a/src/Sleddog.Blink1/Internal/Interfaces/IBlink1MultiQuery.cs +++ b/src/Sleddog.Blink1/Internal/Interfaces/IBlink1MultiQuery.cs @@ -2,12 +2,11 @@ namespace Sleddog.Blink1.Internal.Interfaces { - internal interface IBlink1MultiQuery : IBlink1MultiCommand - { - } + //internal interface IBlink1MultiQuery : IBlink1MultiCommand + //{ } - internal interface IBlink1MultiQuery : IBlink1MultiQuery where T : class - { - T ToResponseType(IEnumerable responseData); - } + //internal interface IBlink1MultiQuery : IBlink1MultiQuery where T : class + //{ + // T ToResponseType(IEnumerable responseData); + //} } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Internal/Interfaces/IBlink1Query.cs b/src/Sleddog.Blink1/Internal/Interfaces/IBlink1Query.cs index 0e88245..65b5389 100644 --- a/src/Sleddog.Blink1/Internal/Interfaces/IBlink1Query.cs +++ b/src/Sleddog.Blink1/Internal/Interfaces/IBlink1Query.cs @@ -1,11 +1,10 @@ namespace Sleddog.Blink1.Internal.Interfaces { - internal interface IBlink1Query : IBlink1Command - { - } + internal interface IBlink1Query : IBlink1Command + { } - internal interface IBlink1Query : IBlink1Query where T : class - { - T ToResponseType(byte[] responseData); - } + internal interface IBlink1Query : IBlink1Query where T : class + { + T ToResponseType(byte[] responseData); + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Internal/ObservableExt.cs b/src/Sleddog.Blink1/Internal/ObservableExt.cs index 50f4bd4..a9bcce6 100644 --- a/src/Sleddog.Blink1/Internal/ObservableExt.cs +++ b/src/Sleddog.Blink1/Internal/ObservableExt.cs @@ -3,16 +3,16 @@ namespace Sleddog.Blink1.Internal { - internal static class ObservableExt - { - public static IObservable TimerMaxTick(int numberOfTicks, TimeSpan dueTime, TimeSpan interval) - { - return Observable.Generate( - 0L, - i => i <= numberOfTicks, - i => i + 1, - i => i, - i => i == 0 ? dueTime : interval); - } - } + internal static class ObservableExt + { + public static IObservable TimerMaxTick(int numberOfTicks, TimeSpan dueTime, TimeSpan interval) + { + return Observable.Generate( + 0L, + i => i <= numberOfTicks, + i => i + 1, + i => i, + i => i == 0 ? dueTime : interval); + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Internal/ReportId.cs b/src/Sleddog.Blink1/Internal/ReportId.cs new file mode 100644 index 0000000..9899a39 --- /dev/null +++ b/src/Sleddog.Blink1/Internal/ReportId.cs @@ -0,0 +1,8 @@ +namespace Sleddog.Blink1.Internal +{ + internal enum ReportId : byte + { + One = 1, + Two = 2 + } +} \ No newline at end of file diff --git a/src/Sleddog.Blink1/LEDPosition.cs b/src/Sleddog.Blink1/LEDPosition.cs index 22c1582..503a746 100644 --- a/src/Sleddog.Blink1/LEDPosition.cs +++ b/src/Sleddog.Blink1/LEDPosition.cs @@ -2,11 +2,11 @@ namespace Sleddog.Blink1 { - [Flags] - public enum LEDPosition - { - Both = 0, - Top = 1, - Bottom = 2 - } + [Flags] + public enum LEDPosition + { + Both = 0, + Top = 1, + Bottom = 2 + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/PlaybackStatus.cs b/src/Sleddog.Blink1/PlaybackStatus.cs index 02a15fe..a82248f 100644 --- a/src/Sleddog.Blink1/PlaybackStatus.cs +++ b/src/Sleddog.Blink1/PlaybackStatus.cs @@ -1,20 +1,20 @@ namespace Sleddog.Blink1 { - public class PlaybackStatus - { - public bool IsPlaying { get; } - public ushort StartPosition { get; } - public ushort EndPosition { get; } - public ushort Count { get; } - public ushort Position { get; } + public class PlaybackStatus + { + public bool IsPlaying { get; } + public ushort StartPosition { get; } + public ushort EndPosition { get; } + public ushort Count { get; } + public ushort Position { get; } - internal PlaybackStatus(bool isPlaying, ushort startPosition, ushort endPosition, ushort count, ushort position) - { - IsPlaying = isPlaying; - StartPosition = startPosition; - EndPosition = endPosition; - Count = count; - Position = position; - } - } + internal PlaybackStatus(bool isPlaying, ushort startPosition, ushort endPosition, ushort count, ushort position) + { + IsPlaying = isPlaying; + StartPosition = startPosition; + EndPosition = endPosition; + Count = count; + Position = position; + } + } } \ No newline at end of file diff --git a/src/Sleddog.Blink1/Sleddog.Blink1.csproj b/src/Sleddog.Blink1/Sleddog.Blink1.csproj index c22f0cc..c698c50 100644 --- a/src/Sleddog.Blink1/Sleddog.Blink1.csproj +++ b/src/Sleddog.Blink1/Sleddog.Blink1.csproj @@ -73,6 +73,7 @@ + @@ -90,6 +91,8 @@ + + @@ -98,6 +101,7 @@ + diff --git a/src/Sleddog.Blink1/app.config b/src/Sleddog.Blink1/app.config index e6bc3bf..c980e0a 100644 --- a/src/Sleddog.Blink1/app.config +++ b/src/Sleddog.Blink1/app.config @@ -1,28 +1,31 @@  + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Sleddog.Blink1/packages.config b/src/Sleddog.Blink1/packages.config index 514cf73..ef4f61a 100644 --- a/src/Sleddog.Blink1/packages.config +++ b/src/Sleddog.Blink1/packages.config @@ -1,9 +1,10 @@  + - - - - - - + + + + + + \ No newline at end of file