diff --git a/EpsonPrintService/HeartbeatBackgroundTask.cs b/EpsonPrintService/HeartbeatBackgroundTask.cs
new file mode 100644
index 0000000..8c5629a
--- /dev/null
+++ b/EpsonPrintService/HeartbeatBackgroundTask.cs
@@ -0,0 +1,105 @@
+using Inspectron.Epson.PrintServer.ConfigurationSources;
+using Microsoft.Extensions.Logging;
+using System.Net.Http.Json;
+using System.Text.Json.Serialization;
+
+namespace EpsonPrintService;
+
+///
+/// Background task that periodically sends heartbeat signals to the API
+///
+public class HeartbeatBackgroundTask
+{
+ private readonly EpsonPrintServiceConfiguration _configuration;
+ private readonly ILogger _logger;
+ private readonly HttpClient _httpClient;
+ private readonly TimeSpan _interval;
+
+ public HeartbeatBackgroundTask(
+ EpsonPrintServiceConfiguration configuration,
+ ILogger logger)
+ {
+ _configuration = configuration;
+ _logger = logger;
+ _httpClient = new HttpClient();
+ _interval = TimeSpan.FromSeconds(30);
+ }
+
+ ///
+ /// Starts the heartbeat background task
+ ///
+ /// Token to cancel the background task
+ public async Task StartAsync(CancellationToken cancellationToken)
+ {
+ _logger.LogInformation("Starting heartbeat background task (interval: {Interval}s)", _interval.TotalSeconds);
+
+ // Run immediately on start
+ await SendHeartbeatAsync();
+
+ // Then run periodically
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ try
+ {
+ await Task.Delay(_interval, cancellationToken);
+ await SendHeartbeatAsync();
+ }
+ catch (TaskCanceledException)
+ {
+ break;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error during heartbeat");
+ }
+ }
+
+ _logger.LogInformation("Heartbeat background task stopped");
+ }
+
+ private async Task SendHeartbeatAsync()
+ {
+ try
+ {
+ var url = _configuration.HeartbeatApiUrl;
+ var apiKey = _configuration.PrinterServerKey;
+
+ if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(apiKey))
+ {
+ _logger.LogWarning("Heartbeat not configured (missing HeartbeatApiUrl or PrinterServerKey)");
+ return;
+ }
+
+ using var request = new HttpRequestMessage(HttpMethod.Post, url);
+ request.Headers.Add("X-Printer-Server-Key", apiKey);
+
+ var payload = new HeartbeatPayload
+ {
+ OsVersion = Environment.OSVersion.ToString()
+ };
+
+ request.Content = JsonContent.Create(payload);
+
+ var response = await _httpClient.SendAsync(request);
+
+ if (response.IsSuccessStatusCode)
+ {
+ _logger.LogDebug("Heartbeat sent successfully");
+ }
+ else
+ {
+ _logger.LogWarning("Heartbeat failed with status code: {StatusCode}", response.StatusCode);
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogWarning(ex, "Failed to send heartbeat");
+ }
+ }
+
+ private class HeartbeatPayload
+ {
+ [JsonPropertyName("osVersion")]
+ public string OsVersion { get; set; } = string.Empty;
+ }
+}
diff --git a/EpsonPrintService/Program.cs b/EpsonPrintService/Program.cs
index c83fa85..098654a 100644
--- a/EpsonPrintService/Program.cs
+++ b/EpsonPrintService/Program.cs
@@ -45,12 +45,12 @@ kernel.Bind().To().InSingleto
kernel.Bind().ToSelf().InSingletonScope();
kernel.Bind().To().InSingletonScope();
kernel.Bind().ToSelf().InSingletonScope();
+kernel.Bind().ToSelf().InSingletonScope();
var printLoop = kernel.Get();
-var printServer = kernel.Get();
-var discoveryTask = kernel.Get();
-printServer.RegisterPrinter("127.0.0.1");
+var discoveryTask = kernel.Get();
+var heartbeatTask = kernel.Get();
await printLoop.StartAsync();
@@ -64,8 +64,9 @@ Console.CancelKeyPress += (sender, e) =>
cts.Cancel();
};
-// Start the printer discovery background task
+// Start background tasks
_ = discoveryTask.StartAsync(cts.Token);
+_ = heartbeatTask.StartAsync(cts.Token);
try
{
diff --git a/Inspectron.Epson/PrintServer/ConfigurationSources/EpsonPrintServiceConfiguration.cs b/Inspectron.Epson/PrintServer/ConfigurationSources/EpsonPrintServiceConfiguration.cs
index 0935696..f5b8026 100644
--- a/Inspectron.Epson/PrintServer/ConfigurationSources/EpsonPrintServiceConfiguration.cs
+++ b/Inspectron.Epson/PrintServer/ConfigurationSources/EpsonPrintServiceConfiguration.cs
@@ -7,6 +7,8 @@ public class EpsonPrintServiceConfiguration: IPrinterConfigurationSource, IAssig
public string GroupId { get; set; }
public string RestaurantId { get; set; }
public string ApiKey { get; set; }
+ public string? HeartbeatApiUrl { get; set; }
+ public string? PrinterServerKey { get; set; }
public Dictionary PrinterConfigurations { get; set; }
public PrinterConfiguration GetConfiguration(string printerAddress)