using System; using System.Net; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Media; using RobotClientWpf.Properties; using RobotClientWpf.Utilities; using RobotLib; namespace RobotClientWpf { /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { private bool startupCanceled; private static Mutex? mutex; // mutex with unique key private static readonly string mutexName = "00489402-435c-426e-9d11-9a2b839b39b6"; // random guid private static readonly NLog.Logger log = NLog.LogManager.GetCurrentClassLogger(); private ChallengeFactory? challenge; private bool manualDisconnect; public MainWindow() { // Check if another instance is already running // There is already an instance running of this program if (Mutex.TryOpenExisting(mutexName, out mutex)) { MessageBox.Show("Another instance of RobotClientWpf is already running!" + Environment.NewLine + "You cannot open multiple instances.", "Already running", MessageBoxButton.OK, MessageBoxImage.Exclamation); startupCanceled = true; Application.Current.Shutdown(); return; } // new mutex and keep Alive mutex = new Mutex(false, mutexName); GC.KeepAlive(mutex); // start window InitializeComponent(); this.challenge = new ChallengeFactory(); // inform other views about challenge factory this.mainView.SetChallengeFactory(this.challenge); this.configView.SetChallengeFactory(this.challenge); // subscribe to events this.challenge.PublisherSubscriber.ConnectionStateChanged += PublisherSubscriber_ConnectionStateChanged; } private void PublisherSubscriber_ConnectionStateChanged(object? sender, bool e) { if(e == false) { if (manualDisconnect == true) { manualDisconnect = false; return; } this.DisplayBottomMessage(MessageSeverity.Error, "Connection to MQTT broker lost."); this.SetIpFieldsState(true, true, "Connect"); } } private void BatteryChanged(object? sender, BatteryEventArgs e) { if (!Dispatcher.CheckAccess()) { EventHandler eventDelegate = BatteryChanged; Dispatcher.Invoke(eventDelegate, sender, e); } else { //labelBattery.Content = $"Battery: {e.Voltage} V"; } } private void buttonBuzz_Click(object sender, RoutedEventArgs e) { //Robot.Instance.Buzzer.Beep(300, 500); } private void btnConnectDisconnect_Click(object sender, RoutedEventArgs e) { Task.Run(delegate () { this.ClearBottomMessage(); if (this.challenge.PublisherSubscriber.IsConnected) // is connected => disconnect { manualDisconnect = true; // prevent wrong message this.challenge.PublisherSubscriber.Disconnect(); this.DisplayBottomMessage(MessageSeverity.Success, "Disconnected from MQTT broker."); this.SetIpFieldsState(true, true, "Connect"); } else // is not yet connected => connect { this.SetIpFieldsState(false, false, "Connecting..."); string ipAddress = UIAccessHelpers.GetTextboxText(tbIp); if (IPAddress.TryParse(ipAddress, out _)) { var connectionSuccess = this.challenge.PublisherSubscriber.Connect(ipAddress, "ADIS", "TEST"); if (connectionSuccess) { this.DisplayBottomMessage(MessageSeverity.Success, "Successfully connected to MQTT broker."); this.SetIpFieldsState(false, true, "Disconnect"); } else { this.DisplayBottomMessage(MessageSeverity.Error, $"Failed to connect to MQTT broker on address {ipAddress}."); this.SetIpFieldsState(true, true, "Connect"); } } else { this.DisplayBottomMessage(MessageSeverity.Error, $"Unable to parse MQTT Broker IP address {ipAddress}."); this.SetIpFieldsState(true, true, "Connect"); } } }); } private void SetIpFieldsState(bool ipTextbox, bool connectDisconnectButton, string buttonText) { UIAccessHelpers.SetButtonState(btnConnectDisconnect, connectDisconnectButton); UIAccessHelpers.SetTextboxState(tbIp, ipTextbox); UIAccessHelpers.SetButtonContent(btnConnectDisconnect, buttonText); } public void DisplayBottomMessage(MessageSeverity severity, string message) { Brush col; switch (severity) { case MessageSeverity.Success: col = Brushes.Green; break; case MessageSeverity.Warning: col = Brushes.Orange; break; case MessageSeverity.Error: col = Brushes.Red; break; case MessageSeverity.Information: col = Brushes.Blue; break; case MessageSeverity.Unknown: default: col = Brushes.DarkGray; break; } UIAccessHelpers.SetTextblockTextAndForegroundColor(tbBottomMessage, message, col); } private void ClearBottomMessage() { this.DisplayBottomMessage(MessageSeverity.Information, ""); } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { if (!startupCanceled) { // save settings Settings.Default.MqttBrokerIp = this.tbIp.Text; Settings.Default.Save(); } } private void Window_Loaded(object sender, RoutedEventArgs e) { this.tbIp.Text = Settings.Default.MqttBrokerIp; } } }