118 lines
3.3 KiB
C#
118 lines
3.3 KiB
C#
using System;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Threading;
|
|
|
|
namespace Barsik
|
|
{
|
|
/// <summary>
|
|
/// Parses output of "sensors" command and puts CPU core temperatures into
|
|
/// registers
|
|
/// </summary>
|
|
class SensorsMonitoringUnit : BaseMonitoringUnit
|
|
{
|
|
const string CORE_STR = "Core{0} Temp:";
|
|
const float MULTIPLIER = 100;
|
|
int cores;
|
|
|
|
public SensorsMonitoringUnit(JsonElement config, RegistersContainer registers) : base(config, registers)
|
|
{
|
|
cores = config.GetProperty("Cores").GetInt32();
|
|
}
|
|
|
|
public override void Run()
|
|
{
|
|
while (true)
|
|
{
|
|
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("sensors");
|
|
procStartInfo.RedirectStandardOutput = true;
|
|
procStartInfo.UseShellExecute = false;
|
|
procStartInfo.CreateNoWindow = true;
|
|
using (System.Diagnostics.Process proc = new System.Diagnostics.Process())
|
|
{
|
|
proc.StartInfo = procStartInfo;
|
|
proc.Start();
|
|
while (!proc.HasExited)
|
|
{
|
|
Thread.Sleep(100);
|
|
}
|
|
string result = proc.StandardOutput.ReadToEnd();
|
|
var lines = result.Split('\n');
|
|
// lines in output will be of format:
|
|
// Core0 Temp: +29.0°C
|
|
// and there could be several lines for one core
|
|
// so let's take all of them and use maximal value as core temp
|
|
float[] t = new float[cores];
|
|
for (int i = 0; i < cores; i++)
|
|
{
|
|
t[i] = 0;
|
|
}
|
|
for (int i = 0; i < lines.Length; i++)
|
|
{
|
|
for (int j = 0; j < cores; j++)
|
|
{
|
|
string toFind = string.Format(CORE_STR, j);
|
|
if (lines[i].Contains(toFind))
|
|
{
|
|
var value = ExtractValue(lines[i].Substring(toFind.Length));
|
|
t[j] = Math.Max(t[j], value);
|
|
}
|
|
}
|
|
}
|
|
// fill register data starting from baseAddress
|
|
for (int i = 0; i < cores; i++)
|
|
{
|
|
registers[baseAddress + i] = (int)(t[i] * MULTIPLIER);
|
|
}
|
|
}
|
|
Thread.Sleep(2000);
|
|
}
|
|
}
|
|
|
|
bool Good(char c)
|
|
{
|
|
if (c == '-' || c == '+' || c == '.') return true;
|
|
if (c >= '0' && c <= '9') return true;
|
|
return false;
|
|
}
|
|
|
|
private float ExtractValue(string v)
|
|
{
|
|
int pos = 0;
|
|
while (pos < v.Length && !Good(v[pos])) pos++;
|
|
int pos2 = pos;
|
|
while (pos2 < v.Length && Good(v[pos2])) pos2++;
|
|
float res;
|
|
float.TryParse(v.Substring(pos, pos2 - pos), out res);
|
|
return res;
|
|
}
|
|
|
|
public override void GenerateThingsConfig(StringBuilder config)
|
|
{
|
|
config.Append("\tBridge poller ");
|
|
config.Append(unitName);
|
|
config.AppendFormat("[start = {0}, length = {1}, type = \"holding\", refresh = 500] {{\n", baseAddress, cores);
|
|
int currentAddress = baseAddress;
|
|
for (int i = 0; i < cores; i++)
|
|
{
|
|
string name = string.Format("Core{0}Temp", i);
|
|
config.Append("\t\tThing data ");
|
|
config.Append(name);
|
|
config.AppendFormat("[readStart = \"{0}\", readValueType = \"int16\", readTransform=\"JS(divide100.js)\"]\n", currentAddress);
|
|
currentAddress++;
|
|
}
|
|
config.Append("\t}\n");
|
|
}
|
|
|
|
public override void GenerateItemsConfig(string name, StringBuilder config)
|
|
{
|
|
for (int i = 0; i < cores; i++)
|
|
{
|
|
config.Append(string.Format("Number {0}_Core{1}Temp \"{0} CPU Core{1} [%.1f °C]\" <temperature>", name, i));
|
|
config.Append(" {channel=\"");
|
|
config.AppendFormat("modbus:data:{0}:{1}:Core{2}Temp:number", name, unitName, i);
|
|
config.Append("\"}\n");
|
|
}
|
|
}
|
|
}
|
|
} |