예제 #1
0
        private void DispatchCommandTask(DeviceBase device, Command cCommand)
        {
            // invoke device
            DeviceCommandResult result;

            try
            {
                var command = new DeviceCommand(cCommand.Name.Trim(),
                                                cCommand.Parameters == null ? null : cCommand.Parameters.DeepClone(),
                                                cCommand.UserId);
                result = device.HandleCommand(command, _cancellationSource.Token);
            }
            catch (OperationCanceledException)
            {
                return;
            }
            catch (Exception ex)
            {
                // operation faulted - log the error and send failed result
                Logger.Error(string.Format("Exception while handling a command '{0}' by device {1} ({2})", cCommand.Name, device.ID, device.Name), ex);
                result = new DeviceCommandResult("Failed", "An error occurred while handling the command");
            }

            // send command result
            cCommand.Status = result.Status;
            cCommand.Result = result.Result == null ? null : JToken.FromObject(result.Result, device.JsonSerializer);
            SendCommandResult(device, cCommand);
        }
예제 #2
0
        /// <summary>
        /// Sends a notification on behalf of the specified device.
        /// </summary>
        /// <param name="sender">Sender <see cref="DeviceBase"/> object.</param>
        /// <param name="notification"><see cref="DeviceNotification"/> object to send.</param>
        public void SendNotification(DeviceBase sender, DeviceNotification notification)
        {
            if (sender == null)
            {
                throw new ArgumentNullException("sender");
            }
            if (notification == null)
            {
                throw new ArgumentNullException("notification");
            }

            Logger.InfoFormat("Sending notification '{0}' from device {1} ({2})", notification.Name, sender.ID, sender.Name);

            try
            {
                var cNotification = new Notification(notification.Name.Trim(),
                                                     notification.Parameters == null ? null : notification.Parameters.DeepClone());
                DeviceClient.SendNotification(sender.ID, sender.Key, cNotification);
            }
            catch (Exception ex)
            {
                // critical error - log and fault the service
                Logger.Error(string.Format("Exception while sending notification '{0}' from device {1} ({2})", notification.Name, sender.ID, sender.Name), ex);
                throw;
            }
        }
예제 #3
0
        /// <summary>
        /// Sends a device status update.
        /// </summary>
        /// <param name="sender">Sender <see cref="DeviceBase"/> object.</param>
        /// <param name="status">New device status.</param>
        public void SendStatusUpdate(DeviceBase sender, string status)
        {
            if (sender == null)
            {
                throw new ArgumentNullException("sender");
            }
            if (string.IsNullOrEmpty(status))
            {
                throw new ArgumentException("Status is null or empty!", "status");
            }

            Logger.InfoFormat("Updating device {1} ({2}) status to '{0}'", status, sender.ID, sender.Name);

            try
            {
                var cDevice = new Device(sender.ID, sender.Key)
                {
                    Status = status
                };
                DeviceClient.UpdateDevice(cDevice);
            }
            catch (Exception ex)
            {
                // critical error - log and fault the service
                Logger.Error(string.Format("Exception while updating device {1} ({2}) status to '{0}'", status, sender.ID, sender.Name), ex);
                throw;
            }
        }
예제 #4
0
        /// <summary>
        /// Adds new device to the host.
        /// </summary>
        /// <param name="device"><see cref="DeviceBase"/> object to add.</param>
        public void AddDevice(DeviceBase device)
        {
            if (device == null)
                throw new ArgumentNullException("device");

            device.Initialize(new DeviceServiceChannel(this, device));
            _devices.Add(device);
        }
예제 #5
0
        private void SendCommandResult(DeviceBase device, Command cCommand)
        {
            Logger.InfoFormat("Sending command '{0}' status '{1}' from device {2} ({3})",
                              cCommand.Name, cCommand.Status, device.ID, device.Name);

            try
            {
                DeviceClient.UpdateCommand(device.ID, device.Key, cCommand);
            }
            catch (Exception ex)
            {
                // not critical - do nothing
                Logger.Error(string.Format("Exception while sending command '{0}' status '{1}' from device {2} ({3})",
                                           cCommand.Name, cCommand.Status, device.ID, device.Name), ex);
            }
        }
예제 #6
0
        private void MainDeviceTask(DeviceBase device)
        {
            var token = _cancellationSource.Token;

            try
            {
                device.Main(token);
            }
            catch (OperationCanceledException)
            {
                return;
            }
            catch (Exception ex)
            {
                // operation faulted - log the error and stop the task
                Logger.Error(string.Format("Exception in main thread of device {0} ({1})", device.ID, device.Name), ex);
                throw;
            }
        }
예제 #7
0
        private void RegisterDevice(DeviceBase device)
        {
            Logger.InfoFormat("Registering device {0} ({1})", device.ID, device.Name);

            try
            {
                var cDeviceClass = new DeviceClass(device.ClassName, device.ClassVersion, device.ClassOfflineTimeout,
                                                   device.ClassData == null ? null : JToken.FromObject(device.ClassData, device.JsonSerializer));
                var cDevice = new Device(device.ID, device.Key, device.Name, device.Status,
                                         device.Data == null ? null : JToken.FromObject(device.Data, device.JsonSerializer), Network, cDeviceClass);
                cDevice.Equipment = device.EquipmentInfo.Select(e => new Equipment(
                                                                    e.Name, e.Code, e.Type, e.Data == null ? null : JToken.FromObject(e.Data, device.JsonSerializer))).ToList();
                DeviceClient.RegisterDevice(cDevice);
            }
            catch (Exception ex)
            {
                // critical error - log and fault the service
                Logger.Error(string.Format("Exception while registering device {0} ({1}), rethrowing exception", device.ID, device.Name), ex);
                throw;
            }
        }
예제 #8
0
        private void SubscribeToCommands(DeviceBase device)
        {
            Logger.InfoFormat("Subscribe to device {0} ({1}) commands", device.ID, device.Name);
            if (device.ListenCommands)
            {
                while (true)
                {
                    try
                    {
                        DeviceClient.SubscribeToCommands(device.ID, device.Key);
                        break;
                    }
                    catch (DeviceServiceException e)
                    {
                        Logger.ErrorFormat("Error when subscribing to device {0} ({1}) commands: {2}",
                                           device.ID, device.Name, e);

                        // retry with small wait
                        Thread.Sleep(100);
                    }
                }
            }
        }
예제 #9
0
        /// <summary>
        /// Sends a device status update.
        /// </summary>
        /// <param name="sender">Sender <see cref="DeviceBase"/> object.</param>
        /// <param name="status">New device status.</param>
        public void SendStatusUpdate(DeviceBase sender, string status)
        {
            if (sender == null)
                throw new ArgumentNullException("sender");
            if (string.IsNullOrEmpty(status))
                throw new ArgumentException("Status is null or empty!", "status");

            Logger.InfoFormat("Updating device {1} ({2}) status to '{0}'", status, sender.ID, sender.Name);

            try
            {
                var cDevice = new Device(sender.ID, sender.Key) { Status = status };
                DeviceClient.UpdateDevice(cDevice);
            }
            catch (Exception ex)
            {
                // critical error - log and fault the service
                Logger.Error(string.Format("Exception while updating device {1} ({2}) status to '{0}'", status, sender.ID, sender.Name), ex);
                throw;
            }
        }
예제 #10
0
 public DeviceServiceChannel(DeviceHost host, DeviceBase device)
 {
     _host = host;
     _device = device;
 }
예제 #11
0
        private void SendCommandResult(DeviceBase device, Command cCommand)
        {
            Logger.InfoFormat("Sending command '{0}' status '{1}' from device {2} ({3})",
                cCommand.Name, cCommand.Status, device.ID, device.Name);

            try
            {
                DeviceClient.UpdateCommand(device.ID, device.Key, cCommand);
            }
            catch (Exception ex)
            {
                // not critical - do nothing
                Logger.Error(string.Format("Exception while sending command '{0}' status '{1}' from device {2} ({3})",
                    cCommand.Name, cCommand.Status, device.ID, device.Name), ex);
            }
        }
예제 #12
0
 private void DispatchCommandTask(DeviceBase device, Command cCommand)
 {
     // invoke device
     DeviceCommandResult result;
     try
     {
         var command = new DeviceCommand(cCommand.Name.Trim(),
             cCommand.Parameters == null ? null : cCommand.Parameters.DeepClone(),
             cCommand.UserId);
         result = device.HandleCommand(command, _cancellationSource.Token);
     }
     catch (OperationCanceledException)
     {
         return;
     }
     catch (Exception ex)
     {
         // operation faulted - log the error and send failed result
         Logger.Error(string.Format("Exception while handling a command '{0}' by device {1} ({2})", cCommand.Name, device.ID, device.Name), ex);
         result = new DeviceCommandResult("Failed", "An error occurred while handling the command");
     }
             
     // send command result
     cCommand.Status = result.Status;
     cCommand.Result = result.Result == null ? null : JToken.FromObject(result.Result, device.JsonSerializer);
     SendCommandResult(device, cCommand);
 }
예제 #13
0
 private void MainDeviceTask(DeviceBase device)
 {
     var token = _cancellationSource.Token;
     try
     {
         device.Main(token);
     }
     catch (OperationCanceledException)
     {
         return;
     }
     catch (Exception ex)
     {
         // operation faulted - log the error and stop the task
         Logger.Error(string.Format("Exception in main thread of device {0} ({1})", device.ID, device.Name), ex);
         throw;
     }
 }
예제 #14
0
        private void RegisterDevice(DeviceBase device)
        {
            Logger.InfoFormat("Registering device {0} ({1})", device.ID, device.Name);

            try
            {
                var cDeviceClass = new DeviceClass(device.ClassName, device.ClassVersion, device.ClassOfflineTimeout,
                    device.ClassData == null ? null : JToken.FromObject(device.ClassData, device.JsonSerializer));
                var cDevice = new Device(device.ID, device.Key, device.Name, device.Status,
                    device.Data == null ? null : JToken.FromObject(device.Data, device.JsonSerializer), Network, cDeviceClass);
                cDevice.Equipment = device.EquipmentInfo.Select(e => new Equipment(
                    e.Name, e.Code, e.Type, e.Data == null ? null : JToken.FromObject(e.Data, device.JsonSerializer))).ToList();
                DeviceClient.RegisterDevice(cDevice);
            }
            catch (Exception ex)
            {
                // critical error - log and fault the service
                Logger.Error(string.Format("Exception while registering device {0} ({1}), rethrowing exception", device.ID, device.Name), ex);
                throw;
            }
        }
예제 #15
0
        private void SubscribeToCommands(DeviceBase device)
        {
            Logger.InfoFormat("Subscribe to device {0} ({1}) commands", device.ID, device.Name);
            if (device.ListenCommands)
            {
                while (true)
                {
                    try
                    {
                        DeviceClient.SubscribeToCommands(device.ID, device.Key);
                        break;
                    }
                    catch (DeviceServiceException e)
                    {
                        Logger.ErrorFormat("Error when subscribing to device {0} ({1}) commands: {2}",
                            device.ID, device.Name, e);

                        // retry with small wait
                        Thread.Sleep(100);
                    }
                }
            }
        }
예제 #16
0
        /// <summary>
        /// Sends a notification on behalf of the specified device.
        /// </summary>
        /// <param name="sender">Sender <see cref="DeviceBase"/> object.</param>
        /// <param name="notification"><see cref="DeviceNotification"/> object to send.</param>
        public void SendNotification(DeviceBase sender, DeviceNotification notification)
        {
            if (sender == null)
                throw new ArgumentNullException("sender");
            if (notification == null)
                throw new ArgumentNullException("notification");

            Logger.InfoFormat("Sending notification '{0}' from device {1} ({2})", notification.Name, sender.ID, sender.Name);

            try
            {
                var cNotification = new Notification(notification.Name.Trim(),
                    notification.Parameters == null ? null : notification.Parameters.DeepClone());
                DeviceClient.SendNotification(sender.ID, sender.Key, cNotification);
            }
            catch (Exception ex)
            {
                // critical error - log and fault the service
                Logger.Error(string.Format("Exception while sending notification '{0}' from device {1} ({2})", notification.Name, sender.ID, sender.Name), ex);
                throw;
            }
        }
예제 #17
0
        private void PollCommandsTask(DeviceBase device)
        {
            var timestamp = DateTime.UtcNow;
            var token = _cancellationSource.Token;
            while (true)
            {
                // poll commands
                List<Command> cCommands;
                try
                {
                    cCommands = DeviceClient.PollCommands(device.ID, device.Key, timestamp, token);
                }
                catch (OperationCanceledException)
                {
                    return;
                }
                catch (Exception ex)
                {
                    // not critical - will retry
                    Logger.Error(string.Format("Exception while polling commands for device {0} ({1})", device.ID, device.Name), ex);
                    token.WaitHandle.WaitOne(1000);
                    continue;
                }

                // dispatch comands to device
                timestamp = cCommands.Max(c => c.Timestamp.Value);
                foreach (var cCommand in cCommands)
                {
                    Logger.InfoFormat("Dispatching command '{0}' to device {1} ({2})", cCommand.Name, device.ID, device.Name);

                    var cCommandCopy = cCommand;
                    _tasks.Add(Task.Factory.StartNew(() => DispatchCommandTask(device, cCommandCopy), token));
                }
            }
        }