コード例 #1
0
        public void GetDataInCallback(int command, IReadOnlyList <byte> data, Action <Exception, IReadOnlyList <byte> > callback)
        {
            if (command == 6)
            {
                var result = data.ToList();
                if (result[3] == 0)
                {
                    Log.Log(Name + " > " + "Запрос текущих данных через шестерку");
                    var cmd = new PollCommand();

                    if (_lastCurrentDataRequestTime.HasValue && _lastCurrentDataResult != null && DateTime.Now - _lastCurrentDataRequestTime < _cacheTtl)
                    {
                        NamedLog("Данные взяты из кэша (время жизни кэша до: " + (_lastCurrentDataRequestTime.Value + _cacheTtl).ToString("yyyy.MM.dd-HH:mm:ss") + ") и сейчас будут отправлены: " + _lastCurrentDataResult.ToText());
                        callback(null, _lastCurrentDataResult);
                    }
                    else
                    {
                        NamedLog("Отправка запроса в менеджер обмена по сети БУМИЗ");
                        _bumiz.SendDataAsync(
                            _bumizControllerInfo.Name,
                            cmd,
                            sendResult => {
                            try {
                                NamedLog("Менеджер обмена БУМИЗ вернул управление");
                                if (sendResult.ChannelException == null)
                                {
                                    var cmdResult = cmd.GetResult(sendResult.Bytes);
                                    NamedLog("Результат обмена: " + cmdResult);

                                    var i1 = (float)cmdResult.PhaseAcurrent;
                                    var i2 = (float)cmdResult.PhaseBcurrent;
                                    var i3 = (float)cmdResult.PhaseCcurrent;
                                    var p1 = (float)cmdResult.PowerT1;
                                    var p2 = (float)cmdResult.PowerT2;

                                    var bits = (byte)(
                                        (cmdResult.IsInFault ? 0x01 : 0x00) +
                                        (cmdResult.IsTurnedOn ? 0x02 : 0x00) +
                                        (cmdResult.NoLinkWithCounter ? 0x00 : 0x04) +
                                        (cmdResult.CounterType == "СЕ102" ? 0x08 : 0x00) +
                                        (cmdResult.IsAutoTurnOffTimerStarted ? 0x10 : 0x00) +
                                        (cmdResult.NoFramOrCrcError ? 0x20 : 0x00) +
                                        (cmdResult.NoArchives ? 0x00 : 0x40));
                                    NamedLog("Упаковка данных в байты ответа...");
                                    result.AddRange(i1.ToBytes());
                                    result.AddRange(i2.ToBytes());
                                    result.AddRange(i3.ToBytes());
                                    result.AddRange(p1.ToBytes());
                                    result.AddRange(p2.ToBytes());
                                    result.Add(bits);

                                    var channel = result[0];
                                    var number  = result[2];
                                    result.Add(number);
                                    result.Add(0);
                                    result.Add(channel);
                                    result.Add(0);

                                    NamedLog("Упаковка текущих данных завершена");

                                    _lastCurrentDataRequestTime = DateTime.Now;
                                    _lastCurrentDataResult      = result.ToList();

                                    File.AppendAllText(
                                        Path.Combine(Env.LogPath, _bumizControllerInfo.Name + ".read.txt"),
                                        DateTime.Now.ToString("yyyy.MM.dd-HH:mm:ss") + " > " +
                                        i1.ToString("f2") + " \t" +
                                        i2.ToString("f2") + " \t" +
                                        i3.ToString("f2") + " \t" +
                                        p1.ToString("f2") + " \t" +
                                        p2.ToString("f2") + " \t" +
                                        bits + Environment.NewLine);
                                }
                                else
                                {
                                    NamedLog("Произошло внутреннее исключение при обмене: " + sendResult.ChannelException);
                                }
                            }
                            catch (Exception ex) {
                                NamedLog("После отправки команды, при обработке ответа возникло исключение: " + ex);
                            }
                            finally {
                                NamedLog("В скаду через шлюз будет отправлен результат: " + result.ToText());
                                callback(null, result);
                            }
                        }, IoPriority.High);
                    }
                }
                else if ((result[3] & 0x06) == 0x06)
                {
                    try {
                        NamedLog("Запрос получасовых данных для " + _bumizControllerInfo.Name);
                        var minutes     = result[3] == 0x06 ? 0 : 30;
                        var hour        = result[4];
                        var day         = result[5];
                        var month       = result[6];
                        var year        = 2000 + result[7];
                        var certainTime = new DateTime(year, month, day, hour, minutes, 0);

                        if (certainTime > DateTime.Now)
                        {
                            NamedLog("Запрос за время, которое в системе еще не достигнуто! " + certainTime.ToSimpleString());
                        }
                        NamedLog("Запрос к хранилищу импульсов за время " + certainTime.ToSimpleString());

                        var storedImpulses = _pcStorageHolder.Storage.GetAtomicData(Name, certainTime);
                        if (storedImpulses == null)
                        {
                            throw new Exception("Не удалось получить информацию по импульсам за время" + certainTime.ToSimpleString() + " для объекта " + Name);
                        }
                        var storedIntegral = _pcStorageHolder.Storage.GetIntegralData(Name, certainTime);
                        if (storedIntegral == null)
                        {
                            throw new Exception("Не удалось получить суммарную информацию по импульсам до времени " + certainTime.ToSimpleString() + " для объекта " + Name);
                        }
                        NamedLog("Запрос к хранилищу выполнен");
                        NamedLog("Получены следующие суммарные данные из хранилища: " + storedIntegral);

                        var exps = new List <Expression>
                        {
                            new Expression(_bumizControllerInfo.Pulse1Expression),
                            new Expression(_bumizControllerInfo.Pulse2Expression),
                            new Expression(_bumizControllerInfo.Pulse3Expression)
                        };

                        foreach (var expression in exps)
                        {
                            expression.Parameters.Add("p1", storedIntegral.ImpulsesCount1);
                            expression.Parameters.Add("p2", storedIntegral.ImpulsesCount2);
                            expression.Parameters.Add("p3", storedIntegral.ImpulsesCount3);
                        }

                        var rp1 = (float)(double)exps[0].Evaluate();
                        var rp2 = (float)(double)exps[1].Evaluate();
                        var rp3 = (float)(double)exps[2].Evaluate();

                        result.AddRange(rp1.ToBytes());
                        result.AddRange(rp2.ToBytes());
                        result.AddRange(rp3.ToBytes());
                        NamedLog("В результате применения к импульсам расчетных формул получены значения расходов: (p1, p2, p3): " + rp1.ToString("f2") + "   " + rp2.ToString("f2") + "   " + rp3.ToString("f2"));


                        result.AddRange(BitConverter.GetBytes(storedIntegral.RecordsCount));
                        result.AddRange(BitConverter.GetBytes(storedIntegral.CorrectRecordsCount));
                        result.AddRange(BitConverter.GetBytes(storedIntegral.IncorrectRecordsCount));
                        result.AddRange(BitConverter.GetBytes(storedIntegral.SupposedRecordsCount));
                        NamedLog("Всего записей в хранилище: " + storedIntegral.RecordsCount);


                        result.Add((byte)storedImpulses.Value.PulseCount1);
                        result.Add((byte)storedImpulses.Value.PulseCount2);
                        result.Add((byte)storedImpulses.Value.PulseCount3);
                        result.Add((byte)storedImpulses.Value.Status);
                        result.Add((byte)((storedImpulses.Value.StatusX & 0xF0) >> 8));
                        result.Add((byte)(storedImpulses.Value.StatusX & 0x0F));
                        result.Add((byte)(storedImpulses.Value.IsRecordCorrect ? 0x01 : 0x00));

                        var channel = result[0];
                        var number  = result[2];
                        result.Add(number);
                        result.Add(0);
                        result.Add(channel);
                        result.Add(0);

                        NamedLog("Упаковка получасовых данных завершена");
                    }
                    catch (Exception ex) {
                        NamedLog("Будет отправлена пустая посылка, т.к. произошло исключение во время составления ответа на получас: " + ex);
                    }
                    finally {
                        callback(null, result);
                    }
                }
                else
                {
                    NamedLog("Такая шестерка не поддерживается, будет отправлена пустая посылка");
                    callback(null, result);
                }
            }
            else
            {
                throw new Exception("Такая команда не поддерживается объектом БУМИЗ");
            }
        }
コード例 #2
0
        private void AsyncRecurseArchiveReadMethod(string objName, WaitableCounter sharedTasksCounter)
        {
            Log.Log("Рекурсивное чтение архивов для " + objName);
            var      nowTime   = DateTime.Now;
            DateTime?timeToGet = _storage.GetFirstMissedTimeUpToTime(objName, nowTime);

            if (timeToGet.HasValue)
            {
                var time = timeToGet.Value;
                var cmd  = new ReadArchiveRecordServiceCommand(time);
                Log.Log("Есть архивы, которые нужно вычитать. Имя объекта=" + objName + "   Команда=<" + cmd.Comment + ">   Время=" + cmd.RequestedTime.ToSimpleString() + " Арх.№=" + cmd.RecordNumber);

                sharedTasksCounter.IncrementCount();
                _bumizIoManager.SendDataAsync(objName, cmd, result => {
                    try {
                        Log.Log("Асинхронный запрос к сети БУМИЗ выполнен для объекта " + objName);
                        if (result != null)
                        {
                            if (result.ChannelException == null)
                            {
                                Log.Log(result.Bytes.ToText() + " <= для времени = " + time.ToSimpleString() + " Арх.№=" + cmd.RecordNumber);
                                try {
                                    var ctResult = cmd.GetResult(result.Bytes);
                                    Log.Log(ctResult.ToString());
                                    if (ctResult.RecordTime.Date == time.Date)
                                    {
                                        Log.Log("Даты совпадают, сохраняем данные в хранилище");
                                        _storage.SaveData(objName, time, true, ctResult.Count1, ctResult.Count2, ctResult.Count3, ctResult.Status, ctResult.Xstatus);
                                    }
                                    else
                                    {
                                        throw new Exception("Дата внутри архива не совпадает с датой запроса");
                                    }
                                }
                                catch (Exception ex) {
                                    Log.Log("Ошибка обработки ответа БУМИЗ, в хранилище будет записана информация о плохой записи архива");
                                    Log.Log("Причина - исключение: " + ex.ToString());
                                    _storage.SaveData(objName, time, false, 0, 0, 0, 0, 0);
                                }
                                finally {
                                    AsyncRecurseArchiveReadMethod(objName, sharedTasksCounter);
                                }
                            }
                            else
                            {
                                Log.Log("Ошибка канала передачи данных: " + result.ChannelException.ToString());
                                Log.Log("Объект " + objName + " больше не будет опрашиваться в этой итерации (пока все остальные не закончат свои обмены)");
                                // Получается, что при ошибке передачи данных следующий запрос не будет осуществлен, и объект выпадает из цикла опроса, пока другие объекты не закончат свои работы
                            }
                        }
                        else
                        {
                            Log.Log("Результат выполнения операции не существует, странно :О");
                        }
                    }
                    catch (Exception ex) {
                        Log.Log("Произошла ошибка при разборе ответа от объекта " + objName);
                        Log.Log(ex.ToString());
                        // TODO: что делать при ошибке чтения данных (нет связи с FRAM)?
                    }
                    finally {
                        Log.Log("Декремент счетчика задач сети БУМИЗ для объекта " + objName);
                        sharedTasksCounter.DecrementCount();
                    }
                }, IoPriority.Low);
            }
            else
            {
                Log.Log("Либо ошибка хранилища, либо для объекта " + objName + " все данные вычитаны");
            }
        }
コード例 #3
0
        private void SyncTimeFunc()
        {
            var getTimeCmd        = new GetCounterTimeCommand();
            var wrappedGetTimeCmd = new WrappedCounterCommand(getTimeCmd);

            var setTimeCmd        = new SetCounterTimeToCurrentCommand(TimeSpan.FromSeconds(5.0));
            var wrappedSetTimeCmd = new WrappedCounterCommand(setTimeCmd);

            while (true)
            {
                var waiter = new AutoResetEvent(false);

                // TODO: данный алгоритм не поддерживает возможности параллельной работы по нескольким каналам одновременно (все объекты синхронизируются последовательно)
                // TODO: чтобы включить таковую поддержку, нужно создать threadWorker для отправки команд
                // TODO: но тогда теряется выполнение в реальном времени (то есть, грубо говоря, время будет устанавливаться не точно, если в очереди с высоким приоритетом 100500 команд)
                // TODO: т.к. DateTime для установки задается во время добавления команды в очередь, а не во время извлечения
                // TODO: решение: можно написать команду, которая будет подставлять то текущее время на момент распаковки! SetCounterTimeCurrentCommand - написал SetCounterTimeToCurrentCommand
                foreach (var bumizName in _bumizNames)
                {
                    var objectName = bumizName;
                    //var obj = info.Item1;
                    //var channel = info.Item2;

                    bool canSyncTime = false;

                    _bumizIoManager.SendDataAsync(objectName,
                                                  //channel.SendInteleconCommandAsync(
                                                  wrappedGetTimeCmd, result => {
                        try {
                            if (result.ChannelException == null)
                            {
                                var counterReply = result.Bytes.GetDataBytesFromCounterReply();
                                Log.Log("Получены байты:" + counterReply.ToText());
                                var curControllerTime = getTimeCmd.GetResult(counterReply);
                                var currentTime       = DateTime.Now;
                                canSyncTime           = CanSafeAndReallyNeedTimeSync(curControllerTime, currentTime);
                                Log.Log("Время контроллера " + objectName + ": " + curControllerTime.ToString("yyyy.MM.dd-HH:mm:ss") + (canSyncTime ? " будет произведена синхронизация" : " синхронизация не требуется или невозможна в автоматическом режиме"));
                            }
                            else
                            {
                                throw result.ChannelException;
                            }
                        }
                        catch (Exception ex) {
                            Log.Log("Ошибка при обработке ответа команды получения времени контроллера: " + ex);
                        }
                        finally {
                            waiter.Set();                              // в любом случае нужно продолжить алгоритм
                        }
                    }, IoPriority.Lowest);                             // тут высокий приоритет не нужен, главное, чтобы команда установки времени выполнилась быстро (чтобы успеть во временное окно)

                    Log.Log("Ждем результатов чтения времени объекта " + objectName + " ...");
                    waiter.WaitOne();

                    if (canSyncTime)
                    {
                        _bumizIoManager.SendDataAsync(objectName,
                                                      //channel.SendInteleconCommandAsync(
                                                      wrappedSetTimeCmd, result => {
                            try {
                                if (result.ChannelException == null)
                                {
                                    Log.Log("Синхронизация прошла успешно для объекта " + objectName);
                                }
                                else
                                {
                                    throw result.ChannelException;
                                }
                            }
                            catch (Exception ex) {
                                Log.Log("Ошибка при обработке ответа команды установки времени контроллера: " + ex);
                            }
                            finally {
                                waiter.Set();                                         // finally waited ok
                            }
                        }, IoPriority.Highest);
                        waiter.WaitOne();
                    }

                    Thread.Sleep(300000);
                }

                Thread.Sleep(10000);
            }
        }