Example #1
0
 /// <summary>
 /// Creates a new <see cref="DataFrame"/> from specified parameters.
 /// </summary>
 /// <param name="timestamp">The exact timestamp, in <see cref="Ticks"/>, of the data represented by this <see cref="DataFrame"/>.</param>
 /// <param name="configurationFrame">The <see cref="ConfigurationFrame"/> associated with this <see cref="DataFrame"/>.</param>
 /// <remarks>
 /// This constructor is used by a consumer to generate an IEEE C37.118 data frame.
 /// </remarks>
 public DataFrame(Ticks timestamp, ConfigurationFrame1 configurationFrame)
     : base(new DataCellCollection(), timestamp, configurationFrame)
 {
     // Pass time-base along to DataFrame's common header
     if (!(configurationFrame is null))
     {
         CommonHeader.Timebase = configurationFrame.Timebase;
     }
 }
        /// <summary>
        /// Creates a new <see cref="CommonFrameHeader"/> from specified parameters.
        /// </summary>
        /// <param name="configurationFrame">IEEE C37.118 <see cref="ConfigurationFrame1"/> if available.</param>
        /// <param name="typeID">The IEEE C37.118 specific frame type of this frame.</param>
        /// <param name="idCode">The ID code of this frame.</param>
        /// <param name="timestamp">The timestamp of this frame.</param>
        /// <param name="version">The target version for this IEEE C37.118 frame.</param>
        public CommonFrameHeader(ConfigurationFrame1 configurationFrame, FrameType typeID, ushort idCode, Ticks timestamp, DraftRevision version)
        {
            m_frameType = typeID;
            m_idCode    = idCode;
            m_timestamp = timestamp;
            m_version   = (byte)version;
            m_timebase  = (UInt24)100000;

            if (configurationFrame is null)
            {
                return;
            }

            // Hang on to configured frame rate and ticks per frame
            m_framesPerSecond = configurationFrame.FrameRate;
            m_ticksPerFrame   = Ticks.PerSecond / (double)m_framesPerSecond;
        }
        /// <summary>
        /// Creates a new <see cref="CommonFrameHeader"/> from given <paramref name="buffer"/>.
        /// </summary>
        /// <param name="configurationFrame">IEEE C37.118 <see cref="ConfigurationFrame1"/> if already parsed.</param>
        /// <param name="buffer">Buffer that contains data to parse.</param>
        /// <param name="startIndex">Start index into buffer where valid data begins.</param>
        public CommonFrameHeader(ConfigurationFrame1 configurationFrame, byte[] buffer, int startIndex)
        {
            const byte VersionNumberMask = (byte)IEEEC37_118.FrameType.VersionNumberMask;

            if (buffer[startIndex] != GemstonePhasorProtocolls.Common.SyncByte)
            {
                throw new InvalidOperationException($"Bad data stream, expected sync byte 0xAA as first byte in IEEE C37.118 frame, got 0x{buffer[startIndex].ToString("X").PadLeft(2, '0')}");
            }

            // Strip out frame type and version information...
            m_frameType = (FrameType)(buffer[startIndex + 1] & ~VersionNumberMask);
            m_version   = (byte)(buffer[startIndex + 1] & VersionNumberMask);

            m_frameLength = BigEndian.ToUInt16(buffer, startIndex + 2);
            m_idCode      = BigEndian.ToUInt16(buffer, startIndex + 4);

            uint secondOfCentury  = BigEndian.ToUInt32(buffer, startIndex + 6);
            uint fractionOfSecond = BigEndian.ToUInt32(buffer, startIndex + 10);

            // Without timebase, the best timestamp you can get is down to the whole second
            m_timestamp = new UnixTimeTag((decimal)secondOfCentury).ToDateTime().Ticks;

            if (!(configurationFrame is null))
            {
                // If config frame is available, frames have enough information for sub-second time resolution
                m_timebase = configurationFrame.Timebase;

                // "Actual fractional seconds" are obtained by taking fractionOfSecond and dividing by timebase.
                // Since we are converting to ticks, we need to multiply by Ticks.PerSecond.
                // We do the multiplication first so that the whole operation can be done using integer arithmetic.
                // m_timebase / 2L is added before dividing by timebase in order to round the result.
                long ticksBeyondSecond = (fractionOfSecond & ~Common.TimeQualityFlagsMask) * Ticks.PerSecond;
                m_timestamp += (ticksBeyondSecond + m_timebase / 2L) / m_timebase;

                // Hang on to configured frame rate and ticks per frame
                m_framesPerSecond = configurationFrame.FrameRate;
                m_ticksPerFrame   = Ticks.PerSecond / (double)m_framesPerSecond;
            }

            m_timeQualityFlags = fractionOfSecond & Common.TimeQualityFlagsMask;
        }
Example #4
0
 /// <summary>
 /// Creates a new <see cref="ConfigurationCell3"/> from specified parameters.
 /// </summary>
 /// <param name="parent">The reference to parent <see cref="ConfigurationFrame1"/> of this <see cref="ConfigurationCell3"/>.</param>
 /// <param name="idCode">The numeric ID code for this <see cref="ConfigurationCell3"/>.</param>
 /// <param name="nominalFrequency">The nominal Frequency of the <see cref="FrequencyDefinition"/> of this <see cref="ConfigurationCell3"/>.</param>
 public ConfigurationCell3(ConfigurationFrame1 parent, ushort idCode, double nominalFrequency) //FIXME: Does this need to use config frame 3?
     : this(parent)
 {
     IDCode           = idCode;
     NominalFrequency = nominalFrequency;
 }
 /// <summary>
 /// Creates a new <see cref="ConfigurationCell"/> from specified parameters.
 /// </summary>
 /// <param name="parent">The reference to parent <see cref="ConfigurationFrame1"/> of this <see cref="ConfigurationCell"/>.</param>
 /// <param name="idCode">The numeric ID code for this <see cref="ConfigurationCell"/>.</param>
 /// <param name="nominalFrequency">The nominal Frequency of the <see cref="FrequencyDefinition"/> of this <see cref="ConfigurationCell"/>.</param>
 public ConfigurationCell(ConfigurationFrame1 parent, ushort idCode, double nominalFrequency)
     : this(parent)
 {
     IDCode = idCode;
     NominalFrequency = nominalFrequency;
 }