private void StopTimer(TimerDetails timerDetails)
        {
            _timers.TryRemove(timerDetails.Name, out var timer);

            if (timer != null)
            {
                _logger.LogInformation($"Disposing timer for {timerDetails.Name}");
                timer.Dispose();
            }
        }
        private void StartTimer(TimerDetails timerDetails)
        {
            // Stop existing timer
            StopTimer(timerDetails);

            _logger.LogInformation($"Creating timer for {timerDetails.Name}");

            var delayInSeconds = timerDetails.DelaySecondsFromNow();

            _logger.LogInformation($"Setting timer for {timerDetails.Name} to {delayInSeconds} seconds");
            _timers[timerDetails.Name] = new Timer(TimerCallback, timerDetails, delayInSeconds * 1000, Timeout.Infinite);
        }
        private async Task ClearMqttTopicRetainedMessage(TimerDetails timerDetails)
        {
            _timersMutex.WaitOne();

            try
            {
                var topic = $"mqtttimer/{timerDetails.Name}";

                var managedMqttApplicationMessage = new ManagedMqttApplicationMessageBuilder()
                                                    .WithApplicationMessage(new MqttApplicationMessageBuilder()
                                                                            .WithTopic(topic)
                                                                            .WithAtLeastOnceQoS()
                                                                            .WithRetainFlag()
                                                                            .Build())
                                                    .Build();

                await _mqttClient.PublishAsync(managedMqttApplicationMessage);
            }
            finally
            {
                _timersMutex.ReleaseMutex();
            }
        }