Esempio n. 1
0
        private DateTime ParseTimestamp(ushort[] clockWords)
        {
            if ((object)clockWords == null)
            {
                throw new NullReferenceException("Clock words array was null - cannot parse timestamp");
            }

            if (clockWords.Length != 4)
            {
                throw new InvalidOperationException("Clock words array must have four values - cannot parse timestamp");
            }

            int  days, hours, minutes, seconds, milliseconds, microseconds;
            byte highByte, lowByte;

            highByte = clockWords[0].HighByte();
            lowByte  = clockWords[0].LowByte();

            days  = highByte.HighNibble() * 100 + highByte.LowNibble() * 10 + lowByte.HighNibble();
            hours = lowByte.LowNibble() * 10;

            highByte = clockWords[1].HighByte();
            lowByte  = clockWords[1].LowByte();

            hours  += highByte.HighNibble();
            minutes = highByte.LowNibble() * 10 + lowByte.HighNibble();
            seconds = lowByte.LowNibble() * 10;

            highByte = clockWords[2].HighByte();
            lowByte  = clockWords[2].LowByte();

            seconds += highByte.HighNibble();

            milliseconds = highByte.LowNibble() * 100 + lowByte.HighNibble() * 10 + lowByte.LowNibble();

            if (milliseconds > 999)
            {
                milliseconds = 0;
            }

            highByte = clockWords[3].HighByte();
            lowByte  = clockWords[3].LowByte();

            microseconds = highByte.HighNibble() * 100 + highByte.LowNibble() * 10 + lowByte.HighNibble();

            if (microseconds > 999)
            {
                microseconds = 0;
            }

            return(m_baseTime
                   .AddDays(days - 1)  // Base time starts at day one, so we subtract one for target day
                   .AddHours(hours)
                   .AddMinutes(minutes)
                   .AddSeconds(seconds)
                   .AddMilliseconds(milliseconds)
                   .AddTicks(Ticks.FromMicroseconds(microseconds)));
        }
Esempio n. 2
0
        private int ReadTimestamp(byte[] buffer)
        {
            int index = 0;

            // Read sample index
            uint sample = LittleEndian.ToUInt32(buffer, index);

            index += 4;

            // Get timestamp of this record
            Timestamp = DateTime.MinValue;

            // If sample rates are defined, this is the preferred method for timestamp resolution
            if (InferTimeFromSampleRates && m_schema.SampleRates.Length > 0)
            {
                // Find rate for given sample
                SampleRate sampleRate = m_schema.SampleRates.LastOrDefault(sr => sample <= sr.EndSample);

                if (sampleRate.Rate > 0.0D)
                {
                    Timestamp = new DateTime(Ticks.FromSeconds(1.0D / sampleRate.Rate * sample) + m_schema.StartTime.Value);
                }
            }

            // Read microsecond timestamp
            uint microseconds = LittleEndian.ToUInt32(buffer, index);

            index += 4;

            // Fall back on specified microsecond time
            if (Timestamp == DateTime.MinValue)
            {
                Timestamp = new DateTime(Ticks.FromMicroseconds(microseconds * m_schema.TimeFactor) + m_schema.StartTime.Value);
            }

            // Apply timestamp offset to restore UTC timezone
            if (AdjustToUTC)
            {
                TimeOffset offset = Schema.TimeCode ?? new TimeOffset();
                Timestamp = new DateTime(Timestamp.Ticks + offset.TickOffset, DateTimeKind.Utc);
            }

            return(index);
        }
Esempio n. 3
0
        // Handle binary file read
        private bool ReadNextBinary()
        {
            FileStream currentFile  = m_fileStreams[m_streamIndex];
            int        recordLength = m_schema.BinaryRecordLength;

            byte[] buffer = new byte[recordLength];

            // Read next record from file
            int bytesRead = currentFile.Read(buffer, 0, recordLength);

            // See if we have reached the end of this file
            if (bytesRead == 0)
            {
                m_streamIndex++;

                // There is more to read if there is another file
                return(m_streamIndex < m_fileStreams.Length && ReadNext());
            }

            if (bytesRead == recordLength)
            {
                int index = 0;

                // Read sample index
                uint sample = LittleEndian.ToUInt32(buffer, index);
                index += 4;

                // Get timestamp of this record
                m_timestamp = DateTime.MinValue;

                // If sample rates are defined, this is the preferred method for timestamp resolution
                if (m_inferTimeFromSampleRates && m_schema.SampleRates.Length > 0)
                {
                    // Find rate for given sample
                    SampleRate sampleRate = m_schema.SampleRates.LastOrDefault(sr => sample <= sr.EndSample);

                    if (sampleRate.Rate > 0.0D)
                    {
                        m_timestamp = new DateTime(Ticks.FromSeconds(1.0D / sampleRate.Rate * sample) + m_schema.StartTime.Value);
                    }
                }

                // Read microsecond timestamp
                uint microseconds = LittleEndian.ToUInt32(buffer, index);
                index += 4;

                // Fall back on specified microsecond time
                if (m_timestamp == DateTime.MinValue)
                {
                    m_timestamp = new DateTime(Ticks.FromMicroseconds(microseconds * m_schema.TimeFactor) + m_schema.StartTime.Value);
                }

                // Parse all analog record values
                for (int i = 0; i < m_schema.AnalogChannels.Length; i++)
                {
                    // Read next value
                    m_values[i] = LittleEndian.ToInt16(buffer, index) * m_schema.AnalogChannels[i].Multiplier + m_schema.AnalogChannels[i].Adder;
                    index      += 2;
                }

                int    valueIndex   = m_schema.AnalogChannels.Length;
                int    digitalWords = m_schema.DigitalWords;
                ushort digitalWord;

                for (int i = 0; i < digitalWords; i++)
                {
                    // Read next digital word
                    digitalWord = LittleEndian.ToUInt16(buffer, index);
                    index      += 2;

                    // Distribute each bit of digital word through next 16 digital values
                    for (int j = 0; j < 16 && valueIndex < m_values.Length; j++, valueIndex++)
                    {
                        m_values[valueIndex] = digitalWord.CheckBits(BitExtensions.BitVal(j)) ? 1.0D : 0.0D;
                    }
                }
            }
            else
            {
                throw new InvalidOperationException("Failed to read enough bytes from COMTRADE file for a record as defined by schema - possible schema/data file mismatch or file corruption.");
            }

            return(true);
        }
Esempio n. 4
0
        // Handle ASCII file read
        private bool ReadNextAscii()
        {
            if ((object)m_fileReaders == null)
            {
                m_fileReaders = new StreamReader[m_fileStreams.Length];

                for (int i = 0; i < m_fileStreams.Length; i++)
                {
                    m_fileReaders[i] = new StreamReader(m_fileStreams[i]);
                }
            }

            // Read next line of record values
            StreamReader reader = m_fileReaders[m_streamIndex];
            string       line   = reader.ReadLine();

            string[] elems = ((object)line != null) ? line.Split(',') : null;

            // See if we have reached the end of this file
            if ((object)elems == null || elems.Length != m_values.Length + 2)
            {
                if (reader.EndOfStream)
                {
                    m_streamIndex++;

                    // There is more to read if there is another file
                    return(m_streamIndex < m_fileStreams.Length && ReadNext());
                }

                throw new InvalidOperationException("COMTRADE schema does not match number of elements found in ASCII data file.");
            }

            // Parse row of data
            uint sample = uint.Parse(elems[0]);

            // Get timestamp of this record
            m_timestamp = DateTime.MinValue;

            // If sample rates are defined, this is the preferred method for timestamp resolution
            if (m_inferTimeFromSampleRates && m_schema.SampleRates.Length > 0)
            {
                // Find rate for given sample
                SampleRate sampleRate = m_schema.SampleRates.LastOrDefault(sr => sample <= sr.EndSample);

                if (sampleRate.Rate > 0.0D)
                {
                    m_timestamp = new DateTime(Ticks.FromSeconds(1.0D / sampleRate.Rate * sample) + m_schema.StartTime.Value);
                }
            }

            // Fall back on specified microsecond time
            if (m_timestamp == DateTime.MinValue)
            {
                m_timestamp = new DateTime(Ticks.FromMicroseconds(uint.Parse(elems[1]) * m_schema.TimeFactor) + m_schema.StartTime.Value);
            }

            // Parse all record values
            for (int i = 0; i < m_values.Length; i++)
            {
                m_values[i] = double.Parse(elems[i + 2]);

                if (i < m_schema.AnalogChannels.Length)
                {
                    m_values[i] *= m_schema.AnalogChannels[i].Multiplier;
                    m_values[i] += m_schema.AnalogChannels[i].Adder;
                }
            }

            return(true);
        }
Esempio n. 5
0
        // Handle ASCII file read
        private bool ReadNextAscii()
        {
            // For ASCII files, we wrap file streams with file readers
            if ((object)m_fileReaders == null)
            {
                m_fileReaders = new StreamReader[m_fileStreams.Length];

                for (int i = 0; i < m_fileStreams.Length; i++)
                {
                    m_fileReaders[i] = new StreamReader(m_fileStreams[i]);
                }
            }

            // Read next line of record values
            StreamReader reader = m_fileReaders[m_streamIndex];
            string       line   = reader.ReadLine();

            string[] elems = ((object)line != null) ? line.Split(',') : null;

            // See if we have reached the end of this file
            if ((object)elems == null || elems.Length != Values.Length + 2)
            {
                if (reader.EndOfStream)
                {
                    return(ReadNextFile());
                }

                throw new InvalidOperationException("COMTRADE schema does not match number of elements found in ASCII data file.");
            }

            // Parse row of data
            uint sample = uint.Parse(elems[0]);

            // Get timestamp of this record
            Timestamp = DateTime.MinValue;

            // If sample rates are defined, this is the preferred method for timestamp resolution
            if (InferTimeFromSampleRates && m_schema.SampleRates.Length > 0)
            {
                // Find rate for given sample
                SampleRate sampleRate = m_schema.SampleRates.LastOrDefault(sr => sample <= sr.EndSample);

                if (sampleRate.Rate > 0.0D)
                {
                    Timestamp = new DateTime(Ticks.FromSeconds(1.0D / sampleRate.Rate * sample) + m_schema.StartTime.Value);
                }
            }

            // Fall back on specified microsecond time
            if (Timestamp == DateTime.MinValue)
            {
                Timestamp = new DateTime(Ticks.FromMicroseconds(uint.Parse(elems[1]) * m_schema.TimeFactor) + m_schema.StartTime.Value);
            }

            // Apply timestamp offset to restore UTC timezone
            if (AdjustToUTC)
            {
                TimeOffset offset = Schema.TimeCode ?? new TimeOffset();
                Timestamp = new DateTime(Timestamp.Ticks + offset.TickOffset, DateTimeKind.Utc);
            }

            // Parse all record values
            for (int i = 0; i < Values.Length; i++)
            {
                Values[i] = double.Parse(elems[i + 2]);

                if (i < m_schema.AnalogChannels.Length)
                {
                    Values[i] = AdjustValue(Values[i], i);
                }
            }

            return(true);
        }