/// <summary> /// Creates a new <see cref="DataCell"/> from serialization parameters. /// </summary> /// <param name="info">The <see cref="SerializationInfo"/> with populated with data.</param> /// <param name="context">The source <see cref="StreamingContext"/> for this deserialization.</param> protected DataCell(SerializationInfo info, StreamingContext context) : base(info, context) { // Deserialize data cell m_status2Flags = info.GetByte("status2Flags"); m_clockStatusFlags = (ClockStatusFlags)info.GetValue("clockStatusFlags", typeof(ClockStatusFlags)); m_sampleNumber = info.GetUInt16("sampleNumber"); }
/// <summary> /// Parses the binary body image. /// </summary> /// <param name="buffer">Binary image to parse.</param> /// <param name="startIndex">Start index into <paramref name="buffer"/> to begin parsing.</param> /// <param name="length">Length of valid data within <paramref name="buffer"/>.</param> /// <returns>The length of the data that was parsed.</returns> protected override int ParseBodyImage(byte[] buffer, int startIndex, int length) { ConfigurationCell configCell = ConfigurationCell; ConfigurationFrame configFrame = configCell.Parent; ProtocolVersion protocolVersion = configFrame.CommonHeader.ProtocolVersion; IPhasorValue phasorValue; IDigitalValue digitalValue; int parsedLength, index = startIndex; if (protocolVersion == ProtocolVersion.M) { // Parse out optional STATUS2 flags if (configFrame.Status2Included) { m_status2Flags = buffer[index]; index++; } else { m_status2Flags = 0; } // We interpret status bytes together as one word (matches other protocols this way) base.StatusFlags = Word.MakeWord((byte)Status1Flags, m_status2Flags); } else { // Read sample number for G protocol m_sampleNumber = BigEndian.ToUInt16(buffer, index); index += 2; } // Parse out time tag if (configFrame.TimestampIncluded) { m_clockStatusFlags = (ClockStatusFlags)buffer[index]; index += 1; ushort day = BinaryCodedDecimal.Decode(BigEndian.ToUInt16(buffer, index)); byte hours = BinaryCodedDecimal.Decode(buffer[index + 2]); byte minutes = BinaryCodedDecimal.Decode(buffer[index + 3]); byte seconds = BinaryCodedDecimal.Decode(buffer[index + 4]); double timebase = 2880.0D; index += 5; // Read sample number for M protocol if (protocolVersion == ProtocolVersion.M) { m_sampleNumber = BigEndian.ToUInt16(buffer, index + 5); timebase = 719.0D; index += 2; } // TODO: Think about how to handle year change with floating clock... // Calculate timestamp Parent.Timestamp = new DateTime(DateTime.UtcNow.Year, 1, 1).AddDays(day - 1).AddHours(hours).AddMinutes(minutes).AddSeconds(seconds + m_sampleNumber / timebase); } else { Parent.Timestamp = DateTime.UtcNow.Ticks; SynchronizationIsValid = false; m_sampleNumber = BigEndian.ToUInt16(buffer, index); index += 2; } // Parse out first five phasor values (1 - 5) int phasorIndex = 0; // Phasor 1 (always present) phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor2Enabled) == OnlineDataFormatFlags.Phasor2Enabled) { // Phasor 2 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor3Enabled) == OnlineDataFormatFlags.Phasor3Enabled) { // Phasor 3 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor4Enabled) == OnlineDataFormatFlags.Phasor4Enabled) { // Phasor 4 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor5Enabled) == OnlineDataFormatFlags.Phasor5Enabled) { // Phasor 5 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } // For 1690M format the frequency, reference phasor, dF/dt and first digital follow phasors 1-5 if (protocolVersion == ProtocolVersion.M) { // Parse out frequency value FrequencyValue = Macrodyne.FrequencyValue.CreateNewValue(this, configCell.FrequencyDefinition, buffer, index, out parsedLength); index += parsedLength; // Parse reference phasor information if (configFrame.ReferenceIncluded) { m_referenceSampleNumber = BigEndian.ToUInt16(buffer, index); m_referencePhasor = PhasorValue.CreateNewValue(this, new PhasorDefinition(null, "Reference Phasor", PhasorType.Voltage, null), buffer, index, out parsedLength) as PhasorValue; index += 6; } // Parse first digital value if (configFrame.Digital1Included) { digitalValue = DigitalValue.CreateNewValue(this, configCell.DigitalDefinitions[0], buffer, index, out parsedLength); DigitalValues.Add(digitalValue); index += parsedLength; } } // Parse out next five phasor values (6 - 10) if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor6Enabled) == OnlineDataFormatFlags.Phasor6Enabled) { // Phasor 6 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor7Enabled) == OnlineDataFormatFlags.Phasor7Enabled) { // Phasor 7 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor8Enabled) == OnlineDataFormatFlags.Phasor8Enabled) { // Phasor 8 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor9Enabled) == OnlineDataFormatFlags.Phasor9Enabled) { // Phasor 9 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor10Enabled) == OnlineDataFormatFlags.Phasor10Enabled) { // Phasor 10 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } // For 1690G format the channel phasors, reference phasor, frequency, dF/dt and digitals follow phasors 1-10 if (protocolVersion == ProtocolVersion.G) { // Technically 30 more possible channel phasors can be defined for (int i = phasorIndex; i < ConfigurationCell.PhasorDefinitions.Count; i++) { phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } // Parse reference phasor information if (configFrame.ReferenceIncluded) { m_referencePhasor = PhasorValue.CreateNewValue(this, new PhasorDefinition(null, "Reference Phasor", PhasorType.Voltage, null), buffer, index, out parsedLength) as PhasorValue; index += parsedLength; } // Parse out frequency value FrequencyValue = Macrodyne.FrequencyValue.CreateNewValue(this, configCell.FrequencyDefinition, buffer, index, out parsedLength); index += parsedLength; // Parse first digital value if (configFrame.Digital1Included) { digitalValue = DigitalValue.CreateNewValue(this, configCell.DigitalDefinitions[0], buffer, index, out parsedLength); DigitalValues.Add(digitalValue); index += parsedLength; } } // Parse second digital value if (configFrame.Digital2Included) { digitalValue = DigitalValue.CreateNewValue(this, configCell.DigitalDefinitions[configCell.DigitalDefinitions.Count - 1], buffer, index, out parsedLength); DigitalValues.Add(digitalValue); index += parsedLength; } // Return total parsed length return(index - startIndex); }
/// <summary> /// Parses the binary body image. /// </summary> /// <param name="buffer">Binary image to parse.</param> /// <param name="startIndex">Start index into <paramref name="buffer"/> to begin parsing.</param> /// <param name="length">Length of valid data within <paramref name="buffer"/>.</param> /// <returns>The length of the data that was parsed.</returns> protected override int ParseBodyImage(byte[] buffer, int startIndex, int length) { ConfigurationCell configCell = ConfigurationCell; ConfigurationFrame configFrame = configCell.Parent; ProtocolVersion protocolVersion = configFrame.CommonHeader.ProtocolVersion; IPhasorValue phasorValue; IDigitalValue digitalValue; int parsedLength, index = startIndex; if (protocolVersion == ProtocolVersion.M) { // Parse out optional STATUS2 flags if (configFrame.Status2Included) { m_status2Flags = buffer[index]; index++; } else { m_status2Flags = 0; } // We interpret status bytes together as one word (matches other protocols this way) base.StatusFlags = Word.MakeWord((byte)Status1Flags, m_status2Flags); } else { // Read sample number for G protocol m_sampleNumber = BigEndian.ToUInt16(buffer, index); index += 2; } // Parse out time tag if (configFrame.TimestampIncluded) { m_clockStatusFlags = (ClockStatusFlags)buffer[index]; index += 1; ushort day = BinaryCodedDecimal.Decode(BigEndian.ToUInt16(buffer, index)); byte hours = BinaryCodedDecimal.Decode(buffer[index + 2]); byte minutes = BinaryCodedDecimal.Decode(buffer[index + 3]); byte seconds = BinaryCodedDecimal.Decode(buffer[index + 4]); double timebase = 2880.0D; index += 5; // Read sample number for M protocol if (protocolVersion == ProtocolVersion.M) { m_sampleNumber = BigEndian.ToUInt16(buffer, index + 5); timebase = 719.0D; index += 2; } // TODO: Think about how to handle year change with floating clock... // Calculate timestamp Parent.Timestamp = new DateTime(DateTime.UtcNow.Year, 1, 1).AddDays(day - 1).AddHours(hours).AddMinutes(minutes).AddSeconds(seconds + m_sampleNumber / timebase); } else { Parent.Timestamp = DateTime.UtcNow.Ticks; SynchronizationIsValid = false; m_sampleNumber = BigEndian.ToUInt16(buffer, index); index += 2; } // Parse out first five phasor values (1 - 5) int phasorIndex = 0; // Phasor 1 (always present) phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor2Enabled) == OnlineDataFormatFlags.Phasor2Enabled) { // Phasor 2 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor3Enabled) == OnlineDataFormatFlags.Phasor3Enabled) { // Phasor 3 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor4Enabled) == OnlineDataFormatFlags.Phasor4Enabled) { // Phasor 4 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor5Enabled) == OnlineDataFormatFlags.Phasor5Enabled) { // Phasor 5 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } // For 1690M format the frequency, reference phasor, dF/dt and first digital follow phasors 1-5 if (protocolVersion == ProtocolVersion.M) { // Parse out frequency value FrequencyValue = Macrodyne.FrequencyValue.CreateNewValue(this, configCell.FrequencyDefinition, buffer, index, out parsedLength); index += parsedLength; // Parse reference phasor information if (configFrame.ReferenceIncluded) { m_referenceSampleNumber = BigEndian.ToUInt16(buffer, index); m_referencePhasor = PhasorValue.CreateNewValue(this, new PhasorDefinition(null, "Reference Phasor", PhasorType.Voltage, null), buffer, index, out parsedLength) as PhasorValue; index += 6; } // Parse first digital value if (configFrame.Digital1Included) { digitalValue = DigitalValue.CreateNewValue(this, configCell.DigitalDefinitions[0], buffer, index, out parsedLength); DigitalValues.Add(digitalValue); index += parsedLength; } } // Parse out next five phasor values (6 - 10) if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor6Enabled) == OnlineDataFormatFlags.Phasor6Enabled) { // Phasor 6 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor7Enabled) == OnlineDataFormatFlags.Phasor7Enabled) { // Phasor 7 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor8Enabled) == OnlineDataFormatFlags.Phasor8Enabled) { // Phasor 8 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor9Enabled) == OnlineDataFormatFlags.Phasor9Enabled) { // Phasor 9 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if ((configFrame.OnlineDataFormatFlags & OnlineDataFormatFlags.Phasor10Enabled) == OnlineDataFormatFlags.Phasor10Enabled) { // Phasor 10 phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } // For 1690G format the channel phasors, reference phasor, frequency, dF/dt and digitals follow phasors 1-10 if (protocolVersion == ProtocolVersion.G) { // Technically 30 more possible channel phasors can be defined for (int i = phasorIndex; i < ConfigurationCell.PhasorDefinitions.Count; i++) { phasorValue = PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[phasorIndex++], buffer, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } // Parse reference phasor information if (configFrame.ReferenceIncluded) { m_referencePhasor = PhasorValue.CreateNewValue(this, new PhasorDefinition(null, "Reference Phasor", PhasorType.Voltage, null), buffer, index, out parsedLength) as PhasorValue; index += parsedLength; } // Parse out frequency value FrequencyValue = Macrodyne.FrequencyValue.CreateNewValue(this, configCell.FrequencyDefinition, buffer, index, out parsedLength); index += parsedLength; // Parse first digital value if (configFrame.Digital1Included) { digitalValue = DigitalValue.CreateNewValue(this, configCell.DigitalDefinitions[0], buffer, index, out parsedLength); DigitalValues.Add(digitalValue); index += parsedLength; } } // Parse second digital value if (configFrame.Digital2Included) { digitalValue = DigitalValue.CreateNewValue(this, configCell.DigitalDefinitions[configCell.DigitalDefinitions.Count - 1], buffer, index, out parsedLength); DigitalValues.Add(digitalValue); index += parsedLength; } // Return total parsed length return (index - startIndex); }
/// <summary> /// Creates a new <see cref="DataCell"/> from serialization parameters. /// </summary> /// <param name="info">The <see cref="SerializationInfo"/> with populated with data.</param> /// <param name="context">The source <see cref="StreamingContext"/> for this deserialization.</param> protected DataCell(SerializationInfo info, StreamingContext context) : base(info, context) { // Deserialize data cell m_status2Flags = info.GetByte("status2Flags"); m_clockStatusFlags = (ClockStatusFlags)info.GetValue("clockStatusFlags", typeof(ClockStatusFlags)); m_sampleNumber = info.GetUInt16("sampleNumber"); }
/// <summary> /// Parses the binary body image. /// </summary> /// <param name="binaryImage">Binary image to parse.</param> /// <param name="startIndex">Start index into <paramref name="binaryImage"/> to begin parsing.</param> /// <param name="length">Length of valid data within <paramref name="binaryImage"/>.</param> /// <returns>The length of the data that was parsed.</returns> protected override int ParseBodyImage(byte[] binaryImage, int startIndex, int length) { ConfigurationCell configCell = ConfigurationCell; ConfigurationFrame configFrame = configCell.Parent; IPhasorValue phasorValue; IDigitalValue digitalValue; int x, parsedLength, index = startIndex; m_status1Flags = binaryImage[index]; index++; // Parse out status 2 flags if (configFrame.Status2Included) { m_status2Flags = binaryImage[index]; index++; } else m_status2Flags = 0; base.StatusFlags = Word.MakeWord(m_status1Flags, m_status2Flags); // Parse out time tag if (configFrame.TimestampIncluded) { m_clockStatusFlags = (ClockStatusFlags)binaryImage[index]; index += 1; ushort day = BinaryCodedDecimal.Decode(EndianOrder.BigEndian.ToUInt16(binaryImage, index)); byte hours = BinaryCodedDecimal.Decode(binaryImage[index + 2]); byte minutes = BinaryCodedDecimal.Decode(binaryImage[index + 3]); byte seconds = BinaryCodedDecimal.Decode(binaryImage[index + 4]); m_sampleNumber = EndianOrder.BigEndian.ToUInt16(binaryImage, index + 5); index += 7; // TODO: Think about how to handle year change with floating clock... // Calculate timestamp Parent.Timestamp = new DateTime(DateTime.UtcNow.Year, 1, 1).AddDays(day - 1).AddHours(hours).AddMinutes(minutes).AddSeconds(seconds + m_sampleNumber / 719.0D); } else { Parent.Timestamp = DateTime.UtcNow.Ticks; SynchronizationIsValid = false; // TODO: Handle "assigned value" - change flags? m_sampleNumber = EndianOrder.BigEndian.ToUInt16(binaryImage, index); index += 2; } // Parse out first five phasor values for (x = 0; x < TVA.Common.Min(configCell.PhasorDefinitions.Count, 5); x++) { phasorValue = Macrodyne.PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[x], binaryImage, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } // Parse out frequency value FrequencyValue = Macrodyne.FrequencyValue.CreateNewValue(this, configCell.FrequencyDefinition, binaryImage, index, out parsedLength); index += parsedLength; if (configFrame.ReferenceIncluded) { // TODO: Parse reference phasor... index += 3; } if (configFrame.Digital1Included) { digitalValue = DigitalValue.CreateNewValue(this, configCell.DigitalDefinitions[0], binaryImage, index, out parsedLength); DigitalValues.Add(digitalValue); index += parsedLength; } // Parse out next five phasor values for (x = 5; x < configCell.PhasorDefinitions.Count; x++) { phasorValue = Macrodyne.PhasorValue.CreateNewValue(this, configCell.PhasorDefinitions[x], binaryImage, index, out parsedLength); PhasorValues.Add(phasorValue); index += parsedLength; } if (configFrame.Digital2Included) { digitalValue = DigitalValue.CreateNewValue(this, configCell.DigitalDefinitions[configCell.DigitalDefinitions.Count - 1], binaryImage, index, out parsedLength); DigitalValues.Add(digitalValue); index += parsedLength; } // Return total parsed length return (index - startIndex); }