From 5cf75372d48d9aeb9a89c06fd15ebfa7a643c099 Mon Sep 17 00:00:00 2001 From: Jimmy White Date: Sun, 14 Jul 2024 14:18:17 +0100 Subject: [PATCH] added error trapping and logging --- API/MeetingState.cs | 6 +- API/MqttService.cs | 40 +++++-- API/State.cs | 2 +- API/WebSocketManager.cs | 59 +++++++--- App.xaml.cs | 38 +++++-- MainWindow.xaml.cs | 247 ++++++++++++++++++++++++---------------- TEAMS2HA.csproj | 12 +- 7 files changed, 264 insertions(+), 140 deletions(-) diff --git a/API/MeetingState.cs b/API/MeetingState.cs index 0959856..585712d 100644 --- a/API/MeetingState.cs +++ b/API/MeetingState.cs @@ -36,7 +36,7 @@ public class MeetingState public bool IsRecordingOn { get; set; } public bool IsSharing { get; set; } public bool IsVideoOn { get; set; } - public bool teamsRunning { get; set; } + public bool TeamsRunning { get; set; } #endregion Public Properties } @@ -45,8 +45,8 @@ public class MeetingUpdate { #region Public Properties - public MeetingPermissions MeetingPermissions { get; set; } - public MeetingState MeetingState { get; set; } + public MeetingPermissions? MeetingPermissions { get; set; } + public MeetingState? MeetingState { get; set; } #endregion Public Properties } diff --git a/API/MqttService.cs b/API/MqttService.cs index d271956..3a73e10 100644 --- a/API/MqttService.cs +++ b/API/MqttService.cs @@ -58,8 +58,7 @@ public void Initialize(AppSettings settings, string deviceId, List senso _sensorNames = sensorNames; _isInitialized = true; - //_mqttClient.ApplicationMessageReceivedAsync += OnMessageReceivedAsync; - + } else { @@ -108,7 +107,7 @@ private MqttService() await Task.CompletedTask; }; Log.Information("MQTT client created."); - // _mqttClient.ApplicationMessageReceivedAsync += OnMessageReceivedAsync; + } public async Task SubscribeToReactionButtonsAsync() @@ -164,7 +163,14 @@ private Task OnMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs e) / string reactionPayloadJson = JsonConvert.SerializeObject(reactionPayload); // Invoke the command to send the reaction to Teams - CommandToTeams?.Invoke(reactionPayloadJson); + try + { + CommandToTeams?.Invoke(reactionPayloadJson); + } + catch (Exception ex) + { + Log.Error($"Error sending reaction to Teams: {ex.Message}"); + } } } @@ -218,7 +224,14 @@ private void HandleSwitchCommand(string topic, string command) if (!string.IsNullOrEmpty(jsonMessage)) { // Raise the event - CommandToTeams?.Invoke(jsonMessage); + try + { + CommandToTeams?.Invoke(jsonMessage); + } + catch (Exception ex) + { + Log.Error($"Error sending command to Teams: {ex.Message}"); + } } } public async Task ConnectAsync(AppSettings settings) @@ -333,7 +346,14 @@ public async Task PublishReactionButtonsAsync() .Build(); if (_mqttClient.IsConnected) { - await PublishAsync(message); + try + { + await PublishAsync(message); + } + catch (Exception ex) + { + Log.Error($"Error publishing reaction button configuration: {ex.Message}"); + } } } @@ -499,7 +519,7 @@ public async Task PublishConfigurations(MeetingUpdate meetingUpdate, AppSettings IsBackgroundBlurred = false, IsSharing = false, HasUnreadMessages = false, - teamsRunning = IsTeamsRunning() + TeamsRunning = IsTeamsRunning() } }; } @@ -662,7 +682,7 @@ private string GetStateValue(string sensor, MeetingUpdate meetingUpdate) // Similar casting for these properties return (bool)meetingUpdate.MeetingState.GetType().GetProperty(sensor).GetValue(meetingUpdate.MeetingState, null) ? "True" : "False"; - case "teamsRunning": + case "TeamsRunning": return (bool)meetingUpdate.MeetingState.GetType().GetProperty(sensor).GetValue(meetingUpdate.MeetingState, null) ? "True" : "False"; default: @@ -682,7 +702,7 @@ private string DetermineDeviceClass(string sensor) case "HasUnreadMessages": case "IsRecordingOn": case "IsSharing": - case "teamsRunning": + case "TeamsRunning": return "binary_sensor"; // These are true/false sensors default: return "unknown"; // Or a default device class if appropriate @@ -703,7 +723,7 @@ public async Task SetupMqttSensors() IsBackgroundBlurred = false, IsSharing = false, HasUnreadMessages = false, - teamsRunning = false + TeamsRunning = false } }; diff --git a/API/State.cs b/API/State.cs index 9532c6b..8f5a10d 100644 --- a/API/State.cs +++ b/API/State.cs @@ -167,7 +167,7 @@ public string Status } } - public bool teamsRunning { get; set; } + public bool TeamsRunning { get; set; } public bool CanToggleMute { get; set; } public bool CanToggleVideo { get; set; } public bool CanToggleHand { get; set; } diff --git a/API/WebSocketManager.cs b/API/WebSocketManager.cs index 0ee9ee1..432546e 100644 --- a/API/WebSocketManager.cs +++ b/API/WebSocketManager.cs @@ -79,7 +79,7 @@ public async Task ConnectAsync(Uri uri) } catch (Exception ex) { - Log.Error("Failed to connect: " + ex.Message); + Log.Error("Failed to connect to Teams: " + ex.Message); SetIsConnected(false); } finally @@ -92,7 +92,7 @@ private void SetIsConnected(bool value) if (_isConnected != value) { _isConnected = value; - State.Instance.teamsRunning = value; //update the MQTT state + State.Instance.TeamsRunning = value; //update the MQTT state ConnectionStatusChanged?.Invoke(IsConnected); //update the UI } @@ -105,8 +105,12 @@ public async Task PairWithTeamsAsync(Action updateTokenCallback) _pairingResponseTaskSource = new TaskCompletionSource(); string pairingCommand = "{\"action\":\"pair\",\"parameters\":{},\"requestId\":1}"; - await SendMessageAsync(pairingCommand); - + try + { + await SendMessageAsync(pairingCommand); + } catch (Exception ex) { + Log.Error("Error sending pairing command: " + ex.Message); + } var responseTask = await Task.WhenAny(_pairingResponseTaskSource.Task, Task.Delay(TimeSpan.FromSeconds(30))); if (responseTask == _pairingResponseTaskSource.Task) @@ -174,16 +178,29 @@ public async Task SendMessageAsync(string message, CancellationToken cancellatio Log.Warning("WebSocket is not connected. Message not sent."); return; } - - byte[] messageBytes = Encoding.UTF8.GetBytes(message); - await _clientWebSocket.SendAsync(new ArraySegment(messageBytes), WebSocketMessageType.Text, true, cancellationToken); - Log.Debug($"Message Sent: {message}"); + try + { + byte[] messageBytes = Encoding.UTF8.GetBytes(message); + await _clientWebSocket.SendAsync(new ArraySegment(messageBytes), WebSocketMessageType.Text, true, cancellationToken); + Log.Debug($"Message Sent: {message}"); + } + catch (Exception ex) + { + Log.Error("Error sending message from websocket manager: " + ex.Message); + } } public async Task EnsureConnectedAsync() { if (_clientWebSocket.State != WebSocketState.Open) { - await ConnectAsync(_currentUri); + Log.Information("Reconnecting to Teams..."); + try + { + await ConnectAsync(_currentUri); + } catch (Exception ex) + { + Log.Error("Error reconnecting to Teams: " + ex.Message); + } } } public async Task SendReactionToTeamsAsync(string reactionType) @@ -333,7 +350,7 @@ private void OnMessageReceived(object sender, string message) meetingState["isRecordingOn"] = meetingUpdate.MeetingState.IsRecordingOn; meetingState["isBackgroundBlurred"] = meetingUpdate.MeetingState.IsBackgroundBlurred; meetingState["isSharing"] = meetingUpdate.MeetingState.IsSharing; - meetingUpdate.MeetingState.teamsRunning = IsConnected; + meetingUpdate.MeetingState.TeamsRunning = IsConnected; if (meetingUpdate.MeetingState.IsVideoOn) { State.Instance.Camera = "On"; @@ -342,13 +359,13 @@ private void OnMessageReceived(object sender, string message) { State.Instance.Camera = "Off"; } - if (meetingUpdate.MeetingState.teamsRunning) + if (meetingUpdate.MeetingState.TeamsRunning) { - State.Instance.teamsRunning = true; + State.Instance.TeamsRunning = true; } else { - State.Instance.teamsRunning = false; + State.Instance.TeamsRunning = false; } if (meetingUpdate.MeetingState.IsInMeeting) { @@ -404,13 +421,14 @@ private void OnMessageReceived(object sender, string message) } try { + Log.Information("Meeting State Updated: {meetingState}", meetingState); TeamsUpdateReceived?.Invoke(this, new TeamsUpdateEventArgs { MeetingUpdate = meetingUpdate }); } catch (Exception ex) { Log.Error(ex, "Error in TeamsUpdateReceived"); } - Log.Debug($"Meeting State Updated: {meetingState}"); + } } } @@ -418,9 +436,16 @@ public async Task DisconnectAsync() { if (_clientWebSocket.State == WebSocketState.Open) { - await _clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Client disconnect", CancellationToken.None); - SetIsConnected(false); - Log.Information("Disconnected from server."); + try + { + await _clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Client disconnect", CancellationToken.None); + SetIsConnected(false); + Log.Information("Disconnected from server."); + } + catch (Exception ex) + { + Log.Error("Error disconnecting from server: " + ex.Message); + } } } } diff --git a/App.xaml.cs b/App.xaml.cs index b6e7afc..2100db9 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -1,17 +1,10 @@ using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; using System.Threading; -using System.Threading.Tasks; using System.Windows; +using Serilog; // Ensure Serilog is configured properly in the project namespace TEAMS2HA { - /// - /// Interaction logic for App.xaml - /// public partial class App : Application { private static Mutex mutex = null; @@ -31,7 +24,36 @@ protected override void OnStartup(StartupEventArgs e) return; } + // Configure logging here if not already configured + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + .WriteTo.File("logs\\TEAMS2HA_.txt", rollingInterval: RollingInterval.Day) + .CreateLogger(); + + // Handle unhandled exceptions + this.DispatcherUnhandledException += App_DispatcherUnhandledException; + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + base.OnStartup(e); } + + private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) + { + Log.Error($"Unhandled exception caught on dispatcher thread: {e.Exception}"); + // Optionally, prevent application exit + e.Handled = true; + } + + private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + Log.Error($"Unhandled exception caught on current domain: {e.ExceptionObject}"); + } + + protected override void OnExit(ExitEventArgs e) + { + Log.CloseAndFlush(); // Ensure all logs are flushed properly + mutex?.ReleaseMutex(); // Release the mutex when application is exiting + base.OnExit(e); + } } } diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index 1f66087..d775b9e 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -68,10 +68,7 @@ public static AppSettings Instance { lock (_lock) { - if (_instance == null) - { - _instance = new AppSettings(); - } + _instance ??= new AppSettings(); return _instance; } } @@ -174,7 +171,14 @@ public void SaveSettingsToFile() Log.Debug("SetStartupAsync: Startup options set"); // Serialize and save string json = JsonConvert.SerializeObject(this, Formatting.Indented); - File.WriteAllText(_settingsFilePath, json); + try + { + File.WriteAllText(_settingsFilePath, json); + } + catch (Exception ex) + { + Log.Error("SaveSettingsToFile: Error saving settings to file: {message}", ex.Message); + } } #endregion Public Methods @@ -186,21 +190,28 @@ private void LoadSettingsFromFile() { if (File.Exists(_settingsFilePath)) { - string json = File.ReadAllText(_settingsFilePath); - JsonConvert.PopulateObject(json, this); - - // Decrypt sensitive data - if (!String.IsNullOrEmpty(this.EncryptedMqttPassword)) - { - this.MqttPassword = CryptoHelper.DecryptString(this.EncryptedMqttPassword); - } - if (!String.IsNullOrEmpty(this.TeamsToken)) + try { - this.PlainTeamsToken = CryptoHelper.DecryptString(this.TeamsToken); + string json = File.ReadAllText(_settingsFilePath); + JsonConvert.PopulateObject(json, this); + + // Decrypt sensitive data + if (!String.IsNullOrEmpty(this.EncryptedMqttPassword)) + { + this.MqttPassword = CryptoHelper.DecryptString(this.EncryptedMqttPassword); + } + if (!String.IsNullOrEmpty(this.TeamsToken)) + { + this.PlainTeamsToken = CryptoHelper.DecryptString(this.TeamsToken); + } + if (string.IsNullOrEmpty(this.MqttPort)) + { + this.MqttPort = "1883"; // Default MQTT port + } } - if (string.IsNullOrEmpty(this.MqttPort)) + catch (Exception ex) { - this.MqttPort = "1883"; // Default MQTT port + Log.Error("LoadSettingsFromFile: Error loading settings from file: {message}", ex.Message); } } else @@ -246,7 +257,7 @@ public partial class MainWindow : Window private List sensorNames = new List { - "IsMuted", "IsVideoOn", "IsHandRaised", "IsInMeeting", "IsRecordingOn", "IsBackgroundBlurred", "IsSharing", "HasUnreadMessages", "teamsRunning" + "IsMuted", "IsVideoOn", "IsHandRaised", "IsInMeeting", "IsRecordingOn", "IsBackgroundBlurred", "IsSharing", "HasUnreadMessages", "TeamsRunning" }; private bool teamspaired = false; @@ -263,12 +274,18 @@ public MainWindow() // Configure logging LoggingConfig.Configure(); - + Log.Information("Starting TEAMS2HA"); // Create the TEAMS2HA folder in the local application data folder var appDataFolder = Path.Combine(localAppData, "TEAMS2HA"); Log.Debug("Set Folder Path to {path}", appDataFolder); - Directory.CreateDirectory(appDataFolder); // Ensure the directory exists - + try + { + Directory.CreateDirectory(appDataFolder); // Ensure the directory exists + } + catch + { + Log.Error("Error creating Log Directory at {path}", appDataFolder); + } // Set the settings file path _settingsFilePath = Path.Combine(appDataFolder, "settings.json"); @@ -329,24 +346,32 @@ public MainWindow() #region Public Methods public async Task InitializeConnections() { - MqttService.Instance.Initialize(_settings, _settings.SensorPrefix, sensorNames); - await MqttService.Instance.ConnectAsync(AppSettings.Instance); - if (_mqttService == null) + try { - _mqttService = MqttService.Instance; - _mqttService.StatusUpdated += UpdateMqttStatus; - - } - await _mqttService.SubscribeAsync($"homeassistant/switch/{deviceid.ToLower()}/+/set", MqttQualityOfServiceLevel.AtLeastOnce); - await _mqttService.SubscribeAsync($"homeassistant/binary_sensor/{deviceid.ToLower()}/+/state", MqttQualityOfServiceLevel.AtLeastOnce); - // await _mqttService.SubscribeAsync("#", MqttQualityOfServiceLevel.AtLeastOnce); //line to test all topics + MqttService.Instance.Initialize(_settings, _settings.SensorPrefix, sensorNames); + await MqttService.Instance.ConnectAsync(AppSettings.Instance); + if (_mqttService == null) + { + _mqttService = MqttService.Instance; + _mqttService.StatusUpdated += UpdateMqttStatus; + } - _ = _mqttService.PublishConfigurations(null!, _settings); - _mqttService.CommandToTeams += HandleCommandToTeams; - InitializeWebSocket(); - Dispatcher.Invoke(() => UpdateStatusMenuItems()); + await _mqttService.SubscribeAsync($"homeassistant/switch/{deviceid.ToLower()}/+/set", MqttQualityOfServiceLevel.AtLeastOnce); + await _mqttService.SubscribeAsync($"homeassistant/binary_sensor/{deviceid.ToLower()}/+/state", MqttQualityOfServiceLevel.AtLeastOnce); + // Uncomment to subscribe to all topics for debugging + // await _mqttService.SubscribeAsync("#", MqttQualityOfServiceLevel.AtLeastOnce); + _ = _mqttService.PublishConfigurations(null!, _settings); + _mqttService.CommandToTeams += HandleCommandToTeams; + InitializeWebSocket(); + Dispatcher.Invoke(() => UpdateStatusMenuItems()); + } + catch (Exception ex) + { + Log.Error($"Failed to initialize connections: {ex.Message}"); + } } + public bool IsTeamsConnected { get { return isTeamsConnected; } @@ -374,27 +399,37 @@ public bool IsTeamsConnected } private async void InitializeWebSocket() { - var uri = new Uri($"ws://localhost:8124?token={_settings.PlainTeamsToken}&protocol-version=2.0.0&manufacturer=JimmyWhite&device=PC&app=THFHA&app-version=2.0.26"); - await WebSocketManager.Instance.PairWithTeamsAsync(newToken => + try { - // Update the UI with the new token - TeamsApiKeyBox.Text = "Paired"; - }); - await WebSocketManager.Instance.ConnectAsync(uri); - WebSocketManager.Instance.TeamsUpdateReceived += TeamsClient_TeamsUpdateReceived; + var uri = new Uri($"ws://localhost:8124?token={_settings.PlainTeamsToken}&protocol-version=2.0.0&manufacturer=JimmyWhite&device=PC&app=THFHA&app-version=2.0.26"); + await WebSocketManager.Instance.PairWithTeamsAsync(newToken => + { + // Update the UI with the new token + Dispatcher.Invoke(() => TeamsApiKeyBox.Text = "Paired"); + }); - WebSocketManager.Instance.ConnectionStatusChanged += (isConnected) => - { - // Because this event handler might be called from a non-UI thread, - // use Dispatcher.Invoke to ensure that the UI update runs on the UI thread: - Dispatcher.Invoke(() => TeamsConnectionStatusChanged(isConnected)); - }; - + await WebSocketManager.Instance.ConnectAsync(uri); + WebSocketManager.Instance.TeamsUpdateReceived += TeamsClient_TeamsUpdateReceived; + WebSocketManager.Instance.ConnectionStatusChanged += (isConnected) => + { + // Because this event handler might be called from a non-UI thread, + // use Dispatcher.Invoke to ensure that the UI update runs on the UI thread: + Dispatcher.Invoke(() => TeamsConnectionStatusChanged(isConnected)); + }; - Dispatcher.Invoke(() => UpdateStatusMenuItems()); + Dispatcher.Invoke(() => UpdateStatusMenuItems()); + } + catch (Exception ex) + { + Log.Error($"Error initializing WebSocket connection: {ex.Message}"); + Dispatcher.Invoke(() => + MessageBox.Show("Failed to connect to Teams service. Please check your network settings and try again.", "WebSocket Connection Failed", MessageBoxButton.OK, MessageBoxImage.Error) + ); + } } + private void MainWindow_StateChanged(object sender, EventArgs e) { if (WindowState == WindowState.Minimized) @@ -417,6 +452,7 @@ private void MainWindow_StateChanged(object sender, EventArgs e) private void MainWindow_Closing(object sender, CancelEventArgs e) { // Minimize to system tray instead of closing + Log.Information("MainWindow_Closing: Minimizing to system tray"); e.Cancel = true; this.WindowState = WindowState.Minimized; } @@ -448,8 +484,10 @@ protected override void OnStateChanged(EventArgs e) private void AboutMenuItem_Click(object sender, RoutedEventArgs e) { string currentTheme = _settings.Theme; // Assuming this is where the theme is stored - var aboutWindow = new AboutWindow(deviceid, MyNotifyIcon); - aboutWindow.Owner = this; + var aboutWindow = new AboutWindow(deviceid, MyNotifyIcon) + { + Owner = this + }; aboutWindow.ShowDialog(); } @@ -512,57 +550,67 @@ private bool CheckIfSensorPrefixChanged(AppSettings newSettings) private void CreateNotifyIconContextMenu() { - ContextMenu contextMenu = new ContextMenu(); + Log.Information("CreateNotifyIconContextMenu: Creating NotifyIcon Context Menu"); + try + { + ContextMenu contextMenu = new ContextMenu(); - // Show/Hide Window - MenuItem showHideMenuItem = new MenuItem(); - showHideMenuItem.Header = "Show/Hide"; - showHideMenuItem.Click += ShowHideMenuItem_Click; + // Show/Hide Window + MenuItem showHideMenuItem = new MenuItem(); + showHideMenuItem.Header = "Show/Hide"; + showHideMenuItem.Click += ShowHideMenuItem_Click; - // MQTT Status - _mqttStatusMenuItem = new MenuItem { Header = "MQTT Status: Unknown", IsEnabled = false }; + // MQTT Status + _mqttStatusMenuItem = new MenuItem { Header = "MQTT Status: Unknown", IsEnabled = false }; - // Teams Status - _teamsStatusMenuItem = new MenuItem { Header = "Teams Status: Unknown", IsEnabled = false }; + // Teams Status + _teamsStatusMenuItem = new MenuItem { Header = "Teams Status: Unknown", IsEnabled = false }; - // Logs - _logMenuItem = new MenuItem { Header = "View Logs" }; - _logMenuItem.Click += LogsButton_Click; // Reuse existing event handler + // Logs + _logMenuItem = new MenuItem { Header = "View Logs" }; + _logMenuItem.Click += LogsButton_Click; // Reuse existing event handler - // About - _aboutMenuItem = new MenuItem { Header = "About" }; - _aboutMenuItem.Click += AboutMenuItem_Click; + // About + _aboutMenuItem = new MenuItem { Header = "About" }; + _aboutMenuItem.Click += AboutMenuItem_Click; - // Exit - MenuItem exitMenuItem = new MenuItem(); - exitMenuItem.Header = "Exit"; - exitMenuItem.Click += ExitMenuItem_Click; + // Exit + MenuItem exitMenuItem = new MenuItem(); + exitMenuItem.Header = "Exit"; + exitMenuItem.Click += ExitMenuItem_Click; - contextMenu.Items.Add(showHideMenuItem); - contextMenu.Items.Add(_mqttStatusMenuItem); - contextMenu.Items.Add(_teamsStatusMenuItem); - contextMenu.Items.Add(_logMenuItem); - contextMenu.Items.Add(_aboutMenuItem); - contextMenu.Items.Add(new Separator()); // Separator before exit - contextMenu.Items.Add(exitMenuItem); + contextMenu.Items.Add(showHideMenuItem); + contextMenu.Items.Add(_mqttStatusMenuItem); + contextMenu.Items.Add(_teamsStatusMenuItem); + contextMenu.Items.Add(_logMenuItem); + contextMenu.Items.Add(_aboutMenuItem); + contextMenu.Items.Add(new Separator()); // Separator before exit + contextMenu.Items.Add(exitMenuItem); - MyNotifyIcon.ContextMenu = contextMenu; + MyNotifyIcon.ContextMenu = contextMenu; + } + catch (Exception ex) + { + Log.Error("CreateNotifyIconContextMenu: Error creating NotifyIcon Context Menu: {message}", ex.Message); + } } - private void ExitMenuItem_Click(object sender, RoutedEventArgs e) + private async void ExitMenuItem_Click(object sender, RoutedEventArgs e) { // Handle the click event for the exit menu item (Close the application) if (_mqttService != null) { + Log.Information("ExitMenuItem_Click: Disconnecting MQTT client..."); _mqttService.StatusUpdated -= UpdateMqttStatus; _mqttService.CommandToTeams -= HandleCommandToTeams; - // Disconnect asynchronously without waiting - _ = _mqttService.DisconnectAsync(); + if (_mqttService.IsConnected) + { + await _mqttService.DisconnectAsync(); + Log.Debug("MQTT Client Disposed"); + } + - // Dispose of the MQTT service - _mqttService.Dispose(); - Log.Debug("MQTT Client Disposed"); } @@ -575,7 +623,14 @@ private async Task HandleCommandToTeams(string jsonMessage) { if (WebSocketManager.Instance != null && WebSocketManager.Instance.IsConnected) { - await WebSocketManager.Instance.SendMessageAsync(jsonMessage); + try + { + await WebSocketManager.Instance.SendMessageAsync(jsonMessage); + } + catch (Exception ex) + { + Log.Error("HandleCommandToTeams: Error sending message to Teams: {message}", ex.Message); + } } else { @@ -587,7 +642,6 @@ private async Task HandleCommandToTeams(string jsonMessage) - private void LogsButton_Click(object sender, RoutedEventArgs e) { string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Teams2HA"); @@ -708,7 +762,7 @@ private void ShowOneTimeNoticeIfNeeded() if (!_settings.HasShownOneTimeNotice2) { // Show the notice to the user - MessageBox.Show("Important: Due to recent updates, the functionality of TEAMS2HA has changed. sensor prefixes are now all forced to lower case", "Notice", MessageBoxButton.OK, MessageBoxImage.Information); + MessageBox.Show("Important: New for this version, improved logging and error checking.", "Notice", MessageBoxButton.OK, MessageBoxImage.Information); // Update the setting so that the notice isn't shown again _settings.HasShownOneTimeNotice2 = true; @@ -744,11 +798,7 @@ private async void SaveSettings_Click(object sender, RoutedEventArgs e) { Log.Debug("SaveSettings_Click: Save Settings Clicked" + _settings.ToString()); - // uncomment below for testing ** insecure as tokens exposed in logs! ** - //foreach(var setting in _settings.GetType().GetProperties()) - //{ - // Log.Debug(setting.Name + " " + setting.GetValue(_settings)); - //} + await SaveSettingsAsync(); } @@ -840,7 +890,14 @@ private async void TeamsClient_TeamsUpdateReceived(object sender, TeamsUpdateEve _latestMeetingUpdate = e.MeetingUpdate; Log.Debug("TeamsClient_TeamsUpdateReceived: Teams Update Received {update}", _latestMeetingUpdate); // Update sensor configurations - await _mqttService.PublishConfigurations(_latestMeetingUpdate, _settings); + try + { + await _mqttService.PublishConfigurations(_latestMeetingUpdate, _settings); + } + catch (Exception ex) + { + Log.Error("TeamsClient_TeamsUpdateReceived: Error publishing configurations: {message}", ex.Message); + } UpdateStatusMenuItems(); } } @@ -853,7 +910,7 @@ private void TeamsConnectionStatusChanged(bool isConnected) _teamsStatusMenuItem.Header = "Teams Status: " + (isConnected ? "Connected" : "Disconnected"); if (_latestMeetingUpdate != null && _latestMeetingUpdate.MeetingState != null) { - _latestMeetingUpdate.MeetingState.teamsRunning = isConnected; + _latestMeetingUpdate.MeetingState.TeamsRunning = isConnected; } _ = _mqttService.PublishConfigurations(_latestMeetingUpdate, _settings); }); diff --git a/TEAMS2HA.csproj b/TEAMS2HA.csproj index 2354876..bb63fb6 100644 --- a/TEAMS2HA.csproj +++ b/TEAMS2HA.csproj @@ -5,8 +5,8 @@ net7.0-windows enable true - 1.1.0.751 - 1.1.0.751 + 1.1.0.769 + 1.1.0.769 Assets\Square150x150Logo.scale-200.ico Teams2HA Square150x150Logo.scale-200.png @@ -28,15 +28,15 @@ - - + + - - + +