Beispiel #1
0
        static async Task Main(string[] args)
        {
            var mongoHost     = Environment.GetEnvironmentVariable("MONGO_HOST") ?? "localhost";
            var interfaceHost = Environment.GetEnvironmentVariable("INTERFACE_HOST") ?? "localhost";

            //wait for mongo to be available
            await CheckMongoAvailibility(mongoHost);
            await CheckWebServerAvailibility(interfaceHost);

            FlurlHttp.Configure(settings => {
                var jsonSettings = new JsonSerializerSettings
                {
                    NullValueHandling      = NullValueHandling.Ignore,
                    ObjectCreationHandling = ObjectCreationHandling.Replace
                };
                settings.JsonSerializer = new NewtonsoftJsonSerializer(jsonSettings);
            });

            Thread.CurrentThread.CurrentCulture   = new System.Globalization.CultureInfo("en-US");
            Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
            Console.WriteLine("Starting daemon");
            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            var cancellationToken = cancellationTokenSource.Token;

            SerialThread serialThread = new SerialThread(mongoHost, interfaceHost);

            serialThread.PlayBeep();

            WebSocketThread  webSocketThread  = new WebSocketThread($"ws://{interfaceHost}:3001", serialThread);
            ProcessingThread processingThread = new ProcessingThread(serialThread, webSocketThread, mongoHost, interfaceHost);

            var serialPort = Environment.GetEnvironmentVariable("SERIAL_PORT");

            if (string.IsNullOrEmpty(serialPort))
            {
                serialThread.SetPortName();
            }
            else
            {
                serialThread.SetPortName(serialPort);
            }

            var webSocketTask  = webSocketThread.Start(cancellationToken);
            var serialTask     = serialThread.Start(cancellationToken);
            var processingTask = processingThread.Start(cancellationToken);

            Task.WaitAll(webSocketTask, serialTask, processingTask);

            Console.WriteLine("Daemon finished");
        }
        // handle messages received from websocket
        private async Task MessageReceived(string message, WebSocketWrapper webSocketWrapper)
        {
            if (!string.IsNullOrEmpty(message))
            {
                var messageObject = JObject.Parse(message);

                if (messageObject["type"].ToString() == "ping")
                {
                    // ping received as heartbeat, reply with a ping
                    await SendPing(webSocketWrapper).ConfigureAwait(false);
                }
                else if (messageObject["type"].ToString() == "pub")
                {
                    // message from one of the subscriptions, see if it is a setting
                    if (messageObject["path"].ToString() == settingsPath)
                    {
                        var settings = messageObject["message"];

                        foreach (var key in settings.Children())
                        {
                            var property = key as JProperty;

                            if (property != null)
                            {
                                var handled = false;
                                var name    = property.Name;
                                var setting = settingsToSendThrough.FirstOrDefault(s => s.SettingKey == name);

                                if (setting != null)
                                {
                                    object propertyValue = property.Value.ToObject(setting.SettingType);
                                    this.Settings.AddOrUpdate(name, propertyValue, (name, value) => propertyValue);

                                    if (name == "RA")
                                    {
                                        alarmThread.ResetAlarm();
                                        handled = true;
                                    }
                                    else if (name == "MT")
                                    {
                                        alarmThread.AlarmMuted = (int)propertyValue > 0;

                                        // we are only allowed to mute for one minute
                                        if ((int)propertyValue > 0)
                                        {
                                            muteResetCancellationTokenSource.Cancel();
                                            muteResetCancellationTokenSource = new CancellationTokenSource();
                                            var cancellationToken = muteResetCancellationTokenSource.Token;

                                            _ = Task.Run(async() =>
                                            {
                                                await Task.Delay(60000);

                                                if (!cancellationToken.IsCancellationRequested)
                                                {
                                                    logger.LogInformation("Resetting the mute state to zero");
                                                    await this.apiService.SendSettingToServerAsync("MT", 0);
                                                }
                                            }, muteResetCancellationTokenSource.Token);
                                        }
                                    }
                                    else if (name == "ACTIVE" && (int)propertyValue == 1)
                                    {
                                        _ = Task.Run(() =>
                                        {
                                            // ACTIVE changed to 1, play short beep
                                            logger.LogInformation("Received setting from server: {0}={1}", name, propertyValue);
                                            var bytes = setting.ToBytes(propertyValue);

                                            serialThread.WriteData(bytes, (messageId) =>
                                            {
                                                logger.LogDebug("The machine should have played a beep after receiving active 1");
                                                serialThread.PlayBeep();
                                                alarmThread.ResetAlarm();
                                                alarmThread.SetInactive();
                                                return(Task.CompletedTask);
                                            });
                                        });

                                        handled = true;

                                        serialThread.MachineState = (int)propertyValue;
                                    }
                                    else if (name == "ACTIVE")
                                    {
                                        LastSettingReceivedAt = DateTime.Now;

                                        _ = Task.Run(() =>
                                        {
                                            logger.LogInformation("Received setting from server: {0}={1}", name, propertyValue);
                                            var bytes = setting.ToBytes(propertyValue);
                                            serialThread.WriteData(bytes);

                                            alarmThread.ResetAlarm();
                                            alarmThread.SetInactive();
                                        });
                                        handled = true;

                                        serialThread.MachineState = (int)propertyValue;
                                    }

                                    if (!handled && setting.SendToArduino)
                                    {
                                        LastSettingReceivedAt = DateTime.Now;
                                        _ = Task.Run(() =>
                                        {
                                            logger.LogInformation("Received setting from GUI/server: {0}={1}", name, propertyValue);
                                            var bytes = setting.ToBytes(propertyValue);
                                            serialThread.WriteData(bytes, (msgId) =>
                                            {
                                                logger.LogInformation("Received setting ack from machine: {0}={1}", name, propertyValue);
                                                return(Task.CompletedTask);
                                            });
                                        });

                                        if (setting.CausesAlarmInactivity)
                                        {
                                            alarmThread.SetInactive();
                                        }
                                    }
                                } // end if setting != null
                            }     // end if property != null
                        }         // end foreach
                    }
                }
            }
        }
Beispiel #3
0
        // handle messages received from websocket
        private async Task MessageReceived(string message, WebSocketWrapper webSocketWrapper)
        {
            if (!string.IsNullOrEmpty(message))
            {
                var messageObject = JObject.Parse(message);

                if (messageObject["type"].ToString() == "ping")
                {
                    // ping received as heartbeat, reply with a ping
                    await SendPing(webSocketWrapper).ConfigureAwait(false);
                }
                else if (messageObject["type"].ToString() == "pub")
                {
                    // message from one of the subscriptions, see if it is a setting
                    if (messageObject["path"].ToString() == settingsPath)
                    {
                        var settings = messageObject["message"];

                        foreach (var key in settings.Children())
                        {
                            var property = key as JProperty;

                            if (property != null)
                            {
                                var name          = property.Name;
                                var propertyValue = property.Value.ToObject <float>();
                                this.Settings[name] = propertyValue;

                                if (name == "RA")
                                {
                                    alarmThread.ResetAlarm();
                                }
                                else if (name == "MT")
                                {
                                    alarmThread.AlarmMuted = propertyValue > 0.0f;

                                    // we are only allowed to mute for one minute
                                    if (propertyValue > 0.0f)
                                    {
                                        muteResetCancellationTokenSource.Cancel();
                                        muteResetCancellationTokenSource = new CancellationTokenSource();
                                        var cancellationToken = muteResetCancellationTokenSource.Token;

                                        _ = Task.Run(async() =>
                                        {
                                            await Task.Delay(60000);

                                            if (!cancellationToken.IsCancellationRequested)
                                            {
                                                logger.LogInformation("Resetting the mute state to zero");
                                                await this.apiService.SendSettingToServerAsync("MT", 0);
                                            }
                                        }, muteResetCancellationTokenSource.Token);
                                    }
                                }
                                else if (name == "ACTIVE" && propertyValue >= 0.9f && propertyValue < 1.1f) // see if float value is close to 1
                                {
                                    _ = Task.Run(() =>
                                    {
                                        // ACTIVE changed to 1, play short beep
                                        logger.LogInformation("Received setting from server: {0}={1}", name, propertyValue);
                                        var bytes = ASCIIEncoding.ASCII.GetBytes(string.Format("{0}={1}", name, propertyValue.ToString("0.00")));

                                        serialThread.WriteData(bytes, (messageId) =>
                                        {
                                            logger.LogDebug("The machine should have played a beep after receiving active 1");
                                            serialThread.PlayBeep();
                                            alarmThread.ResetAlarm();
                                            alarmThread.SetInactive();
                                            return(Task.CompletedTask);
                                        });
                                    });
                                }
                                else if (name == "ACTIVE")
                                {
                                    LastSettingReceivedAt = DateTime.Now;

                                    _ = Task.Run(() =>
                                    {
                                        logger.LogInformation("Received setting from server: {0}={1}", name, propertyValue);
                                        var bytes = ASCIIEncoding.ASCII.GetBytes(string.Format("{0}={1}", name, propertyValue.ToString("0.00")));
                                        serialThread.WriteData(bytes);

                                        alarmThread.ResetAlarm();
                                        alarmThread.SetInactive();
                                    });
                                }

                                var setting = settingsToSendThrough.FirstOrDefault(s => s.SettingKey == name);
                                if (setting != null)
                                {
                                    LastSettingReceivedAt = DateTime.Now;
                                    _ = Task.Run(() =>
                                    {
                                        logger.LogInformation("Received setting from server: {0}={1}", name, propertyValue);
                                        var bytes = ASCIIEncoding.ASCII.GetBytes(string.Format("{0}={1}", name, propertyValue.ToString("0.00")));
                                        serialThread.WriteData(bytes);
                                    });

                                    if (setting.CausesAlarmInactivity)
                                    {
                                        alarmThread.SetInactive();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }