diff --git a/Tcmp-SDK/Properties/AssemblyInfo.cs b/Tcmp-SDK/Properties/AssemblyInfo.cs
index 3b3bb33..05d72de 100644
--- a/Tcmp-SDK/Properties/AssemblyInfo.cs
+++ b/Tcmp-SDK/Properties/AssemblyInfo.cs
@@ -10,7 +10,7 @@
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("TapTrack")]
[assembly: AssemblyProduct("TapTrack.Tcmp")]
-[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("TapTrack")]
[assembly: AssemblyCulture("")]
@@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.8.0.0")]
-[assembly: AssemblyFileVersion("0.8.0.0")]
+[assembly: AssemblyVersion("0.9.0.0")]
+[assembly: AssemblyFileVersion("0.9.0.0")]
diff --git a/Tcmp-SDK/TapTrack.Tcmp.csproj b/Tcmp-SDK/TapTrack.Tcmp.csproj
index f8a1641..dc7fa76 100644
--- a/Tcmp-SDK/TapTrack.Tcmp.csproj
+++ b/Tcmp-SDK/TapTrack.Tcmp.csproj
@@ -86,6 +86,7 @@
+
diff --git a/Tcmp-SDK/Tcmp/CommandFamilies/System/IndicatorCommand.cs b/Tcmp-SDK/Tcmp/CommandFamilies/System/IndicatorCommand.cs
new file mode 100644
index 0000000..1287fbb
--- /dev/null
+++ b/Tcmp-SDK/Tcmp/CommandFamilies/System/IndicatorCommand.cs
@@ -0,0 +1,164 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using TapTrack.Tcmp.Communication;
+
+namespace TapTrack.Tcmp.CommandFamilies.System
+{
+ ///
+ /// Represents an indicator present on a .
+ ///
+ public enum IndicatorOption
+ {
+ ///
+ /// The red LED.
+ ///
+ RedLed,
+
+ ///
+ /// The green LED.
+ ///
+ GreenLed,
+
+ ///
+ /// The blue LED.
+ ///
+ BlueLed,
+
+ ///
+ /// The buzzer.
+ ///
+ Buzzer
+ }
+
+ ///
+ /// Represents a command to modify the state of an indicator.
+ /// See for available options.
+ ///
+ public abstract class IndicatorCommand : SystemCommand
+ {
+ ///
+ /// The command code for this IndicatorCommand.
+ ///
+ public abstract override byte CommandCode { get; }
+
+ ///
+ /// The target indicator.
+ ///
+ public abstract IndicatorOption Option { get; }
+ }
+
+ ///
+ /// Represents a command to activate (turn on) an indicator.
+ ///
+ public sealed class ActivateIndicator : IndicatorCommand
+ {
+ ///
+ public override byte CommandCode { get; }
+
+ ///
+ public override IndicatorOption Option { get; }
+
+ ///
+ /// The amount of time (in milliseconds) to keep the indicator activated.
+ ///
+ public UInt16 Duration { get; }
+
+ ///
+ /// Constructs an command that will activate the
+ /// specified for an optional amount of time.
+ ///
+ /// The to activate.
+ ///
+ /// The amount of time (in milliseconds) to keep the indicator
+ /// activated. A duration of `0` implies activation until a
+ /// command is sent.
+ ///
+ public ActivateIndicator(IndicatorOption option, UInt16 duration = 0)
+ {
+ Option = option;
+ Duration = (UInt16)duration;
+
+ switch (option)
+ {
+ case IndicatorOption.RedLed:
+ {
+ CommandCode = 0x0A;
+ break;
+ }
+ case IndicatorOption.GreenLed:
+ {
+ CommandCode = 0x0D;
+ break;
+ }
+ case IndicatorOption.BlueLed:
+ {
+ CommandCode = 0x10;
+ break;
+ }
+ case IndicatorOption.Buzzer:
+ {
+ CommandCode = 0x13;
+ break;
+ }
+ default:
+ throw new NotImplementedException($"case {option} is not implemented");
+ }
+
+ if (Duration == 0) return;
+
+ // Duration is > 0, so modify command code and add as parameter
+ // TODO: Hard-coding this is not the most flexible solution
+ CommandCode += 0x02;
+ IEnumerable durationBytes = BitConverter.GetBytes(Duration).Reverse();
+ parameters.AddRange(durationBytes);
+ }
+ }
+
+ ///
+ /// Represents a command to deactivate (turn off) an indicator.
+ ///
+ public sealed class DeactivateIndicator : IndicatorCommand
+ {
+ ///
+ public override byte CommandCode { get; }
+
+ ///
+ public override IndicatorOption Option { get; }
+
+ ///
+ /// Constructs a command that will deactivate
+ /// the specified .
+ ///
+ /// The to deactivate.
+ public DeactivateIndicator(IndicatorOption option)
+ {
+ Option = option;
+ switch (option)
+ {
+ case IndicatorOption.RedLed:
+ {
+ CommandCode = 0x0B;
+ break;
+ }
+ case IndicatorOption.GreenLed:
+ {
+ CommandCode = 0x0E;
+ break;
+ }
+ case IndicatorOption.BlueLed:
+ {
+ CommandCode = 0x11;
+ break;
+ }
+ case IndicatorOption.Buzzer:
+ {
+ CommandCode = 0x13;
+ break;
+ }
+ default:
+ throw new NotImplementedException($"case {option} is not implemented");
+ }
+ }
+ }
+}