using System.Collections.Generic; using System.IO.Ports; using RGB.NET.Core; namespace RGB.NET.Devices.WS281X { /// /// /// Represents a update queue for serial devices. /// /// The type of data sent through the serial connection. public abstract class SerialPortUpdateQueue : UpdateQueue { #region Properties & Fields /// /// Gets or sets the prompt to wait for between sending commands. /// // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global protected string Prompt { get; set; } = ">"; /// /// Gets the serial port used by this queue. /// protected SerialPort SerialPort { get; } #endregion #region Constructors /// /// /// Initializes a new instance of the class. /// /// The update trigger used by this queue. /// The name of the serial-port to connect to. /// The baud-rate used by the serial-connection. internal SerialPortUpdateQueue(IDeviceUpdateTrigger updateTrigger, string portName, int baudRate = 115200) : base(updateTrigger) { SerialPort = new SerialPort(portName, baudRate); } #endregion #region Methods /// protected override void OnStartup(object sender, CustomUpdateData customData) { base.OnStartup(sender, customData); if (!SerialPort.IsOpen) SerialPort.Open(); SerialPort.DiscardInBuffer(); } /// protected override void Update(Dictionary dataSet) { foreach (TData command in GetCommands(dataSet)) { SerialPort.ReadTo(Prompt); SendCommand(command); } } /// /// Gets the commands that need to be sent to the device to update the requested colors. /// /// The set of data that needs to be updated. /// The commands to be sent. protected abstract IEnumerable GetCommands(Dictionary dataSet); /// /// Sends a command as a string followed by a line-break to the device. /// This most likely needs to be overwritten if the data-type isn't string. /// /// The command to be sent. protected virtual void SendCommand(TData command) => SerialPort.WriteLine((command as string) ?? string.Empty); #endregion } }