static void Main(string[] args) { // загрузка текущей конфигурации сервера var configName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ModbusIntegrator.ini"); mif = new MemIniFile(configName); // запуск фонового процесса для прослушивания сокета Modbus Tcp 502 var worker = new BackgroundWorker { WorkerSupportsCancellation = true, WorkerReportsProgress = true }; workers.Add(worker); worker.DoWork += Worker_DoWork; worker.RunWorkerCompleted += Worker_RunWorkerCompleted; worker.ProgressChanged += Worker_ProgressChanged; int.TryParse(mif.ReadString("default", "IpPort", "502"), out int port); var tcptuning = new TcpTuning { Port = port }; worker.RunWorkerAsync(tcptuning); locEvClient = new EventClient(); locEvClient.Connect(new[] { "config", "fetching", "archives" }, PropertyUpdate, ShowError, UpdateLocalConnectionStatus); LoadAndRunConfiguration(); // если запускает пользователь сам if (Environment.UserInteractive) { var s = WcfEventService.EventService; s.Start(); try { Console.WriteLine($"{mif.ReadString("integrator", "descriptor", "Unknown program")}, ver {mif.ReadString("integrator", "version", "unknown")}"); Console.WriteLine(); Console.WriteLine("Type any key to exit"); Console.ReadKey(); } finally { s.Stop(); } } else { // запуск в виде службы Windows var servicesToRun = new ServiceBase[] { new WinService() }; ServiceBase.Run(servicesToRun); } // выгрузка фонового процесса при окончании работы сервиса worker.CancelAsync(); }
private static void FetchParameters(List <AskParamData> fetchParams, BackgroundWorker worker, TcpTuning parameters, IPEndPoint remoteEp, List <AskParamData> list) { try { using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { socket.SendTimeout = parameters.SendTimeout; socket.ReceiveTimeout = parameters.ReceiveTimeout; socket.Connect(remoteEp); Thread.Sleep(500); if (socket.Connected) { foreach (var item in list) { socket.Send(PrepareFetchParam(item.Node, item.Func, item.RegAddr, item.TypeValue)); Thread.Sleep(500); var buff = new byte[8192]; var numBytes = socket.Receive(buff); if (numBytes > 0) { var answer = CleanAnswer(buff); if (CheckAnswer(answer, item.Node, item.Func, item.TypeValue)) { var result = EncodeFetchAnswer(answer, item.Node, item.Func, item.RegAddr, item.TypeValue, item.TypeSwap, item.EU); if (item.LastValue != result.Value) { item.LastValue = result.Value; var pointname = item.ParamName; var propname = "PV"; var value = result.Value; locEvClient.UpdateProperty("fetching", $"{item.Prefix}\\{pointname}", propname, value); } } } } socket.Disconnect(false); } } } catch (Exception ex) { worker.ReportProgress(-1, ex.Message); } }
static void LoadAndRunConfiguration() { var roots = "sources;sockets"; foreach (var root in roots.Split(';')) { // загрузка корневых разделов foreach (var socketName in mif.ReadSectionValues(root)) { if (mif.KeyExists(socketName, "IpPort")) ModbusIntegratorEventService.SetPropValue("config", socketName, "IpPort", mif.ReadString(socketName, "IpPort", "502")); var itemName = socketName; ModbusIntegratorEventService.SetPropValue("config", "add", itemName, itemName); var section = $"{socketName}_nodes"; // загрузка узлов текущего раздела foreach (var nodeName in mif.ReadSectionValues(section)) { itemName = $"{socketName}\\{mif.ReadString(section, nodeName, nodeName)}"; ModbusIntegratorEventService.SetPropValue("config", "add", itemName, nodeName); // загрузка общих параметров настройки узла foreach (var key in mif.ReadSectionKeys(nodeName)) { var pointname = $"{socketName}\\{nodeName}"; var propname = key; var value = mif.ReadString(nodeName, key, ""); ModbusIntegratorEventService.SetPropValue("config", pointname, propname, value); } // загрузка форматов перестановки байтов (для Modbus устройств) var swapFormats = new Dictionary<string, string>(); foreach (var key in mif.ReadSectionKeys($"{nodeName}_SwapFormats")) swapFormats.Add(key, mif.ReadString($"{nodeName}_SwapFormats", key, "")); byte.TryParse(mif.ReadString(nodeName, "ModbusNode", "247"), out byte modbusNode); // заполнение списка параметров опроса var fetchParams = new List<AskParamData>(); var suffix = "FetchParams"; var paramsSection = $"{nodeName}_{suffix}"; FillFetchParameters(socketName, nodeName, swapFormats, modbusNode, fetchParams, suffix, paramsSection); // заполнение списка параметров конфигурации var fetchParamsSection = $"{nodeName}_{suffix}"; FillConfigParameters(socketName, nodeName, suffix, fetchParamsSection); var fetchArchives = new List<AskParamData>(); var archives = "HourArchive;DayArchive;MonthArchive".Split(';'); // загрузка секций настройки архивирования для узла (часовых, суточных и месячных) foreach (var archiveName in archives) { // заполнение списка параметров опроса var archivesSection = $"{nodeName}_{archiveName}"; suffix = $"archives\\{archiveName}"; FillFetchParameters(socketName, nodeName, swapFormats, modbusNode, fetchArchives, suffix, archivesSection); // заполнение списка параметров конфигурации var archiveSection = $"{nodeName}_{archiveName}"; FillConfigParameters(socketName, nodeName, suffix, archiveSection); } // проверка настройки включения узла var actived = mif.ReadString(nodeName, "Active", "false").ToLower() == "true"; var modbusTcp = actived && mif.ReadString(nodeName, "LinkProtokol", "false").ToLower() == "modbus tcp"; if (modbusTcp && IPAddress.TryParse(mif.ReadString(nodeName, "IpAddress", "127.0.0.1"), out IPAddress ipAddr) && int.TryParse(mif.ReadString(nodeName, "IpPort", "502"), out int ipPort) && int.TryParse(mif.ReadString(nodeName, "SendTimeout", "5000"), out int sendTimeout) && int.TryParse(mif.ReadString(nodeName, "ReceiveTimeout", "5000"), out int receiveTimeout)) { // запуск потока для обработки устройства по протоколу Modbus Tcp var worker = new BackgroundWorker { WorkerSupportsCancellation = true, WorkerReportsProgress = true }; workers.Add(worker); worker.DoWork += ModbusWorker_DoWork; worker.RunWorkerCompleted += ModbusWorker_RunWorkerCompleted; worker.ProgressChanged += ModbusWorker_ProgressChanged; var tcptuning = new TcpTuning { Address = ipAddr, Port = ipPort, SendTimeout = sendTimeout, ReceiveTimeout = receiveTimeout, FetchParams = fetchParams, FetchArchives = fetchArchives }; worker.RunWorkerAsync(tcptuning); } } } } }