Exemplo n.º 1
0
        /// <summary>
        /// 
        /// </summary>
        public override void HandleOutcomingMessages()
        {
            DeviceContext device;
            String msg;
            DateTime time;
            Frame request;
            Transaction transaction;

            // 1. Проверяем статус устройства: 
            //  1.1 Если устройство находится в состоянии Operational, ничего не делаем
            //  1.2 Если устройство находится в состоянии CommunicationError, ничего не делаем
            //  1.3 Если устройство находится в состоянии ConfigurationError, ничего не делаем
            //  1.4 Если устройства находится в состоянии Stopped, ничего не делаем
            //  1.5 Если устройство находится в состоянии Pre-operational, отправляем команду 
            //      перевода устройства в состояние Operational
            //     1.5.1 Проверяем 

            // Сервис не работает
            if (_Status != Status.Running)
            {
                return;
            }

            // Получаем устройство
            _Context.Next();
            device = _Context.CurrentDevice;

            // Проверяем статус
            if (device.Device.Status == DeviceStatus.Preoperational)
            {
                if (device.CurrentTransaction != null)
                {
                    switch (device.CurrentTransaction.Status)
                    {
                        case TransactionStatus.Running:
                            {
                                // Запрос был уже отправлен. Проверяем таймаут
                                time = device.CurrentTransaction.TimeOfStart;
                                time = time.AddSeconds(device.Device.PollingInterval);

                                if (time < DateTime.Now)
                                {
                                    msg = String.Format("Service NMT: Timeout - устройство" +
                                        "не перешло в режим Operational за заданное время");
                                    // Устройство не перешло из состояние Pre-Operational 
                                    // за заданное время. Устанавливаем статус неудачной попытки
                                    device.CurrentTransaction.Abort(null, msg);
                                }
                                break;
                            }
                        case TransactionStatus.NotInitialized:
                        case TransactionStatus.Completed:
                            {
                                // Устройство перешло в состояние Operational - транзакция выполнена
                                // Однако, по какой-то причине устройство перешло в состояние Pre-Operational
                                // Переводим устройство в состояние Operational
                                request = new Frame();
                                request.Identifier = 0;
                                request.FrameFormat = FrameFormat.StandardFrame;
                                request.FrameType = FrameType.DATAFRAME;
                                request.Data = new Byte[] { 
                                    (Byte)StatusCode.Operational, // Поле комадны
                                    device.Device.NodeId // Поле Node ID
                                    };
                                transaction = new Transaction();
                                transaction.Start(TransactionType.BroadcastMode, request);
                                lock (_SyncRoot)
                                {
                                    _NetworkController.SendMessageToCanPort(
                                        transaction.Request.Value);
                                }
                                break;
                            }
                        case TransactionStatus.Aborted:
                            {
                                // Проверяем количество неудачных попыток и если оно
                                // достигло предела не отсылаем устройству больше запросов
                                if (device.ErrorCount < TotalAttempts)
                                {
                                    // Повторяем запрос
                                    device.CurrentTransaction.Repeat();
                                    lock (_SyncRoot)
                                    {
                                        _NetworkController.SendMessageToCanPort(
                                            device.CurrentTransaction.Request.Value);
                                    }
                                }
                                break;
                            }
                        default:
                            {
                                msg = String.Format(
                                    "Network {0}: ServiceNmt - Обнаружен статус запроса {1} не поддерживаемый " +
                                    "в данной версии ПО", _NetworkController.Description,
                                    device.CurrentTransaction.Status);
                                throw new Exception(msg);
                            }
                    }
                }
                else
                {
                    // Отправляем команду для перевода устройства в состояние Operational
                    request = new Frame();
                    request.Identifier = 0;
                    request.FrameFormat = FrameFormat.StandardFrame;
                    request.FrameType = FrameType.DATAFRAME;
                    request.Data = new Byte[] { 
                        (Byte)StatusCode.Operational, // Поле комадны
                        device.Device.NodeId // Поле Node ID
                    };
                    device.CurrentTransaction = new Transaction();
                    device.CurrentTransaction.Start(TransactionType.UnicastMode, request);
                    lock (_SyncRoot)
                    {
                        _NetworkController.SendMessageToCanPort(
                            device.CurrentTransaction.Request.Value);
                    }
                }
            }
            else
            {
                // Oбратная связь возникает через сервис NodeGuard, 
                // который отслеживает состояние устройства. И только он может установить, что
                // устройство перешло режим Operational и устанавливает статус устройству.
                // По этому, проверяем состояние транзакции и если транзакция активна
                // и устройство изменило статус, то считаем что команда дошла до устройства
                // и завершаем транзакцию.
                if ((device.CurrentTransaction != null) && 
                    (device.CurrentTransaction.IsRunning))
                {
                    // Т.к сервис не получает ответа, останавливаем транзакцию
                    // при помощи пустого фрайма (псевноответа)
                    device.CurrentTransaction.Stop(new Frame());
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Выполняет запрос к удалённому устройству 
        /// (переберая устройства и объекты словаря)
        /// </summary>
        public override void  HandleOutcomingMessages()
        {
            DeviceContext device;
            //ObjectInfo objInfo;

            // Сервис не работает
            if (_Status != Status.Running)
            {
                return;
            }

            if (_Context.Count == 0)
            {
                return;
            }
            // Устанавливаем следующее по списку устройство для обработки
            _Context.Next();
            // Получаем устройство для обработки
            device = _Context.CurrentDevice;

            // Если устройство активно, выполняем запрос
            lock (_SyncRoot)
            {
                if ((device.Device.Status == DeviceStatus.Operational) ||
                    (device.Device.Status == DeviceStatus.Preoperational) ||
                    (device.Device.Status == DeviceStatus.Stopped))
                {
                    if (device.CurrentTransaction == null)
                    {
                        device.CurrentTransaction = new Transaction();
                    }
                    // Проверяем, что последнй запрос (транзакция) к устройству выполнена
                    // Если это так, начинаем новую, в противном случае ничего неделаем (ждём окончания транзакции)
                    if (device.CurrentTransaction.IsRunning)
                    {
                        // Транзакция активна проверяем длительность транзакции
                        if (device.CurrentTransaction.TimeOfStart.AddSeconds(
                            device.Device.PollingInterval) <= DateTime.Now)
                        {
                            // Таймаут на запрос
                            device.CurrentTransaction.Abort(null, "Request timeout");
                            // Пишем в лог...
                        }
                        return;
                    }
                    else
                    {
                        // Если запрос был успешным или неудачным, выжадаем требуемое время
                        // для нового запроса
                        if ((device.CurrentTransaction.Status == TransactionStatus.Aborted) ||
                            (device.CurrentTransaction.Status == TransactionStatus.Completed))
                        {
                            if (device.CurrentTransaction.TimeOfStart.AddSeconds(
                                device.Device.PollingInterval) > DateTime.Now)
                            {
                                return;
                            }
                        }

                        if (device.CurrentTransaction.Status == TransactionStatus.Aborted)
                        {
                            if (device.ErrorCount < TotalAttempts)
                            {
                                // Повторяем запрос
                                device.CurrentTransaction.Repeat();
                                // Отправляем сообщение к устройству
                                _NetworkController.SendMessageToCanPort(
                                    device.CurrentTransaction.Request.Value);
                                return;
                            }
                            else
                            {
                                device.CurrentTransaction = null;
                            }
                        }

                        //Получаем следующий объект словаря для обработки 
                        device.Next();

                        if (!device.CurrentObject.SdoCanRead)
                        {
                            // Данный объект не обрабатывается сервисом SDO
                            return;
                        }
                        Transaction trans = new Transaction();

                        Frame message = new Frame();
                        message.Identifier = System.Convert.ToUInt32(0x600 +
                            device.Device.NodeId);
                        message.FrameFormat = FrameFormat.StandardFrame;
                        message.FrameType = FrameType.DATAFRAME;
                        message.Data = new Byte[8];
                        message.Data[0] = 0x40;
                        message.Data[1] = (byte)device.CurrentObject.Index;
                        message.Data[2] = (byte)(device.CurrentObject.Index >> 8);
                        device.CurrentTransaction = trans;
                        trans.Start(TransactionType.UnicastMode, message);
                    }
                    // Отправляем сообщение к устройству
                    _NetworkController.SendMessageToCanPort(
                        device.CurrentTransaction.Request.Value);
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Конструктор для сериализации
        /// </summary>
        /// <param name="info"></param>
        /// <param name="context"></param>
        //public ServicePdoReceive(SerializationInfo info, StreamingContext context)
        //    : base(info, context)
        //{
        //    _SynchronizationPeriod = info.GetInt32("Interval");
        //    _LastTimeSynchronisation = DateTime.Now;
        //}
        #endregion

        #region Methods
        /// <summary>
        /// 
        /// </summary>
        public override void HandleOutcomingMessages()
        {
            //String msg;
            Frame message;

            if (Status != Status.Running)
            {
                return;
            }

            // 1. Один раз в период опроса (равен периoду) опрашиваем состояние устройства. 
            // Получаем время последнего опроса устройства. Прибавляем к нему время прериода синхронизации времени
            // и сравниваем с текущим временем. Если полученное время меньше текущего, то выполняем синхронизацию.

            if (_LastTransaction != null)
            {
                TimeSpan interval = DateTime.Now - _LastTransaction.TimeOfEnd;

                if (interval.Seconds < Interval)
                {
                    return;
                }
            }
            
            _LastTransaction = new Transaction();
            
            // Формируем и записываем запрос в выходной буфер
            message = new Frame();
            message.Identifier = 0x200;
            message.FrameFormat = FrameFormat.StandardFrame;
            message.FrameType = FrameType.DATAFRAME;
            message.Data = new Byte[4];
            // Получаем текущее время в формате UNIX
            UInt32 unixTime = Unix.ToUnixTime(DateTime.Now);
            unchecked
            {
                message.Data[0] = (Byte)unixTime; // Младший байт
                message.Data[1] = (Byte)(unixTime >> 8);
                message.Data[2] = (Byte)(unixTime >> 16);
                message.Data[3] = (Byte)(unixTime >> 24); // Старший байт
            }
            
            _LastTransaction.Start(TransactionType.BroadcastMode, message);
            _NetworkController.SendMessageToCanPort(_LastTransaction.Request.Value);
            _LastTransaction.Stop(null);

            //Debug.WriteLine(String.Format("Время последней синхронизации времени: {0}",
            //    now.ToString(new System.Globalization.CultureInfo("ru-Ru", false))));
        }