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;
}
}
}