Project initial upload
This commit is contained in:
16
PCPalService/PCPalService.csproj
Normal file
16
PCPalService/PCPalService.csproj
Normal file
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Worker">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>dotnet-PCPalService-11cebed9-d814-495b-a86d-2d912052e92d</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="System.IO.Ports" Version="9.0.3" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
25
PCPalService/PCPalService.sln
Normal file
25
PCPalService/PCPalService.sln
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.13.35828.75 d17.13
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PCPalService", "PCPalService.csproj", "{71DA320E-9016-4178-89D7-32DEF26AE4E1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{71DA320E-9016-4178-89D7-32DEF26AE4E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{71DA320E-9016-4178-89D7-32DEF26AE4E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{71DA320E-9016-4178-89D7-32DEF26AE4E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{71DA320E-9016-4178-89D7-32DEF26AE4E1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {50DABD9C-9653-4E3A-8800-8A3D4C5CB3BF}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
22
PCPalService/Program.cs
Normal file
22
PCPalService/Program.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using PCPalService;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System;
|
||||
|
||||
namespace PCPalService
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureServices((hostContext, services) =>
|
||||
{
|
||||
services.AddHostedService<Worker>();
|
||||
});
|
||||
}
|
||||
}
|
||||
12
PCPalService/Properties/launchSettings.json
Normal file
12
PCPalService/Properties/launchSettings.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"PCPalService": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"environmentVariables": {
|
||||
"DOTNET_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
192
PCPalService/Worker.cs
Normal file
192
PCPalService/Worker.cs
Normal file
@@ -0,0 +1,192 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
using System.ServiceProcess;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using LibreHardwareMonitor.Hardware;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace PCPalService
|
||||
{
|
||||
public class Worker : BackgroundService
|
||||
{
|
||||
private readonly ILogger<Worker> _logger;
|
||||
private SerialPort serialPort;
|
||||
private Computer computer;
|
||||
private readonly string ConfigFile = GetConfigPath();
|
||||
private const string LogFile = "service_log.txt";
|
||||
|
||||
public Worker(ILogger<Worker> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
computer = new Computer { IsCpuEnabled = true, IsMemoryEnabled = true };
|
||||
computer.Open();
|
||||
}
|
||||
|
||||
private static string GetConfigPath()
|
||||
{
|
||||
string folder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "PCPal");
|
||||
Directory.CreateDirectory(folder); // Ensure folder exists
|
||||
return Path.Combine(folder, "config.json");
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
Log("ESP32 Background Service Starting...");
|
||||
|
||||
try
|
||||
{
|
||||
string portName = AutoDetectESP32();
|
||||
if (portName == null)
|
||||
{
|
||||
Log("ESP32-C3 not found. Service stopping...");
|
||||
throw new Exception("ESP32 not detected.");
|
||||
}
|
||||
|
||||
serialPort = new SerialPort(portName, 115200);
|
||||
serialPort.Open();
|
||||
Log($"Connected to ESP32-C3 on {portName}");
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
UpdateLCD();
|
||||
await Task.Delay(5000, stoppingToken);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"Fatal Error: {ex.Message}");
|
||||
Environment.Exit(1); // Force exit, triggering restart
|
||||
}
|
||||
}
|
||||
|
||||
private string AutoDetectESP32()
|
||||
{
|
||||
foreach (string port in SerialPort.GetPortNames())
|
||||
{
|
||||
if (IsESP32Device(port)) return port;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool IsESP32Device(string portName)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (SerialPort testPort = new SerialPort(portName, 115200))
|
||||
{
|
||||
testPort.Open();
|
||||
testPort.WriteLine("CMD:GET_LCD_TYPE");
|
||||
Thread.Sleep(500);
|
||||
string response = testPort.ReadExisting();
|
||||
testPort.Close();
|
||||
return response.Contains("LCD_TYPE:1602A");
|
||||
}
|
||||
}
|
||||
catch { return false; }
|
||||
}
|
||||
|
||||
private void UpdateLCD()
|
||||
{
|
||||
ConfigData config = LoadConfig();
|
||||
string line1 = GetLCDContent(config.Line1Selection, config.Line1CustomText, config.Line1PostText);
|
||||
string line2 = GetLCDContent(config.Line2Selection, config.Line2CustomText, config.Line2PostText);
|
||||
|
||||
|
||||
SendCommand($"CMD:LCD,0,{line1}");
|
||||
SendCommand($"CMD:LCD,1,{line2}");
|
||||
}
|
||||
|
||||
private string GetLCDContent(string selection, string prefix, string postfix)
|
||||
{
|
||||
var parsed = ParseSensorSelection(selection);
|
||||
if (parsed == null)
|
||||
return "N/A";
|
||||
|
||||
string value = GetSensorValue(parsed.Value.hardwareType, parsed.Value.sensorName, parsed.Value.sensorType);
|
||||
return $"{prefix}{value}{postfix}";
|
||||
}
|
||||
|
||||
|
||||
private (HardwareType hardwareType, string sensorName, SensorType sensorType)? ParseSensorSelection(string input)
|
||||
{
|
||||
try
|
||||
{
|
||||
var parts = input.Split(':', 2);
|
||||
if (parts.Length != 2) return null;
|
||||
|
||||
var hardwareType = Enum.Parse<HardwareType>(parts[0].Trim());
|
||||
var sensorInfo = parts[1].Trim();
|
||||
|
||||
int idx = sensorInfo.LastIndexOf('(');
|
||||
if (idx == -1) return null;
|
||||
|
||||
string name = sensorInfo[..idx].Trim();
|
||||
string typeStr = sensorInfo[(idx + 1)..].Trim(' ', ')');
|
||||
var sensorType = Enum.Parse<SensorType>(typeStr);
|
||||
|
||||
return (hardwareType, name, sensorType);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private string GetSensorValue(HardwareType type, string name, SensorType sensorType)
|
||||
{
|
||||
foreach (IHardware hardware in computer.Hardware)
|
||||
{
|
||||
if (hardware.HardwareType == type)
|
||||
{
|
||||
hardware.Update();
|
||||
foreach (ISensor sensor in hardware.Sensors)
|
||||
{
|
||||
if (sensor.SensorType == sensorType && sensor.Name == name)
|
||||
{
|
||||
return sensor.Value?.ToString("0.0") ?? "N/A";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "N/A";
|
||||
}
|
||||
|
||||
private ConfigData LoadConfig()
|
||||
{
|
||||
if (File.Exists(ConfigFile))
|
||||
{
|
||||
string json = File.ReadAllText(ConfigFile);
|
||||
return JsonConvert.DeserializeObject<ConfigData>(json) ?? new ConfigData();
|
||||
}
|
||||
return new ConfigData();
|
||||
}
|
||||
|
||||
private void SendCommand(string command)
|
||||
{
|
||||
serialPort.WriteLine(command);
|
||||
Log($"Sent: {command}");
|
||||
}
|
||||
|
||||
private void Log(string message)
|
||||
{
|
||||
string logEntry = $"{DateTime.Now}: {message}";
|
||||
File.AppendAllText(LogFile, logEntry + Environment.NewLine);
|
||||
_logger.LogInformation(message);
|
||||
}
|
||||
}
|
||||
|
||||
class ConfigData
|
||||
{
|
||||
public string Line1Selection { get; set; }
|
||||
public string Line1CustomText { get; set; }
|
||||
public string Line2Selection { get; set; }
|
||||
public string Line2CustomText { get; set; }
|
||||
public string Line1PostText { get; set; }
|
||||
public string Line2PostText { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
8
PCPalService/appsettings.Development.json
Normal file
8
PCPalService/appsettings.Development.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
}
|
||||
}
|
||||
8
PCPalService/appsettings.json
Normal file
8
PCPalService/appsettings.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
}
|
||||
}
|
||||
10
PCPalService/config.json
Normal file
10
PCPalService/config.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"LastUsedPort": null,
|
||||
"ScreenType": null,
|
||||
"Line1Selection": "Cpu: CPU Total (Load)",
|
||||
"Line1CustomText": "CPU ",
|
||||
"Line2Selection": "Memory: Memory Used (Data)",
|
||||
"Line2CustomText": "Memory ",
|
||||
"Line1PostText": "%",
|
||||
"Line2PostText": "GB"
|
||||
}
|
||||
5543
PCPalService/service_log.txt
Normal file
5543
PCPalService/service_log.txt
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user