コード例 #1
0
        public void Start()
        {
            if (_isServiceRunning || _workingThread.IsAlive)
            {
                return;
            }

            _isServiceRunning = true;
            _runWorkingThread = true;

            _workingThread = new Thread(() =>
            {
                _outboundEventBus.Send(new DeviceStatusUpdatedEvent("Telemetry service was started",
                                                                    DeviceStatusCode.ServiceStarted));
                while (_runWorkingThread)
                {
                    _outboundEventBus.Send(new WindowsControllerTelemetryEvent(new [] { _window1ReedSwitch.GetState().ToBool(), _window2ReedSwitch.GetState().ToBool() }));
                    Thread.Sleep(_sentInterval);
                }

                _outboundEventBus.Send(new DeviceStatusUpdatedEvent("Telemetry service was stopped",
                                                                    DeviceStatusCode.ServiceStopped));
                _isServiceRunning = false;
            });

            _workingThread.Start();
        }
コード例 #2
0
        private void OpenWindowAsync(ushort windowId)
        {
            lock (this)
            {
                _workerThreads[windowId] = new Thread(() =>
                {
                    _windowActuators[windowId].StartMovingExtensionDirection();
                    Logger.Log($"Start openning window {windowId}");

                    for (int i = 0; i <= ACTUATOR_WORK_TIMEOUT; i += 500)
                    {
                        Thread.Sleep(500);
                        if (_workerThreads[windowId] != Thread.CurrentThread)
                        {
                            Logger.Log($"Openning window {windowId} aborted.");
                            return;
                        }
                    }

                    _windowActuators[windowId].StopMoving();
                    if (_windowStates[windowId] == SwitchState.Closed)
                    {
                        _outboundEventBus.Send(new ErrorEvent($"Window actuator mechanism critical failure. Window with id {windowId} is still closed.", ErrorLevel.Critical));
                    }
                    Logger.Log($"Openning window {windowId} finished.");
                });

                _workerThreads[windowId].Start();
            }
        }
コード例 #3
0
        public InboundMessagesHandler(MqttClientWrapper mqttClient, ICommandBus commandBus,
                                      ICommandsFactory commandsFactory, IOutboundEventBus outboundEventBus)
        {
            mqttClient.OnMqttMessageReceived += (_, args) =>
            {
                try
                {
                    var decodedMessage = DecodeMqttMessage(args);
                    var command        = commandsFactory.Create(decodedMessage.Name, decodedMessage.Payload);
                    var errors         = command.Validate();
                    if (errors.Length > 0)
                    {
                        outboundEventBus.Send(new CommandResultEvent(command.CorrelationId, StatusCode.ValidationError,
                                                                     command.GetType().Name, errors.SerializeToString()));
                        return;
                    }

                    commandBus.Send(command);
                }
                catch (Exception e)
                {
                    outboundEventBus.Send(new ErrorEvent(
                                              $"Exception during handling inbound message: {e.Message}", ErrorLevel.Warning));
                }
            };
        }
        public void Handle(ICommand command)
        {
            if (!_telemetryService.IsRunning())
            {
                _outboundEventBus.Send(new CommandResultEvent(command.CorrelationId, StatusCode.Refused,
                                                              nameof(StartTelemetryServiceCommand), "Telemetry service is already stopped"));
                return;
            }

            _telemetryService.Stop();
            _outboundEventBus.Send(new CommandResultEvent(command.CorrelationId, StatusCode.Success,
                                                          nameof(StartTelemetryServiceCommand)));
        }
コード例 #5
0
        public DoorService(IOutboundEventBus outboundEventBus, SwitchDriver doorReedSwitch)
        {
            _outboundEventBus = outboundEventBus;
            _doorReedSwitch   = doorReedSwitch;

            OnDoorOpened = (sender, e) =>
            {
                _outboundEventBus.Send(new DoorOpenedEvent());
            };
            OnDoorClosed = (sender, e) =>
            {
                _outboundEventBus.Send(new DoorClosedEvent());
            };
        }
コード例 #6
0
        public void Start()
        {
            if (_isServiceRunning || _workingThread.IsAlive)
            {
                return;
            }

            _isServiceRunning = true;
            _runWorkingThread = true;

            _workingThread = new Thread(() =>
            {
                StartMeasurements();
                _outboundEventBus.Send(new DeviceStatusUpdatedEvent("Telemetry service was started",
                                                                    DeviceStatusCode.ServiceStarted));
                while (_runWorkingThread)
                {
                    var measurementStartTime = DateTime.UtcNow;
                    Thread.Sleep(_sentInterval);
                    var measurementEndTime = DateTime.UtcNow;
                    var telemetryData      = GetTelemetryData(measurementStartTime, measurementEndTime);
                    ResetMeasurements();
                    _outboundEventBus.Send(telemetryData);
                }

                StopMeasurements();
                _outboundEventBus.Send(new DeviceStatusUpdatedEvent("Telemetry service was stopped",
                                                                    DeviceStatusCode.ServiceStopped));
                _isServiceRunning = false;
            });

            _workingThread.Start();
        }
コード例 #7
0
        public void Start()
        {
            if (_isRunning || _workingThread.IsAlive)
            {
                return;
            }

            _workingThread = new Thread(() =>
            {
                _runWorkingThread = _isRunning = true;

                while (_runWorkingThread)
                {
                    if (!_isConnectedToNetwork)
                    {
                        Thread.Sleep(1000);
                        continue;
                    }
                    _outboundEventBus.Send(GetDiagnosticDataEvent());
                    Thread.Sleep(_interval);
                }
            });

            _workingThread.Start();
        }
コード例 #8
0
        public void Start()
        {
            _commandBus.OnNewCommandPartitionKeyCreated += (_, commandPartitionKey) =>
            {
                new Thread(() =>
                {
                    while (true)
                    {
                        var command        = _commandBus.GetCommandQueue(commandPartitionKey).Dequeue() as ICommand;
                        string commandName = command.GetType().Name;

                        var commandExecutionThread = new Thread(() =>
                        {
                            try
                            {
                                _commandHandlersFactory.Get(commandName).Handle(command);
                            }
                            catch (Exception e)
                            {
                                _outboundEventBus.Send(new CommandResultEvent(command.CorrelationId, StatusCode.Error,
                                                                              commandName, e.Message));
                            }
                        });

                        commandExecutionThread.Start();
                        commandExecutionThread.Join(COMMAND_EXECUTION_TIMEOUT);

                        if (!commandExecutionThread.IsAlive)
                        {
                            continue;
                        }

                        commandExecutionThread.Abort(); //Try to force kill thread
                        _outboundEventBus.Send(new CommandResultEvent(command.CorrelationId, StatusCode.Error,
                                                                      commandName, $"Command {commandName} execution aborted due to timeout exceed"));
                    }
                }).Start();
            };
        }
コード例 #9
0
        private bool AddCommandToQueue(ICommand command)
        {
            if (!_commandQueues.Contains(command.PartitionKey))
            {
                return(false);
            }

            var commandQueue = _commandQueues[command.PartitionKey] as ConcurrentQueue;

            lock (_commandQueues)
            {
                if (commandQueue.Count > MAXIMUM_QUEUE_COUNT)
                {
                    var commandName = command.GetType().Name;
                    _outboundEventBus.Send(new CommandResultEvent(commandName, StatusCode.Refused,
                                                                  $"Command queue overflow for command {commandName}."));
                    return(true);
                }

                commandQueue?.Enqueue(command);
            }

            return(true);
        }
コード例 #10
0
 public void Handle(ICommand command)
 {
     _outboundEventBus.Send(_diagnosticService.GetDiagnosticDataEvent());
     _outboundEventBus.Send(new CommandResultEvent(command.CorrelationId, StatusCode.Success,
                                                   nameof(SendDiagnosticDataCommand)));
 }
コード例 #11
0
 private void Handle(IrrigateCommand command)
 {
     _irrigationService.StartIrrigation(command.MaximumIrrigationTime, command.WaterVolume);
     _outboundEventBus.Send(new CommandResultEvent(command.CorrelationId, StatusCode.Success, nameof(IrrigateCommand)));
 }
コード例 #12
0
 private void Handle(AbortIrrigationCommand command)
 {
     _irrigationService.FinishIrrigation();
     _outboundEventBus.Send(new CommandResultEvent(command.CorrelationId, StatusCode.Success, nameof(AbortIrrigationCommand)));
 }
コード例 #13
0
        public WindowsManagingService(LinearActuatorDriver window1Actuator,
                                      LinearActuatorDriver window2Actuator,
                                      SwitchDriver window1ReedSwitch,
                                      SwitchDriver window2ReedSwitch,
                                      SwitchDriver window1ControlSwitch,
                                      SwitchDriver window2ControlSwitch,
                                      IOutboundEventBus outboundEventBus)
        {
            _windowActuators       = new[] { window1Actuator, window2Actuator };
            _windowReedSwitches    = new[] { window1ReedSwitch, window2ReedSwitch };
            _windowControlSwitches = new[] { window1ControlSwitch, window2ControlSwitch };
            _windowStates          = new[] { window1ReedSwitch.GetState(), window2ReedSwitch.GetState() };
            _outboundEventBus      = outboundEventBus;

            OnWindow1Opened = (sender, e) =>
            {
                _windowStates[0] = SwitchState.Opened;
                _outboundEventBus.Send(new WindowOpenedEvent(0));
            };
            OnWindow1Closed = (sender, e) =>
            {
                _windowStates[0] = SwitchState.Closed;
                _windowActuators[0].StopMoving();
                _outboundEventBus.Send(new WindowClosedEvent(0));
            };

            OnWindow2Opened = (sender, e) =>
            {
                _windowStates[1] = SwitchState.Opened;
                _outboundEventBus.Send(new WindowOpenedEvent(1));
            };

            OnWindow2Closed = (sender, e) =>
            {
                _windowStates[1] = SwitchState.Closed;
                _windowActuators[1].StopMoving();
                _outboundEventBus.Send(new WindowClosedEvent(1));
            };

            //Control switches
            OnWindow1ControlSwitchOpened = (sender, e) => { OpenWindowAsync(0); };
            OnWindow1ControlSwitchClosed = (sender, e) =>
            {
                if (_windowStates[0] == SwitchState.Closed)
                {
                    return;
                }

                CloseWindowAsync(0);
            };

            OnWindow2ControlSwitchOpened = (sender, e) => { OpenWindowAsync(1); };

            OnWindow2ControlSwitchClosed = (sender, e) =>
            {
                if (_windowStates[1] == SwitchState.Closed)
                {
                    return;
                }

                CloseWindowAsync(1);
            };
        }
コード例 #14
0
 public void Handle(ICommand command)
 {
     _outboundEventBus.Send(new CommandResultEvent(command.CorrelationId, StatusCode.Success, nameof(PingCommand)));
 }
コード例 #15
0
 private void Handle(OpenWindowCommand command)
 {
     _windowsManagingService.OpenWindow(command.WindowId);
     _outboundEventBus.Send(new CommandResultEvent(command.CorrelationId, StatusCode.Success,
                                                   nameof(OpenWindowCommand)));
 }
コード例 #16
0
        public void StartIrrigation(int maximumIrrigationTime, int waterVolume)
        {
            if (_irrigationInProgress)
            {
                throw new Exception(
                          $"Irrigation process is running. Cannot start another process.");
            }

            if (!IsRunning())
            {
                throw new Exception(
                          $"Irrigation service is stopped. Cannot start irrigation");
            }

            lock (this)
            {
                _irrigationInProgress = true;
                _runWorkingThread     = true;
                _waterFlowSensorDriver.StartMeasurement(WaterFlowSensorMeasurementResolution.FiveSeconds);
                _irrigationStartTime = DateTime.UtcNow;
                _flowWatcherThread   = new Thread(() =>
                {
                    float previousTotalFlow = 0;
                    while (_runWorkingThread)
                    {
                        float totalFlow = _waterFlowSensorDriver.GetTotalFlow();
                        if (totalFlow <= previousTotalFlow)
                        {
                            FinishIrrigation();
                            _outboundEventBus.Send(new ErrorEvent(
                                                       "Irrigation process aborted because no water flow was detected. Irrigation system malfunction or no water in tank.",
                                                       ErrorLevel.Warning));
                            break;
                        }

                        if (totalFlow >= waterVolume)
                        {
                            FinishIrrigation();
                            break;
                        }

                        Thread.Sleep(10000);
                        if (_flowWatcherThread != Thread.CurrentThread)
                        {
                            break;
                        }
                    }
                });

                _workingThread = new Thread(() =>
                {
                    //Open valve and wait 5 seconds
                    _solidStateRelays.On(_relaySwitchValveChannel);
                    Thread.Sleep(5000);

                    //Start water pump and run water flow watcher thread after waiting 10 seconds
                    _solidStateRelays.On(_relaySwitchPumpChannel);
                    Thread.Sleep(10000);
                    _flowWatcherThread.Start();
                    Thread.Sleep(maximumIrrigationTime * 1000);
                    if (_flowWatcherThread != Thread.CurrentThread)
                    {
                        return;
                    }
                    if (!_runWorkingThread)
                    {
                        return;
                    }

                    FinishIrrigation();
                });

                _workingThread.Start();
            }
        }