Пример #1
0
        public IRpdMeterSystemInformation Build()
        {
            var rpdMeterInfo = new RpdMeterSystemInformationSimple();

            var br = new AdvancedBinaryReader(_stream, false);

            rpdMeterInfo.Address          = br.ReadByte();
            rpdMeterInfo.Type             = br.ReadByte();
            rpdMeterInfo.Status           = br.ReadByte();
            rpdMeterInfo.LinkErrorCounter = br.ReadByte();

            rpdMeterInfo.ChannelsMask          = br.ReadUInt16();
            rpdMeterInfo.ChannelsMaskFromMeter = br.ReadUInt16();
            rpdMeterInfo.ChannelsCount         = br.ReadByte();
            rpdMeterInfo.ChannelsDumpedCount   = br.ReadByte();

            var channelsDumpRulesCodes = new byte[MaxChannels];             // 0 - unused, 1..47 - valid

            br.Read(channelsDumpRulesCodes, 0, MaxChannels);
            rpdMeterInfo.ChannelsDumpRulesCodes = channelsDumpRulesCodes;

            rpdMeterInfo.HigherReadedFaultNumber    = br.ReadByte();
            rpdMeterInfo.ReadedFaultsCount          = br.ReadByte();
            rpdMeterInfo.NumberOfFaultDumpsForMeter = br.ReadByte();
            rpdMeterInfo.PageLine = br.ReadUInt32();
            rpdMeterInfo.PageLinesCountPerFault = br.ReadUInt32();
            rpdMeterInfo.Crc = br.ReadByte();
            return(rpdMeterInfo);
        }
Пример #2
0
        public void ReadFromStream(Stream stream)
        {
            var br = new AdvancedBinaryReader(stream, false);

            Type         = br.ReadByte();
            ControlValue = br.ReadInt16();
            MaxValue     = br.ReadInt16();
            MinValue     = br.ReadInt16();
        }
Пример #3
0
        public IRpdDumpRule Build()
        {
            var rule = new RpdDumpRuleSimple();
            var br   = new AdvancedBinaryReader(_stream, false);

            rule.Type         = br.ReadByte();
            rule.ControlValue = br.ReadInt16();
            rule.MaxValue     = br.ReadInt16();
            rule.MinValue     = br.ReadInt16();
            return(rule);
        }
        public IPsnDataFragmentInformation Build()
        {
            var br         = new AdvancedBinaryReader(_stream, false);
            var pageOffset = br.ReadUInt32();             // Номер страницы

            // 6 байт даты, если она была известна к началу фрагмента:
            var day   = br.ReadByte();
            var month = br.ReadByte();
            var year  = 2000 + br.ReadByte();

            var hour   = br.ReadByte();
            var minute = br.ReadByte();
            var second = br.ReadByte();

            DateTime?time;

            try {
                time = new DateTime(year, month, day, hour, minute, second);
            }
            catch {
                time = null;
            }

            return(new PsnDataFragmentInformationSimple {
                StartOffset = (int)pageOffset, StartTime = time
            });
        }
Пример #5
0
        public void ReadFromStream(Stream stream)
        {
            var br = new AdvancedBinaryReader(stream, false);

            Address          = br.ReadByte();
            Type             = br.ReadByte();
            Status           = br.ReadByte();
            LinkErrorCounter = br.ReadByte();

            ChannelsMask          = br.ReadUInt16();
            ChannelsMaskFromMeter = br.ReadUInt16();
            ChannelsCount         = br.ReadByte();
            ChannelsDumpedCount   = br.ReadByte();
            br.Read(ChannelsDumpRulesCodes, 0, 16);

            HigherReadedFaultNumber    = br.ReadByte();
            ReadedFaultsCount          = br.ReadByte();
            NumberOfFaultDumpsForMeter = br.ReadByte();
            PageLine = br.ReadUInt32();
            PageLinesCountPerFault = br.ReadUInt32();
            Crc = br.ReadByte();
        }
Пример #6
0
        public void ReadFromStream(Stream stream)
        {
            var br = new AdvancedBinaryReader(stream, false);

            Number = br.ReadByte();
            Status = br.ReadByte();
            Day    = br.ReadByte();
            Month  = br.ReadByte();
            Year   = br.ReadByte();
            Hour   = br.ReadByte();
            Minute = br.ReadByte();
            Second = br.ReadByte();

            DescriptionPageAddress = br.ReadInt32();
            LastWrittenPageAddress = br.ReadInt32();

            FaultWasReaded = br.ReadByte();
            BadPageCounter = br.ReadInt16();
        }
        public IRpdDataInformation Build()
        {
            var rpdLogInfo = new RpdDataInformationSimple();

            var br = new AdvancedBinaryReader(_stream, false);

            rpdLogInfo.Number = br.ReadByte();
            rpdLogInfo.Status = br.ReadByte();
            rpdLogInfo.Day    = br.ReadByte();
            rpdLogInfo.Month  = br.ReadByte();
            rpdLogInfo.Year   = br.ReadByte();
            rpdLogInfo.Hour   = br.ReadByte();
            rpdLogInfo.Minute = br.ReadByte();
            rpdLogInfo.Second = br.ReadByte();

            rpdLogInfo.DescriptionPageAddress = br.ReadInt32();
            rpdLogInfo.LastWrittenPageAddress = br.ReadInt32();

            rpdLogInfo.FaultWasReaded = br.ReadByte();
            rpdLogInfo.BadPageCounter = br.ReadInt16();
            return(rpdLogInfo);
        }
Пример #8
0
        /// <summary>
        /// Прочитать информацию об аварии из бинарника вида AVR*.bin
        /// Переопределяет название аварии из бинарника
        /// Переопределяет время аварии
        /// Переопределяет FileHash
        /// Переопределяет BinFileInfo
        /// </summary>
        /// <param name="sourceFile">Путь к бинарнику</param>
        /// <returns>Результат операции</returns>
        public bool ReadInfoFromBinaryFile(FileInfo sourceFile)
        {
            //Log.Global.Info("Попытка чтения информации об аварии из файла: " + sourceFile.FullName);
            bool result = true;

            sourceFile.Refresh();
            if (sourceFile.Exists)
            {
                //Log.Global.Info("Файл лога аварии существует");
                using (var reader = new AdvancedBinaryReader(new FileStream(sourceFile.FullName, FileMode.Open, FileAccess.Read), false))
                {
                    long pagesCount = reader.BaseStream.Length / 2048;
                    //Log.Global.Info("Количество страниц в файле = " + pagesCount);
                    bool startPageFound = false;
                    //int startPageIndex = 0;
                    bool firstNonstartPageFound = false;
                    for (long i = 0; i < pagesCount; ++i)
                    {
                        reader.BaseStream.Seek(i * 2048, SeekOrigin.Begin);
                        byte firstPageByte = reader.ReadByte();            // считаем первый байт
                        if (firstPageByte == 0x55)                         // заголовок найден!
                        {
                            //Log.Global.Info("Заголовочная страница найдена, её номер = " + i);
                            startPageFound  = true;
                            HeaderPageIndex = i;                             // запомнить индекс страницы-заголовка аварии (но в реальности страниц может быть много!)
                            // следующие 6 байт - дата (dd|MM|yy|HH|mm|ss)
                            byte day   = reader.ReadByte();
                            byte month = reader.ReadByte();
                            byte year  = reader.ReadByte();

                            byte hour   = reader.ReadByte();
                            byte minute = reader.ReadByte();
                            byte second = reader.ReadByte();
                            try {
                                AccuredAt = new DateTime(2000 + year, month, day, hour, minute, second);                                 // соберем байты в удобный вид
                            }
                            catch {
                                //Log.Global.Info("Не удалось распарсить дату и время аварии из байт: " + year + " " + month + " " + day + " " + hour + " " + minute + " " + second);
                                AccuredAt = DateTime.MinValue;
                            }
                            //Log.Global.Info("Дата аварии = " + AccuredAt.ToString("yyyy.MM.dd HH:mm:ss"));
                            _faultNumberFromHeader = reader.ReadByte();        // прочитаем номер аварии (байт №8)
                            _metersCount           = reader.ReadByte();        // прочитаем число измерителей (байт №9)
                        }
                        else if (firstPageByte < 0x55)                         // Первую незаголовочную страницу нужно прочитать для получения настроек измерителя:
                        {
                            if (startPageFound)
                            {
                                firstNonstartPageFound = true;
                            }
                            //Log.Global.Info("Незаголовочная страница, её индекс=" + i + " RpdMeters.Count=" + RpdMeters.Count);
                            reader.BaseStream.Seek(i * 2048, SeekOrigin.Begin);

                            var pageRaw = new byte[2048];
                            reader.Read(pageRaw, 0, 2048);                             //считываем страницу
                            var currentPage = new FaultArchivePage(pageRaw, this);

                            // Считываем настройки всех измерителей:
                            for (int j = 0; j < _metersCount; ++j)
                            {
                                var neededMeter = (RpdMeter)RpdMeters[j];
                                if (!neededMeter.SettingsReaded)
                                {
                                    neededMeter.ReadSettings(currentPage);
                                }
                            }
                        }


                        if (startPageFound && firstNonstartPageFound)
                        {
                            break;
                        }
                    }



                    if (startPageFound && firstNonstartPageFound)
                    {
                        //reader.BaseStream.Seek(startPageIndex * 2048, SeekOrigin.Begin);
                        // После чтения информации по измерителям РПД необходимо вернуться в начало и прочитать текущие данные:
                        var rpdCurrentData = new List <RpdChannelCurrentData>();
                        int rpdChannelCurrentDataOffset = 9;
                        // В этом цикле считываем текущие данные каналов РПД, заодно на выходе получая позицию текущих данных ПСН
                        for (int i = 0; i < _metersCount; ++i)
                        {
                            rpdChannelCurrentDataOffset += MeterHeaderCurrentDataRecordLength;

                            foreach (RpdChannel ch in RpdMeters[i].Channels)
                            {
                                //Log.Global.Info("Channel=" + ch.Name + ".IsEnabled = " + ch.IsEnabled);
                                if (ch.IsEnabled)
                                {
                                    rpdChannelCurrentDataOffset += ChannelCurrentDataRecordLength;
                                    //Log.Global.Info("rpdChannelCurrentDataOffset = " + rpdChannelCurrentDataOffset);
                                    // Если настройки были прочитаны:
                                    // Нельзя выносить на верхний уровень, т.к. тогда не правильно отработает смещение rpdChannelCurrentDataOffset
                                    var neededMeter = (RpdMeter)RpdMeters[i];
                                    if (neededMeter.Settings != null && neededMeter.SettingsReaded)
                                    {
                                        //Log.Global.Info(neededMeter.Name + " настроки были прочитаны");
                                        reader.BaseStream.Seek(HeaderPageIndex * 2048 + rpdChannelCurrentDataOffset, SeekOrigin.Begin);

                                        var chT = neededMeter.Settings.Calibrations.Channels[ch.Number - 1];
                                        var b1  = reader.ReadByte();                                        // По суте первый байт не нужен, но нужно сдвинуть текущее положение в файле на 1 байт
                                        var b2  = reader.ReadByte();
                                        var b3  = reader.ReadByte();
                                        //Log.Global.Info("b1 = " + b1);
                                        //Log.Global.Info("b2 = " + b2);
                                        //Log.Global.Info("b3 = " + b3);
                                        double channelCurrentValue = b2 + b3 * 256.0;
                                        //Log.Global.Info("ChCurrValue = " + channelCurrentValue);
                                        double modifiedCurValue = (channelCurrentValue - chT.Zero) * chT.Kkor * chT.Kper * 1.0;
                                        //Log.Global.Info("ResultValue = " + modifiedCurValue);
                                        rpdCurrentData.Add(new RpdChannelCurrentData(ch, modifiedCurValue));
                                    }
                                }
                            }
                        }
                        int psnCurrentDataOffset = rpdChannelCurrentDataOffset;                         // На самом деле № позиции текущих данных ПСН определяется так: сумма числа разрешённых каналов рпд по каждому измерителю:
                        //Log.Global.Info("Смещение текущих данных магистрали ПСН: psnCurrentDataOffset=" + psnCurrentDataOffset);

                        var psnReasonRaw = new byte[FaultReason.PsnGaugesCount * FaultReason.PsnReplyMaxLength];
                        reader.BaseStream.Seek(HeaderPageIndex * 2048 + psnCurrentDataOffset, SeekOrigin.Begin);
                        reader.Read(psnReasonRaw, 0, psnReasonRaw.Length);
                        // TODO: whre to get PsnChannelSimple
                        //Reason = new FaultReason(rpdCurrentData, PsnPagesParser.GetPsnCurrentData(psnReasonRaw, _deviceConfig));
                        reader.Close();
                    }
                    else
                    {
                        reader.Close();
                        throw new Exception("Ошибка, не удалось найти начальную страницу или первую страницу с данными");
                    }
                    //reader.Close();


                    FileHash    = DTHasher.GetMD5Hash(sourceFile.FullName, string.Empty);
                    BinFilePath = sourceFile;
                    //this.Name = sourceFile.Name; // Имя исходного файла всегда корявое,
                    UpdateName();
                    //Log.Global.Info("Информация об аварии {" + Name + "} успешно прочитана");
                    //Log.Global.Info(BinFilePath.FullName);
                    //Log.Global.Info(Reason.ToString);
                }
            }
            else
            {
                result = false;
                //Log.Global.Info("Файл лога аварии не существует! result = " + result);
            }

            return(result);
        }
        public ICommandConfiguration BuildConfiguration()
        {
            // PERFOMANCE INCREASE POSSIBILITY: need fastest work with stream, closing it, then filling fields and vars
            using (var br = new AdvancedBinaryReader(File.OpenRead(_filename), false)) {
                br.BaseStream.Seek(2048, SeekOrigin.Begin);
                var memoryStatusByte = br.ReadByte();
                var configStatusByte = br.ReadByte();

                var verificationStatusBytes = br.ReadBytes(32);

                var meterChannelConfigVerificationStatuses = new List <IMetersChannelsConfigurationVerificationStatus>();
                for (int i = 0; i < verificationStatusBytes.Length; ++i)
                {
                    var status = verificationStatusBytes[i];
                    ChannelConfigVerificationStatus st;
                    switch (status)
                    {
                    case 0:
                        st = ChannelConfigVerificationStatus.NoMeterFoundInTable;
                        break;

                    case 1:
                        st = ChannelConfigVerificationStatus.VerificationSuccess;
                        break;

                    case 2:
                        st = ChannelConfigVerificationStatus.ErrorDuringConfigurationWriting;
                        break;

                    case 3:
                        st = ChannelConfigVerificationStatus.NoLinkWithMeter;
                        break;

                    case 4:
                        st = ChannelConfigVerificationStatus.VerificationInProgress;
                        break;

                    default:
                        st = ChannelConfigVerificationStatus.Unknown;
                        break;
                    }
                    meterChannelConfigVerificationStatuses.Add(new MetersChannelsConfigurationVerificationStatusSimple(i, st));
                }
                br.ReadByte();
                var second = br.ReadByte();
                var minute = br.ReadByte();
                var hour   = br.ReadByte();
                var day    = br.ReadByte();
                var month  = br.ReadByte();
                var year   = br.ReadByte();

                DateTime?dateTime;
                try {
                    dateTime = new DateTime(2000 + year, month, day, hour, minute, second);
                }
                catch {
                    dateTime = null;
                }

                var psnProtocolType = br.ReadUInt16();

                return(new CommandConfigurationSimple(
                           dateTime,
                           (memoryStatusByte & 0x01) == 0x01,
                           (memoryStatusByte & 0x02) == 0x02,
                           (memoryStatusByte & 0x04) == 0x04,
                           (memoryStatusByte & 0x08) == 0x08,

                           (configStatusByte & 0x01) == 0x01,
                           (configStatusByte & 0x02) == 0x02,
                           (configStatusByte & 0x04) == 0x04,
                           (configStatusByte & 0x08) == 0x08,
                           (configStatusByte & 0x10) == 0x10,
                           (configStatusByte & 0x20) == 0x20,
                           (configStatusByte & 0x40) == 0x40,

                           meterChannelConfigVerificationStatuses,
                           psnProtocolType
                           ));
            }
        }
        public ISystemConfiguration BuildConfiguration()
        {
            var sysconf = new SystemConfigurationSimple();

            if (File.Exists(_fileName))
            {
                var raw = File.ReadAllBytes(_fileName);
                if (raw.Length != FileSize)
                {
                    throw new Exception("SYSCONF.BIN file size must be " + FileSize);
                }

                using (var br = new AdvancedBinaryReader(new MemoryStream(raw, false), false)) {
                    //br.Read(sysconf.Raw, 0, sysconf.Raw.Length);
                    br.BaseStream.Seek(0, SeekOrigin.Begin);

                    //-----------------------------------------------------------0 (0)
                    sysconf.DeviceAddress = br.ReadUInt16();
                    sysconf.NetAddress    = (int)br.ReadUInt32();

                    var locomotiveAndSectionNumbers = br.ReadUInt16();
                    sysconf.LocomotiveNumber = locomotiveAndSectionNumbers & 0x7FFF;
                    sysconf.SectionNumber    = (locomotiveAndSectionNumbers & 0x8000) > 0 ? 2 : 1;
                    //br.BaseStream.Seek(8, SeekOrigin.Begin);
                    sysconf.FirmwareVersion                  = br.ReadUInt16();
                    sysconf.LastWrittenPageAddress           = (int)br.ReadUInt32();
                    sysconf.LastReadedBlockAddress           = br.ReadUInt16();
                    sysconf.BadBlocksCount                   = br.ReadUInt16();
                    sysconf.LastWrittenPageNumber            = br.ReadUInt16();
                    sysconf.FirstWrittenAfterResetPageNumber = (int)br.ReadUInt32();
                    sysconf.PsnLogStartPageNumber            = (int)br.ReadUInt32();
                    sysconf.ArrayDumpPsnStartPageNumber      = (int)br.ReadUInt32();
                    sysconf.FatOffsetFromPageZero            = (int)br.ReadUInt32();
                    sysconf.RpdPagesCountTransmittedToPsnLog = (int)br.ReadUInt32();
                    sysconf.ConfigurationByte                = br.ReadByte();

                    //-----------------------------------------------------------1 (2048)
                    br.BaseStream.Seek(2048, SeekOrigin.Begin);
                    sysconf.FaultsCount = br.ReadByte();

                    var rpdLogInfos       = new IRpdDataInformation[FaultLogTableRecordsMax];
                    var rpdLogInfoBuilder = new RpdDataInformationBuilderFromStream(br.BaseStream);
                    for (int i = 0; i < FaultLogTableRecordsMax; ++i)
                    {
                        rpdLogInfos[i] = rpdLogInfoBuilder.Build();
                    }
                    sysconf.FaultDumpsTable = rpdLogInfos;

                    //-----------------------------------------------------------2 (4096)
                    br.BaseStream.Seek(4096, SeekOrigin.Begin);
                    sysconf.MetersCount = br.ReadByte();
                    var rpdMeters           = new IRpdMeterSystemInformation[MetersTableRecordsMax];
                    var rpdMeterInfoBuilder = new RpdMeterSystemInformationBuilderFromStream(br.BaseStream);
                    for (int i = 0; i < MetersTableRecordsMax; ++i)
                    {
                        rpdMeters[i] = rpdMeterInfoBuilder.Build();
                    }
                    sysconf.MetersTable = rpdMeters;

                    //4096 + 1217:
                    br.BaseStream.Seek(4096 + 1217, SeekOrigin.Begin);                     // установим необходимое смещение
                    var psnRegisterStatusMasks = new byte[PsnRegisterStatusMasksMax];
                    br.Read(psnRegisterStatusMasks, 0, PsnRegisterStatusMasksMax);
                    sysconf.PsnRegisterStatusMasks = psnRegisterStatusMasks;

                    //4096 + 1238:
                    br.BaseStream.Seek(4096 + 1238, SeekOrigin.Begin);                     // установим необходимое смещение
                    var dumpRules           = new IRpdDumpRule[DumpRulesMax];
                    var rpdDumpRulesBuilder = new RpdDumpRuleBuilderFromStream(br.BaseStream);
                    for (int i = 0; i < DumpRulesMax; ++i)
                    {
                        dumpRules[i] = rpdDumpRulesBuilder.Build();
                    }
                    sysconf.DumpRules = dumpRules;
                    //------------------------------------------------------------3 (6144)

                    const int offsetPage3             = 6144;
                    const int offsetPowerOnStartPages = offsetPage3 + 2;
                    const int offsetFixedStartPages   = offsetPage3 + 500;

                    br.BaseStream.Seek(offsetPage3, SeekOrigin.Begin);
                    sysconf.CurrentPsnLogNumber = br.ReadUInt16();

                    br.BaseStream.Seek(offsetPowerOnStartPages, SeekOrigin.Begin);
                    var powerOnOffsetInfos        = new List <IPsnDataFragmentInformation>();
                    var psnLogFragmentInfoBuilder = new PsnDataFragmentInformationBuilderFromStream(br.BaseStream);
                    for (int i = 0; i < PsnLogPowerOnStartPagesMaxCount; ++i)
                    {
                        var psnLogFragmentInfo = psnLogFragmentInfoBuilder.Build();
                        if (psnLogFragmentInfo.StartOffset >= sysconf.PsnLogStartPageNumber)
                        {
                            powerOnOffsetInfos.Add(psnLogFragmentInfo);
                        }
                    }
                    // —писок инвертируетс¤, т.к. перед записью элементы таблицы смещаютс¤ и последний элемент оказываетс¤ в начале таблицы
                    powerOnOffsetInfos.Reverse();
                    sysconf.PsnLogPowerUpFragmentInfos = powerOnOffsetInfos;

                    br.BaseStream.Seek(offsetFixedStartPages, SeekOrigin.Begin);                     // „итаем фиксированные смещени¤:
                    var predefinedFragmentInfos = new List <IPsnDataFragmentInformation>();
                    for (int i = 0; i < PsnPredefinedFragmentStartInfosMaxCount; ++i)
                    {
                        predefinedFragmentInfos.Add(psnLogFragmentInfoBuilder.Build());
                    }
                    sysconf.PsnLogPredefinedFragmentInfos = predefinedFragmentInfos;
                    br.BaseStream.Close();
                }
                return(sysconf);
            }
            throw new Exception("Cannot find binary file, file " + _fileName + " is not exist");
        }