private void ProcessNextCommand()
        {
            _processingCommand = true;
            PendingCommand pendingCommand = _pendingCommands.Dequeue();
            ICommand       command        =
                _commandFactory.Create(pendingCommand.commandType, pendingCommand.dataType, pendingCommand.data);

            if (command == null)
            {
                _logger.LogError(LoggedFeature.CommandSystem,
                                 "Command is not bound. Have you installed a separate Installer via CommandsInstaller.Install?");
                return;
            }

            IObservable <Unit> observable = command.Run();
            IObserver <Unit>   observer   = Observer.Create <Unit>(HandleCommandSuccess, HandleCommandError);

            observable.Subscribe(observer);

            // Notify listeners
            CommandSnapshot commandSnapshot =
                new CommandSnapshot(command,
                                    pendingCommand.data,
                                    _clock.Now,
                                    pendingCommand.source);

            foreach (var commandQueueListener in _listeners)
            {
                commandQueueListener.HandleCommandQueued(commandSnapshot);
            }
        }
Esempio n. 2
0
 void AddCommand(Id id, PendingCommand command)
 {
     if (!_commandsById.TryAdd(id, command))
     {
         throw new Exception($"Cannot reuse command identifier {id}");
     }
 }
Esempio n. 3
0
        private bool TextCommandCallback(ServerPlayer player, MsgMessage message)
        {
            if (player == null || message.MessageText == string.Empty || message.To != BZFlag.Data.Players.PlayerConstants.AllPlayersID || message.MessageType == MsgMessage.MessageTypes.ActionMessage)
            {
                return(false);
            }

            if (message.MessageText[0] == '/')
            {
                if (player.Allowances.AllowCommands)
                {
                    PendingCommand cmd = new PendingCommand();
                    cmd.Text   = message.MessageText;
                    cmd.Player = player;
                    lock (PendingCommands)
                    {
                        PendingCommands.Add(cmd);

                        if (Worker == null)
                        {
                            Worker = new Thread(new ThreadStart(ProcessCommands));
                            Worker.Start();
                        }
                    }
                }

                return(true);
            }

            return(false);
        }
 internal void RegisterPending(PendingCommand sender)
 {
     if (!ImmutableInterlocked.TryAdd(ref _pendingCommands, sender.Id, sender))
     {
         throw new InvalidOperationException($"Invalid command ID '{sender.Id}'. ID is already present.");
     }
 }
        // POST: api/PendingApp
        public async Task <IActionResult> PostAsync([FromBody] PendingCommand pendingCommand)
        {
            _context.Add(pendingCommand);
            await _context.SaveChangesAsync();

            return(Ok());
        }
Esempio n. 6
0
        /// <summary>
        /// Sends a command to the controller over serial,
        /// and waits for execution.
        /// </summary>
        /// <param name="command">The command to execute, including parameters.</param>
        /// <returns>The result.</returns>
        public async Task <bool> SendCommand(string command, bool waitForConfirmation = true)
        {
            logger.LogDebug(String.Format("Sending a command to the FMC serial interface: \"{0}\"", command));

            string commandGuid = Guid.NewGuid().ToString();
            await serialController.TryWriteString(command);

            serialController.CommandInProgress = true;

            if (!waitForConfirmation)
            {
                return(true);
            }

            pendingCommands.Add(commandGuid, new PendingCommand(commandGuid, command, DateTime.Now));

            while (true)
            {
                PendingCommand pendingCommand = pendingCommands[commandGuid];

                if (DateTime.Now >= pendingCommand.TimeSent.AddSeconds(30))
                {
                    // Command execution timed out
                    pendingCommands.Remove(commandGuid);

                    serialController.CommandInProgress = false;
                    logger.LogError("An command intended to run on the FMC timed out. This indicates an internal fault. The command was: " + pendingCommand.Command);
                    return(false);
                }

                if (pendingCommand.Confirmed = true && pendingCommand.Status != null)
                {
                    pendingCommands.Remove(commandGuid);

                    serialController.CommandInProgress = false;
                    if (pendingCommand.Status == "success")
                    {
                        logger.LogInformation("An command sent to the FMC succeeded. The command was: " + pendingCommand.Command);
                        return(true);
                    }
                    else if (pendingCommand.Status == "failure")
                    {
                        logger.LogError("The FMC reported command failure. The command was: " + pendingCommand.Command);
                        return(false);
                    }
                    else
                    {
                        throw new Exception("Malformed command status.");
                    }
                }
            }
        }
Esempio n. 7
0
        protected PendingCommand PopCommand()
        {
            lock (PendingCommands)
            {
                if (PendingCommands.Count == 0)
                {
                    return(null);
                }

                PendingCommand cmd = PendingCommands[0];
                PendingCommands.RemoveAt(0);
                return(cmd);
            }
        }
Esempio n. 8
0
        async Task <TResponse> WaitForResponse <TResponse>(Id id, IEnumerable <ICommandWhen <TResponse> > whens)
        {
            var command = new PendingCommand <TResponse>(whens);

            AddCommand(id, command);

            try
            {
                return(await command.Task);
            }
            finally
            {
                RemoveCommand(id);
            }
        }
            public async Task <PendingCommand> Send <TCommand>(TCommand command, CancellationToken ct)
                where TCommand : HomeAssistantCommand
            {
                if (await _state.FirstOrDefaultAsync(state => state == State.Connected) != State.Connected)
                {
                    throw new InvalidOperationException("Connection failed");
                }

                using (await _sendGate.LockAsync(ct))
                    using (var id = _commandIdProvider.GetNext())
                    {
                        var sender  = new PendingCommand(command, this, id, ct);
                        var payload = JsonSerializer.SerializeToUtf8Bytes(command, JsonWriteOpts);

                        await _client.SendAsync(new ArraySegment <byte>(payload), WebSocketMessageType.Text, true, ct);

                        return(sender);
                    }
            }
Esempio n. 10
0
 public void HandleCommand(PendingCommand Command)
 {
     try
     {
         var matchedCommand = Parser.ParseCommand(Command);
         if (matchedCommand != null)
         {
             Core.ProcessPlayerCommand(matchedCommand.Command, matchedCommand.Matches[0], Command.Actor);
         }
         else
         {
             MudObject.SendMessage(Command.Actor, "I do not understand.");
         }
     }
     catch (Exception e)
     {
         Core.ClearPendingMessages();
         MudObject.SendMessage(Command.Actor, e.Message);
     }
 }
Esempio n. 11
0
        protected virtual void ProcessCommands()
        {
            PendingCommand cmd = PopCommand();

            while (cmd != null)
            {
                string[] parts   = cmd.Text.Split(" ".ToCharArray(), 2);
                string   command = parts[0].Substring(1);

                string args = string.Empty;
                if (parts.Length == 2)
                {
                    args = parts[1];
                }

                Commands.CallHandler(command, args, cmd.Player);

                cmd = PopCommand();
            }

            lock (PendingCommands)
                Worker = null;
        }
 internal void UnRegisterPending(PendingCommand sender)
 {
     ImmutableInterlocked.TryRemove(ref _pendingCommands, sender.Id, out _);
 }
Esempio n. 13
0
 public void HandleCommand(PendingCommand Command)
 {
     Command.Actor.CommandHandler = ParentHandler;
     AuthenticatingCommand(Command.Actor, UserName, Command.RawCommand);
 }
Esempio n. 14
0
        /// <summary>
        /// Called when this CMC recieves a serial message.
        /// </summary>
        private Task SerialController_SerialRecieved(string text)
        {
            string[] split = text.Split("\n\r".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
            IList <IDictionary <string, dynamic> > statusResults = new List <IDictionary <string, dynamic> >();
            IList <PendingCommand> commandResults = new List <PendingCommand>();

            foreach (string line in split)
            {
                // Handle malformed serial output by the Arduino
                string _line = line;

                if (line == "{,\"command\":\"syncStatus\"}")
                {
                    continue;
                }

                string[] firstSplit = _line.Split("{\"status\":");
                if (firstSplit.Count() == 2)
                {
                    _line = "{\"status\":" + firstSplit[1];
                }

                IDictionary <string, dynamic> result = null;

                try
                {
                    result = JsonConvert.DeserializeObject <IDictionary <string, dynamic> >(_line);
                }
                catch (Exception e)
                {
                    logger.LogError(String.Format("Could not parse JSON from line with content \"{0}\". Content was malformed from the Arduino. The line will be ignored.", _line), e);
                    continue;
                }

                if (result.ContainsKey("status") && result.ContainsKey("command"))
                {
                    // Command result
                    IEnumerable <PendingCommand> pending = pendingCommands.Select(i => i.Value).Where(p => p.Command == result["command"]).OrderBy(p => p.TimeSent);

                    if (pending.Count() > 0)
                    {
                        PendingCommand command = pending.First();
                        if (command != null)
                        {
                            commandResults.Add(command);

                            pendingCommands[command.Guid].Confirmed = true;
                            pendingCommands[command.Guid].Status    = result["status"];
                        }
                    }
                }
                else if (result.ContainsKey("status"))
                {
                    statusResults.Add(result);

                    switch (result["status"])
                    {
                    case "system_ready":
                        FmcReady = true;
                        Task.Run(async() => { await FmcReadyEvent.Invoke(this); });
                        break;

                    case "tamper_detection_tripped":
                        break;

                    case "sensor_triggered":
                        break;

                    case "sensor_untriggered":
                        break;

                    case "alarm_activated_not_armed":
                        break;

                    case "alert":
                        Alarmed = true;
                        break;

                    case "syncStatus":
                        // Got a sync request-response from the FMC
                        if (result.ContainsKey("statusValues"))
                        {
                            IList <string> statusValues = ((JArray)result["statusValues"]).ToObject <IList <string> >();
                            foreach (string value in statusValues)
                            {
                                switch (value)
                                {
                                case "alarmed":
                                    Alarmed = true;
                                    break;

                                case "silenced":
                                    Alarmed = false;
                                    break;

                                case "armed":
                                    Armed = true;
                                    break;

                                case "disarmed":
                                    Armed = false;
                                    break;

                                case "override":
                                    Override = true;
                                    break;

                                case "no_override":
                                    Override = false;
                                    break;
                                }
                            }
                        }
                        break;
                    }
                }
            }

            return(Task.CompletedTask);
        }