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); }
/// <summary> /// Handles incoming device command, override to implement custom logic. /// Default implementation uses reflection to execute action method with matching <see cref="DeviceCommandAttribute"/> attribute. /// </summary> /// <param name="command"><see cref="DeviceCommand"/> object to handle.</param> /// <param name="token">Thread cancellation token.</param> /// <returns><see cref="DeviceCommandResult"/> object with command execution result.</returns> public virtual DeviceCommandResult HandleCommand(DeviceCommand command, CancellationToken token) { MethodInfo method; if (_deviceCommands.TryGetValue(command.Name, out method)) { var commandType = method.GetParameters()[0].ParameterType; var parameters = commandType == typeof(DeviceCommand) ? command : (command.Parameters == null ? Activator.CreateInstance(commandType) : command.Parameters.ToObject(commandType, JsonSerializer)); return((DeviceCommandResult)method.Invoke(this, new object[] { parameters, token })); } return(OnHandleUnknownCommand(command, token)); }
/// <summary> /// Handles unknown device command, override to implement custom logic. /// Default implementation returns <see cref="DeviceCommandResult"/> object with "Failed" result. /// </summary> /// <param name="command"><see cref="DeviceCommand"/> object to handle.</param> /// <param name="token">Thread cancellation token.</param> /// <returns><see cref="DeviceCommandResult"/> object</returns> protected virtual DeviceCommandResult OnHandleUnknownCommand(DeviceCommand command, CancellationToken token) { return(new DeviceCommandResult("Failed", "There is no handler for this command")); }