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);
            }
        }
예제 #3
0
        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);
                        }
                    }
                }
            }
        }