Files
ESP32C3-OLED/MainForm.cs
2025-04-12 13:15:42 -04:00

299 lines
9.7 KiB
C#

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Text;
using System.Windows.Forms;
using LibreHardwareMonitor.Hardware;
namespace OledMonitor
{
public partial class MainForm : Form
{
private readonly Computer _computer;
private SerialPort? _serialPort;
private readonly System.Windows.Forms.Timer _updateTimer = new();
private readonly Dictionary<string, float> _sensorValues = new();
private bool _autoUpdate = true;
public MainForm()
{
InitializeComponent();
// Initialize LibreHardwareMonitor
_computer = new Computer
{
IsCpuEnabled = true,
IsGpuEnabled = true,
IsMemoryEnabled = true,
IsMotherboardEnabled = true,
IsControllerEnabled = false,
IsNetworkEnabled = false,
IsStorageEnabled = false
};
_computer.Open();
// Find available serial ports
RefreshComPorts();
// Setup timer for updates
_updateTimer.Interval = 1000; // 1 second updates
_updateTimer.Tick += UpdateTimer_Tick;
// Add sensor variable examples to help text
UpdateHelpText();
}
private void UpdateHelpText()
{
// Collect available sensors to show as examples
StringBuilder sb = new StringBuilder();
sb.AppendLine("Available sensor variables:");
sb.AppendLine();
// Update hardware readings
foreach (var hardware in _computer.Hardware)
{
hardware.Update();
foreach (var sensor in hardware.Sensors)
{
if (sensor.Value.HasValue &&
(sensor.SensorType == SensorType.Load ||
sensor.SensorType == SensorType.Temperature ||
sensor.SensorType == SensorType.Clock ||
sensor.SensorType == SensorType.Power))
{
string sensorId = GetSensorVariableName(hardware.Name, sensor.Name);
_sensorValues[sensorId] = sensor.Value.Value;
string unit = GetSensorUnit(sensor.SensorType);
sb.AppendLine($"{sensorId} = {sensor.Value.Value:F1}{unit}");
}
}
}
txtHelpText.Text = sb.ToString();
}
private string GetSensorVariableName(string hardwareName, string sensorName)
{
// Create a simplified and safe variable name
string name = $"{hardwareName}_{sensorName}"
.Replace(" ", "_")
.Replace("%", "Percent")
.Replace("#", "Num")
.Replace("/", "_")
.Replace("\\", "_")
.Replace("(", "")
.Replace(")", "")
.Replace(",", "");
return name;
}
private string GetSensorUnit(SensorType sensorType)
{
return sensorType switch
{
SensorType.Temperature => "°C",
SensorType.Load => "%",
SensorType.Clock => "MHz",
SensorType.Power => "W",
_ => ""
};
}
private void RefreshComPorts()
{
comboBoxPorts.Items.Clear();
foreach (string port in SerialPort.GetPortNames())
{
comboBoxPorts.Items.Add(port);
}
if (comboBoxPorts.Items.Count > 0)
comboBoxPorts.SelectedIndex = 0;
}
private void btnConnect_Click(object? sender, EventArgs e)
{
if (_serialPort != null && _serialPort.IsOpen)
{
DisconnectFromDevice();
btnConnect.Text = "Connect";
lblStatus.Text = "Disconnected";
_updateTimer.Stop();
}
else
{
try
{
string selectedPort = comboBoxPorts.SelectedItem?.ToString() ?? "";
if (string.IsNullOrEmpty(selectedPort))
{
MessageBox.Show("Please select a COM port.");
return;
}
_serialPort = new SerialPort(selectedPort, 115200);
_serialPort.Open();
btnConnect.Text = "Disconnect";
lblStatus.Text = $"Connected to {selectedPort}";
_updateTimer.Start();
// Send immediately after connecting
SendMarkupToDevice();
}
catch (Exception ex)
{
MessageBox.Show($"Error connecting to device: {ex.Message}");
}
}
}
private void DisconnectFromDevice()
{
if (_serialPort != null && _serialPort.IsOpen)
{
_serialPort.Close();
_serialPort.Dispose();
_serialPort = null;
}
}
private void UpdateTimer_Tick(object? sender, EventArgs e)
{
if (_serialPort == null || !_serialPort.IsOpen)
return;
// Update all hardware readings
UpdateSensorValues();
// If set to auto-update, send markup to device
if (_autoUpdate)
{
SendMarkupToDevice();
}
}
private void UpdateSensorValues()
{
// Update all hardware readings
foreach (var hardware in _computer.Hardware)
{
hardware.Update();
foreach (var sensor in hardware.Sensors)
{
if (sensor.Value.HasValue)
{
string sensorId = GetSensorVariableName(hardware.Name, sensor.Name);
_sensorValues[sensorId] = sensor.Value.Value;
}
}
}
}
private void SendMarkupToDevice()
{
if (_serialPort == null || !_serialPort.IsOpen)
return;
try
{
string markup = ProcessVariablesInMarkup(txtMarkupEditor.Text);
_serialPort.WriteLine(markup);
txtMarkupPreview.Text = markup;
}
catch (Exception ex)
{
lblStatus.Text = $"Error: {ex.Message}";
_updateTimer.Stop();
DisconnectFromDevice();
btnConnect.Text = "Connect";
}
}
private string ProcessVariablesInMarkup(string markup)
{
// Replace variables with actual values
foreach (var sensor in _sensorValues)
{
// Look for {variable} syntax in the markup
string variablePattern = $"{{{sensor.Key}}}";
// Format value based on type (integers vs decimals)
string formattedValue;
if (Math.Abs(sensor.Value - Math.Round(sensor.Value)) < 0.01)
{
formattedValue = $"{sensor.Value:F0}";
}
else
{
formattedValue = $"{sensor.Value:F1}";
}
markup = markup.Replace(variablePattern, formattedValue);
}
return markup;
}
private void btnRefreshPorts_Click(object? sender, EventArgs e)
{
RefreshComPorts();
}
private void btnRefreshSensors_Click(object? sender, EventArgs e)
{
UpdateSensorValues();
UpdateHelpText();
}
private void btnSendNow_Click(object? sender, EventArgs e)
{
UpdateSensorValues();
SendMarkupToDevice();
}
private void chkAutoUpdate_CheckedChanged(object? sender, EventArgs e)
{
_autoUpdate = chkAutoUpdate.Checked;
}
private void Form_FormClosing(object? sender, FormClosingEventArgs e)
{
_updateTimer.Stop();
DisconnectFromDevice();
_computer.Close();
}
private void btnLoadExample_Click(object? sender, EventArgs e)
{
txtMarkupEditor.Text =
"<text x=0 y=12 size=1>CPU: {CPU_Core_i7-6700K_Total_Load}%</text>" +
"<bar x=0 y=16 w=100 h=8 val={CPU_Core_i7-6700K_Total_Load} />" +
"<text x=0 y=32 size=1>GPU: {GPU_NVIDIA_GeForce_GTX_1080_Load_GPU_Core}%</text>" +
"<bar x=0 y=36 w=100 h=8 val={GPU_NVIDIA_GeForce_GTX_1080_Load_GPU_Core} />" +
"<text x=0 y=52 size=1>RAM: {Memory_Load}%</text>" +
"<bar x=0 y=56 w=100 h=8 val={Memory_Load} />";
}
private void btnInsertIcon_Click(object? sender, EventArgs e)
{
using IconBrowser browser = new();
if (browser.ShowDialog() == DialogResult.OK)
{
// Get the icon markup and insert it at the cursor position
string iconMarkup = browser.GetIconMarkup();
if (!string.IsNullOrEmpty(iconMarkup))
{
int selectionStart = txtMarkupEditor.SelectionStart;
txtMarkupEditor.Text = txtMarkupEditor.Text.Insert(selectionStart, iconMarkup);
txtMarkupEditor.SelectionStart = selectionStart + iconMarkup.Length;
txtMarkupEditor.Focus();
}
}
}
}
}