From 624a6e150562f8567ac93034458b77c976355b63 Mon Sep 17 00:00:00 2001 From: Denis Denisov Date: Fri, 8 Jan 2021 17:39:23 +0300 Subject: [PATCH] Unit for monitoring some value via running of external program --- ExternalMonitoringUnit.cs | 75 +++++++++++++++++++++++++++++++++++++++ MonitoringUnit.cs | 6 +++- RegistersContainer.cs | 7 ++++ barsik.json.sample | 7 ++++ 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 ExternalMonitoringUnit.cs diff --git a/ExternalMonitoringUnit.cs b/ExternalMonitoringUnit.cs new file mode 100644 index 0000000..b613121 --- /dev/null +++ b/ExternalMonitoringUnit.cs @@ -0,0 +1,75 @@ +using NLog; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Text.Json; +using System.Threading; + +namespace Barsik +{ + class ExternalMonitoringUnit : BaseMonitoringUnit + { + public ExternalMonitoringUnit(JsonElement config, RegistersContainer registers) : base(config, registers) + { + } + + public override void GenerateItemsConfig(string name, StringBuilder config) + { + config.Append(string.Format("Number {0}_{1} \"{0} {1}\"", name, unitName)); + config.Append(" {channel=\""); + config.AppendFormat("modbus:data:{0}:{1}:", name, unitName); + config.AppendFormat("{1}:number", name, unitName); + config.Append("\"}\n"); + } + + public override void GenerateThingsConfig(StringBuilder config) + { + config.Append("\tBridge poller "); + config.Append(unitName); + config.AppendFormat("[start = {0}, length = 2, type = \"holding\", refresh = 500] {{\n", baseAddress); + config.Append("\t\tThing data "); + config.Append(unitName); + config.AppendFormat("[readStart = \"{0}\", readValueType = \"float32\"]\n", baseAddress); + config.Append("\t}\n"); + } + + public override void Run() + { + string program = config.GetProperty("Program").GetString(); + string args = config.GetProperty("Arguments").GetString(); + var logger = LogManager.GetCurrentClassLogger(); + while (true) + { + ProcessStartInfo procStartInfo = new ProcessStartInfo(program); + procStartInfo.Arguments = args; + procStartInfo.RedirectStandardOutput = true; + procStartInfo.UseShellExecute = false; + procStartInfo.CreateNoWindow = true; + using (Process proc = new Process()) + { + proc.StartInfo = procStartInfo; + proc.Start(); + while (!proc.HasExited) + { + Thread.Sleep(100); + } + string result = proc.StandardOutput.ReadToEnd(); + result = result.Trim(); + float resultFloat; + if (float.TryParse(result, out resultFloat)) + { + registers.SetFloat(baseAddress, resultFloat); + } + else + { + logger.Error("Non-float result from process " + program + " with args " + args); + logger.Error("Result:"); + logger.Error(result); + } + } + Thread.Sleep(2000); + } + } + } +} diff --git a/MonitoringUnit.cs b/MonitoringUnit.cs index 737237c..4a0cb6f 100644 --- a/MonitoringUnit.cs +++ b/MonitoringUnit.cs @@ -35,7 +35,11 @@ namespace Barsik { return new MDStatMonitoringUnit(config, registers); } - else + else if (type == "External") + { + return new ExternalMonitoringUnit(config, registers); + } + else { Console.WriteLine("Unknown unit type " + type); return null; diff --git a/RegistersContainer.cs b/RegistersContainer.cs index 102dade..5aad907 100644 --- a/RegistersContainer.cs +++ b/RegistersContainer.cs @@ -30,5 +30,12 @@ namespace Barsik } } } + + public void SetFloat(int address, float value) + { + byte[] bytes = BitConverter.GetBytes(value); + registers[address + 1] = (int)bytes[0] + (((int)bytes[1]) << 8); + registers[address] = (int)bytes[2] + (((int)bytes[3]) << 8); + } } } diff --git a/barsik.json.sample b/barsik.json.sample index b4d190f..f016dd2 100644 --- a/barsik.json.sample +++ b/barsik.json.sample @@ -13,6 +13,13 @@ "Name": "RAID", "Type": "MDStat", "BaseAddress": 3 + }, + { + "Name": "Some_Tool", + "Type": "External", + "BaseAddress": 100, + "Program": "cat", + "Arguments": "/dev/random" } ] }