using System; using System.Linq; using Crestron.SimplSharp.CrestronIO; using PepperDash.Core.Intersystem.Serialization; using PepperDash.Core.Intersystem.Tokens; /* Digital (2 bytes) 10C##### 0####### (mask = 11000000_10000000b -> 0xC080) Analog (4 bytes) 11aa0### 0####### (mask = 11001000_10000000b -> 0xC880) 0aaaaaaa 0aaaaaaa Serial (Variable length) 11001### 0####### (mask = 11111000_10000000b -> 0xF880) dddddddd ........ <- up to 252 bytes of serial data (255 - 3) 11111111 <- denotes end of data */ namespace PepperDash.Core.Intersystem { /// /// Helper methods for creating XSig byte sequences compatible with the Intersystem Communications (ISC) symbol. /// /// /// Indexing is not from the start of each signal type but rather from the beginning of the first defined signal /// the Intersystem Communications (ISC) symbol. /// public static class XSigHelpers { /// /// Forces all outputs to 0. /// /// Bytes in XSig format for clear outputs trigger. public static byte[] ClearOutputs() { return new byte[] { 0xFC }; } /// /// Evaluate all inputs and re-transmit any digital, analog, and permanent serail signals not set to 0. /// /// Bytes in XSig format for send status trigger. public static byte[] SendStatus() { return new byte[] { 0xFD }; } /// /// Get bytes for an IXSigStateResolver object. /// /// XSig state resolver. /// Bytes in XSig format for each token within the state representation. public static byte[] GetBytes(IXSigSerialization xSigSerialization) { return GetBytes(xSigSerialization, 0); } /// /// Get bytes for an IXSigStateResolver object, with a specified offset. /// /// XSig state resolver. /// Offset to which the data will be aligned. /// Bytes in XSig format for each token within the state representation. public static byte[] GetBytes(IXSigSerialization xSigSerialization, int offset) { var tokens = xSigSerialization.Serialize(); if (tokens == null) return new byte[0]; using (var memoryStream = new MemoryStream()) { using (var tokenWriter = new XSigTokenStreamWriter(memoryStream)) tokenWriter.WriteXSigData(xSigSerialization, offset); return memoryStream.ToArray(); } } /// /// Get bytes for a single digital signal. /// /// 1-based digital index /// Digital data to be encoded /// Bytes in XSig format for digtial information. public static byte[] GetBytes(int index, bool value) { return GetBytes(index, 0, value); } /// /// Get bytes for a single digital signal. /// /// 1-based digital index /// Index offset. /// Digital data to be encoded /// Bytes in XSig format for digtial information. public static byte[] GetBytes(int index, int offset, bool value) { return new XSigDigitalToken(index + offset, value).GetBytes(); } /// /// Get byte sequence for multiple digital signals. /// /// Starting index of the sequence. /// Digital signal value array. /// Byte sequence in XSig format for digital signal information. public static byte[] GetBytes(int startIndex, bool[] values) { return GetBytes(startIndex, 0, values); } /// /// Get byte sequence for multiple digital signals. /// /// Starting index of the sequence. /// Index offset. /// Digital signal value array. /// Byte sequence in XSig format for digital signal information. public static byte[] GetBytes(int startIndex, int offset, bool[] values) { // Digital XSig data is 2 bytes per value const int fixedLength = 2; var bytes = new byte[values.Length * fixedLength]; for (var i = 0; i < values.Length; i++) Buffer.BlockCopy(GetBytes(startIndex++, offset, values[i]), 0, bytes, i * fixedLength, fixedLength); return bytes; } /// /// Get bytes for a single analog signal. /// /// 1-based analog index /// Analog data to be encoded /// Bytes in XSig format for analog signal information. public static byte[] GetBytes(int index, ushort value) { return GetBytes(index, 0, value); } /// /// Get bytes for a single analog signal. /// /// 1-based analog index /// Index offset. /// Analog data to be encoded /// Bytes in XSig format for analog signal information. public static byte[] GetBytes(int index, int offset, ushort value) { return new XSigAnalogToken(index + offset, value).GetBytes(); } /// /// Get byte sequence for multiple analog signals. /// /// Starting index of the sequence. /// Analog signal value array. /// Byte sequence in XSig format for analog signal information. public static byte[] GetBytes(int startIndex, ushort[] values) { return GetBytes(startIndex, 0, values); } /// /// Get byte sequence for multiple analog signals. /// /// Starting index of the sequence. /// Index offset. /// Analog signal value array. /// Byte sequence in XSig format for analog signal information. public static byte[] GetBytes(int startIndex, int offset, ushort[] values) { // Analog XSig data is 4 bytes per value const int fixedLength = 4; var bytes = new byte[values.Length * fixedLength]; for (var i = 0; i < values.Length; i++) Buffer.BlockCopy(GetBytes(startIndex++, offset, values[i]), 0, bytes, i * fixedLength, fixedLength); return bytes; } /// /// Get bytes for a single serial signal. /// /// 1-based serial index /// Serial data to be encoded /// Bytes in XSig format for serial signal information. public static byte[] GetBytes(int index, string value) { return GetBytes(index, 0, value); } /// /// Get bytes for a single serial signal. /// /// 1-based serial index /// Index offset. /// Serial data to be encoded /// Bytes in XSig format for serial signal information. public static byte[] GetBytes(int index, int offset, string value) { return new XSigSerialToken(index + offset, value).GetBytes(); } /// /// Get byte sequence for multiple serial signals. /// /// Starting index of the sequence. /// Serial signal value array. /// Byte sequence in XSig format for serial signal information. public static byte[] GetBytes(int startIndex, string[] values) { return GetBytes(startIndex, 0, values); } /// /// Get byte sequence for multiple serial signals. /// /// Starting index of the sequence. /// Index offset. /// Serial signal value array. /// Byte sequence in XSig format for serial signal information. public static byte[] GetBytes(int startIndex, int offset, string[] values) { // Serial XSig data is not fixed-length like the other formats var dstOffset = 0; var bytes = new byte[values.Sum(v => v.Length + 3)]; for (var i = 0; i < values.Length; i++) { var data = GetBytes(startIndex++, offset, values[i]); Buffer.BlockCopy(data, 0, bytes, dstOffset, data.Length); dstOffset += data.Length; } return bytes; } } }