using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Text; using System.Threading; using System.IO; using System.Xml; using System.IO.BACnet; using System.Threading.Tasks; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using System.Text.RegularExpressions; using Quartz; using Quartz.Impl; namespace NetCore31BACNetTransfor { public class Program { static BacnetClient Bacnet_client; static AsyncUdpClient Udp_Client; static List DevicesList; static List DevicesListScan; //BACnet序号 static int udpId = 0; static String LocalBacIP="127.0.0.1"; static int LocalBacPort; //util.xml //common static String RunMode = "formal";// 运行模式,支持formal/debug,缺省为formal static String BreakPoint = "false";// 断点模式,是否启用断点存储模式 static String StorageClass = "CSV";// 断点存储格式,与BreakPoint组合使用 static String StoragePath = "D:";// 断点存储路径,预留 static String PointsFrom = "EXCEL";// pointList来源 static String IntervalType = "interval";// 整点:integral/ 间隔:interval static String CollectInterval = "20Second";// 采集周期,以Second/min为单位 static int SendCount = 10;// 最大上传报文条数 static String SendInterval = "1min";// 上传周期,以Second/min为单位 static int HandleDataThread = 1;// 报文解析线程数 static String BuildingQaurry = "manual";// 下发楼号来源 static String BuildingControl = null;// 下发指定楼号,与BuildingQaurry组合使用 static String WaitingTimeControl = "3Second";// 下发等待时间,以Second为单位 static String NodeMac = "1";// 节点网关 static String ReportVersion = "addtion";// 报文版本,配置为standard时发report版报文;配置为addtion时发reportaddtion版报文 //upload static String LocalUdpIP; static int LocalUdpPort; static String RemoteUdpIP; static int RemoteUdpPort; static String protocol = "bacnetipv2"; static Dictionary>> CollectorPointSetList = new Dictionary>>();// 存放下发的原始设定记录 static Dictionary>> CollectorPropertyValues = new Dictionary>>();// 存储collector各属性信息 static Dictionary> ProtocolCollectorList = new Dictionary>();// 存储各协议对应的采集列表 static Dictionary> Collector_Device_Point = new Dictionary>();// 存储各采集设备对应的点位信息 static Dictionary Meter_Protocol = new Dictionary();// 存储Meter与采集协议的对应 static Dictionary Meter_CollectorMAC = new Dictionary();// 存储Meter与采集设备网关的对应 static Dictionary Meter_SubPath = new Dictionary();// 定制,不维护 static Dictionary Meter_CollectorAddress = new Dictionary();// 存储Meter与采集设备地址的对应 static Dictionary Meter_Site = new Dictionary();// 存储Meter与地址(对接系统)的对应 static Dictionary Meter_Building = new Dictionary();// 存储Meter与楼号的对应 static Dictionary Meter_FunctionGroup = new Dictionary();// 存储Meter与功能号组的对应 static Dictionary Meter_Point = new Dictionary();// 存储Meter与点位的对应 static Dictionary Item_Point = new Dictionary();// 存储Item与点位的对应 static Dictionary RecordAddress = new Dictionary();// 存储数据地址 // static List RecordList = new ArrayList();// 存储数据列表 // static Dictionary> ReportList = new HashMap>();// 存储报文列表 // static Dictionary> Round_Static = new HashMap>();// 预留 static Dictionary Meter_Collector = new Dictionary();// 存储Meter与采集设备的对应 //static List CollectorProtocolGroup = new ArrayList();// 存储协议组列表 static Dictionary CollectorMAC_Meter = new Dictionary();// 存储Meter与采集设备网关的对应 static Dictionary SimulationDevicesMap = new Dictionary();// 存储模拟设备列表 static Dictionary PointTopic = new Dictionary();// 存储点位与topic对应,mqtt协议用到 static Dictionary PointQueue = new Dictionary();// 存储点位与queue对应,amqp协议队列模式用到 static Dictionary> PointExchange = new Dictionary>();// 存储点位与exchange对应,amqp协议路由模式用到 static Dictionary exchangeType = new Dictionary();// 存储路由类型,amqp协议路由模式用到 static Dictionary pointConvType = new Dictionary();// 存储点位解析类型,modbus-tcp协议用到 static Dictionary pointSlave = new Dictionary();// 存储点位SlaveID,modbus-tcp协议用到 static Dictionary pointAddress = new Dictionary();// 存储点位Address,modbus-tcp协议用到 static Dictionary>> FunctionPropertyValues = new Dictionary>>();// 存储功能号各属性信息 static Dictionary>> PointPropertyValues = new Dictionary>>();// 存储Point各属性信息 static Dictionary> Function_Old_New = new Dictionary>();// 存储新旧功能号对应 static Dictionary> Function_New_Old = new Dictionary>();// 存储新旧功能号对应 static Dictionary> Function_New_Site = new Dictionary>();// 存储功能号与地址(对接系统)对应 static Dictionary> Function_New_SubSite = new Dictionary>();// 存储功能号与二级地址(对接系统)对应 static Dictionary> Function_Old_Type = new Dictionary>();// 存储功能号与类型(对接系统)对应 static Dictionary> Function_New_Type = new Dictionary>();// 存储功能号与类型(对接系统)对应 static Dictionary> Function_New_Reverse = new Dictionary>();// 存储功能号与寄存器反转标记(对接系统)对应 static Dictionary> Function_Old_CONVType = new Dictionary>();// 存储功能号与数据解析类型(对接系统)对应 static Dictionary> Function_Old_Size = new Dictionary>();// 存储功能号与寄存器数量(对接系统)对应 static Dictionary> Function_Old_Radio = new Dictionary>();// 存储功能号与数据换算系数对应 static Dictionary> DataConvert = new Dictionary>();// 存储数据转换对应关系 static Dictionary> Function_New_DataConvert = new Dictionary>();// 存储功能号及数据转换的对应关系 static ListFunction_Threshold = new List();//存储阈值和function_id之间关系 static List RecordList = new List();// 存储数据列表 static int GetCurrentUdpId() { udpId++; if (udpId >= 65536) udpId = 1; return udpId; } //BACnet序号 static byte invokeId = 0; static byte GetCurrentInvokeId() { invokeId++; if (invokeId >= byte.MaxValue) invokeId = 1; return invokeId; } //心跳 static int HeartBeatIndex = 0; static int GetHeartBeatIndex() { HeartBeatIndex++; if (HeartBeatIndex == int.MaxValue) HeartBeatIndex = 0; return HeartBeatIndex; } public static void Main(string[] args) { Logger.Log("Begin Translate BACnet Datas"); Init(args); } class SendMessageJob : IJob { /// /// 创建要执行的作业 /// /// /// public async Task Execute(IJobExecutionContext context) { await Task.Run(() => { Console.WriteLine("你好啊!"); }); } } public static void Show() { //创建调度单元 Task tsk = StdSchedulerFactory.GetDefaultScheduler(); IScheduler scheduler = tsk.Result; //2.创建一个具体的作业即job (具体的job需要单独在一个文件中执行) IJobDetail job = JobBuilder.Create().WithIdentity("完成").Build(); //3.创建并配置一个触发器即trigger 1s执行一次 ITrigger _CronTrigger = TriggerBuilder.Create() .WithIdentity("定时确认") .WithCronSchedule("0/2 * * * * ?") //秒 分 时 某一天 月 周 年(可选参数) .Build() as ITrigger; //4.将job和trigger加入到作业调度池中 scheduler.ScheduleJob(job, _CronTrigger); //5.开启调度 scheduler.Start(); Console.ReadLine(); } static void Init(string[] args) { try { Settings.InitSettings(args); LoadSettingFromXML(Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "util.xml")); LoadSettingFromExcel(Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "setting.xls")); LoadPointsFromExcel(Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "pointlist.xls"), protocol); // InitBacnet_client(); Thread.Sleep(50 * 1000); if (Settings.RollCall) { //List iplist = new List(); //foreach (var list in Collector_Device_Point) //{ // foreach (var list1 in list.Value) // { // Console.WriteLine(list1); // String listStr = list1.ToString().Split(",")[0]; // listStr = listStr.Split("[")[1]; // String[] listinfo = listStr.Split("-"); // for (int i = 0; i < listinfo.Count(); i++) { // Console.WriteLine(listinfo[1]); // if (IsNumStr(listinfo[1])) { // iplist.Add(listinfo[1]); // } // } // //var targetObjId = new BacnetObjectId(BacnetObjectTypes.OBJECT_DEVICE, (uint)10); // //var targetBacnetAddress = new BacnetAddress(BacnetAddressTypes.IP, "192.168.1.1"); // //var rez = Bacnet_client.ReadPropertyAsync(targetBacnetAddress, targetObjId, BacnetPropertyIds.PROP_OBJECT_LIST); // //rez.ContinueWith((sender) => // //{ // // var result = sender.Result; // // foreach (var item in result) // // { // // //do stuff // // Console.WriteLine(item.Value); // // } // //}); // //String ip = list1.ToString().Split(":")[0]; // //ip = ip.Split("[")[1]; // //iplist.Add(ip); // } //} //var ipdist = (from li in iplist select li).Distinct(); //iplist = ipdist.OrderBy(s => int.Parse(Regex.Match(s, @"^\d+$").Value)).ToList(); //foreach (var i in iplist) { // Console.WriteLine(i); //} var thread = new Thread(() => ForEachBacnet_client()); thread.Start(); } else { var thread = new Thread(() => InitBacnet_client()); thread.Start(); // InitBacnet_client(); } InitUdp_Client(); //等待扫描,尽量多等一会 Thread.Sleep(5*60*1000); Task.Factory.StartNew(BeginScanBac); Task.Factory.StartNew(BeginHeartBeat); } catch (Exception exp) { Logger.Error("Init: ", exp); } } private static void ForEachBacnet_client() { while (true) { InitBacnet_clientRollCall(); Thread.Sleep(30*60*1000); } } static void InitBacnet_clientRollCall() { try { // Bacnet_client = new BacnetClient(new BacnetIpUdpProtocolTransport(Settings.LocalBacPort, false)); Bacnet_client = new BacnetClient(new BacnetIpUdpProtocolTransport(LocalBacPort, false, false, 1472, LocalBacIP)); Bacnet_client.OnIam -= new BacnetClient.IamHandler(handler_OnIam1); Bacnet_client.OnIam += new BacnetClient.IamHandler(handler_OnIam1); // Bacnet_client.Iam(999999); Bacnet_client.Start(); Bacnet_client.WhoIs(); } catch (Exception exp) { Logger.Error("InitBacnet_clientRollCall: ", exp); } } static void handler_OnIam1(BacnetClient sender, BacnetAddress adr, uint deviceId, uint maxAPDU, BacnetSegmentations segmentation, ushort vendorId) { try { if (IsDetecteDeviceFinished) return; if (DevicesListScan == null) DevicesListScan = new List(); lock (DevicesListScan) { if (DevicesListScan.Any(x => x.DeviceId == deviceId)) return; var device = new BacDevice(adr, deviceId); string ip = Regex.Split(System.Convert.ToString(device.Address), ":", RegexOptions.IgnoreCase)[0]; Console.WriteLine("Chack_ip: " + ip + ", " + Collector_Device_Point.ContainsKey(Convert.ToString(ip))); if (!Collector_Device_Point.ContainsKey(Convert.ToString(ip))) { return; } if (Settings.Localdebug) { Logger.Log(@"Detect Device: " + ip + " " + deviceId); } else { Console.WriteLine(@"Detect Device: " + ip + " " + deviceId); } device.LoadProperties(device.DeviceId, Collector_Device_Point[Convert.ToString(ip)]); //device.LoadPropertiesFromExcel(Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "\\" + Constants.AimExcelDir, "" + deviceId + ".xls")); DevicesListScan.Add(device); } } catch (Exception exp) { Logger.Error("handler_OnIam", exp); //InitBacnet_client(); //InitUdp_Client(); } } private static void LoadPointsFromExcel(string file, string protocol) { Dictionary> sheetData = readExcel(Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "pointlist.xls"), protocol); excuteDataConvert(sheetData); excuteFunctions(sheetData); excutePoints(sheetData); } public static BacnetAddress ConvertIP(System.Net.IPEndPoint ep) { BacnetAddress addr; byte[] tmp1 = ep.Address.GetAddressBytes(); byte[] tmp2 = BitConverter.GetBytes((ushort)ep.Port); Array.Reverse(tmp2); Array.Resize(ref tmp1, tmp1.Length + tmp2.Length); Array.Copy(tmp2, 0, tmp1, tmp1.Length - tmp2.Length, tmp2.Length); addr = new BacnetAddress(BacnetAddressTypes.IP, 0, tmp1); return addr; } private static void excutePoints(Dictionary> sheetData) { int begin = 65535; int sbegin = 65535; int end = 65535; CollectorPropertyValues.Add(protocol, new Dictionary>()); CollectorPointSetList.Add(protocol, new Dictionary>()); Dictionary> ps = new Dictionary>(); List CollectorList = new List(); Dictionary collectorPty = new Dictionary(); Dictionary collectorPtyValue = new Dictionary(); Dictionary pointPty = new Dictionary(); Dictionary pointPtyValue = new Dictionary(); Collector group = new Collector(); String collectorName = ""; for (int i = 0; i <= sheetData.Count; i++) { if (!sheetData.ContainsKey(i)) { continue; } Dictionary rowData = sheetData[i]; if (rowData.ContainsKey(0) && "Collector".Equals(rowData[0])) { // Constant.info("Collector begin: " + i); begin = i; sbegin = 65535; for (int j = 1; j < rowData.Count; j++) { if (collectorPty.ContainsKey(rowData[j])) { collectorPty[rowData[j]] = j; } else { collectorPty.Add(rowData[j], j); } if (collectorPtyValue.ContainsKey(j)) { collectorPtyValue[j] = rowData[j]; } else { collectorPtyValue.Add(j, rowData[j]); } } } else if (rowData.ContainsKey(0) && "Point".Equals(rowData[0])) { // Constant.info("Point begin: " + i); sbegin = i; for (int j = 1; j < rowData.Count; j++) { if (pointPty.ContainsKey(rowData[j])) { pointPty[rowData[j]] = j; } else { pointPty.Add(rowData[j], j); } if (pointPtyValue.ContainsKey(j)) { pointPtyValue[j] = rowData[j]; } else { pointPtyValue.Add(j, rowData[j]); } } } else if (rowData.ContainsKey(0) && (rowData[0].Length > 0) && !("Point".Equals(rowData[0]))) { // Constant.info("Collector end: " + i); end = i; begin = 65535; sbegin = 65535; end = 65535; collectorPty = new Dictionary(); collectorPtyValue = new Dictionary(); pointPty = new Dictionary(); pointPtyValue = new Dictionary(); group = new Collector(); } else if (i > sbegin && i < end) { if (rowData.ContainsKey(1) && rowData[1].Length > 0) { // Constant.info("Point add: " + i); Dictionary deviceList = new Dictionary(); Point point = new Point(); Meter_Protocol.Add(rowData[pointPty["MeterSign"]], protocol); Meter_CollectorMAC.Add(rowData[pointPty["MeterSign"]], group.MAC); Meter_Collector.Add(rowData[pointPty["MeterSign"]], group); //CollectorMAC_Meter[group.MAC] = rowData[pointPty["MeterSign"]]; //CollectorMAC_Meter.Add(group.MAC, rowData[pointPty["MeterSign"]]); Meter_Site.Add(rowData[pointPty["MeterSign"]], !pointPty.ContainsKey("Site") ? "0" : rowData[pointPty["Site"]]); Meter_SubPath.Add(rowData[pointPty["MeterSign"]], !pointPty.ContainsKey("SubPath") ? "null" : rowData[pointPty["SubPath"]]); Meter_Building.Add(rowData[pointPty["MeterSign"]], rowData[pointPty["BuildingSign"]]); Meter_FunctionGroup.Add(rowData[pointPty["MeterSign"]], rowData[pointPty["Functions_Group"]]); String deviceSite = ""; if (pointPty.ContainsKey("MAC") && rowData[pointPty["MAC"]] != null && rowData[pointPty["MAC"]] != null && rowData[pointPty["MAC"]].ToString().Length > 0) { deviceSite = rowData[pointPty["MAC"]].ToString(); Meter_CollectorMAC.Add(rowData[pointPty["MeterSign"]], rowData[pointPty["MAC"]].ToString()); //CollectorMAC_Meter.Add(rowData[pointPty["MAC"]].ToString(),rowData[pointPty["MeterSign"]]); } else { deviceSite = (!pointPty.ContainsKey("BusNo") ? "0" : rowData[pointPty["BusNo"]]) + "-" + (!pointPty.ContainsKey("Site") ? "0" : rowData[pointPty["Site"]]); deviceSite = (!pointPty.ContainsKey("BusNo") || !pointPty.ContainsKey("Site")) ? rowData[pointPty["MeterSign"]] : deviceSite; } point.Item = !pointPty.ContainsKey("Item") ? "null" : rowData[pointPty["Item"]]; point.buildingSign = rowData[pointPty["BuildingSign"]]; point.meterSign = rowData[pointPty["MeterSign"]]; point.deviceId = !pointPty.ContainsKey("DeviceId") ? "null" : rowData[pointPty["DeviceId"]]; point.type = !pointPty.ContainsKey("Type") ? "null" : rowData[pointPty["Type"]]; point.instanceNumber = !pointPty.ContainsKey("InstanceNumber") ? "null" : rowData[pointPty["InstanceNumber"]]; Function f = new Function(); point.funcGroupID = !pointPty.ContainsKey("Functions_Group") ? "null" : rowData[pointPty["Functions_Group"]]; f.functionID = int.Parse(point.funcGroupID); point.functionList.Add(f); // point.functionList.Add(int.Parse(!pointPty.ContainsKey("Functions_Group") ? "null" : rowData[pointPty["Functions_Group"]])); //foreach (String function in Function_New_Old[rowData[pointPty["Functions_Group"]]].Keys) //{ // Function f = new Function(); // f.functionID = int.Parse(function); // point.functionList.Add(f); //} Meter_Point.Add(point.meterSign, point); //Item_Point.Add(point.Item, point); deviceSite = group.IP + ":" + group.Port + "-" + point.deviceId + "-" + point.type + "-" + point.instanceNumber; if (Settings.Localdebug) { Logger.Log("deviceSite: " + deviceSite); } deviceList.Add(deviceSite, point); //if (!Settings.RollCall) { // IPAddress address = IPAddress.Parse(group.IP); // IPEndPoint endpoint = new IPEndPoint(address, group.Port); // BacDevice item = new BacDevice(ConvertIP(endpoint), uint.Parse(point.deviceId)); // DevicesList.Add(item); //} if (Collector_Device_Point.ContainsKey(group.IP)) { foreach (KeyValuePair kv in deviceList) { Collector_Device_Point[group.IP].Add(kv.Key, kv.Value); if (Settings.Localdebug) { Logger.Log("1_group.IP" + group.IP + " kv.Key: " + kv.Key + " kv.Value: " + kv.Value.ToString()); } } } else { Collector_Device_Point.Add(group.IP, deviceList); if (Settings.Localdebug) { Logger.Log("2_group.IP" + group.IP + " deviceList: " + deviceList.ToString()); } } PointPropertyValues[collectorName].Add(point.buildingSign + "-" + point.meterSign, new Dictionary()); for (int j = 1; j < rowData.Count; j++) { PointPropertyValues[collectorName] [point.buildingSign + "-" + point.meterSign] .Add(pointPtyValue[j], rowData[j]); } } } else if (i > begin && i < end) { if (rowData.ContainsKey(1) && rowData[1].Length > 0) { // Constant.info("Collector add: " + i); Collector collector = new Collector(); collector.IP = !collectorPty.ContainsKey("IP") ? "null" : rowData[(collectorPty[("IP")])]; collector.Port = int.Parse( !collectorPty.ContainsKey("Port") ? "0" : rowData[(collectorPty[("Port")])]); collector.User = !collectorPty.ContainsKey("User") ? "null" : rowData[(collectorPty[("User")])]; collector.Password = !collectorPty.ContainsKey("Password") ? "null" : rowData[(collectorPty[("Password")])]; collector.ProgId = !collectorPty.ContainsKey("ProgId") ? "null" : rowData[(collectorPty[("ProgId")])]; collector.BroadcastAddress = !collectorPty.ContainsKey("BroadcastAddress") ? "null" : rowData[(collectorPty[("BroadcastAddress")])]; collector.MAC = !collectorPty.ContainsKey("MAC") ? "null" : rowData[(collectorPty[("MAC")])]; collector.PROTOCOL = !collectorPty.ContainsKey("PROTOCOL") ? "UDP" : rowData[(collectorPty[("PROTOCOL")])]; collector.Mode = !collectorPty.ContainsKey("Mode") ? "mina" : rowData[(collectorPty[("Mode")])]; collector.Max_size = int.Parse(!collectorPty.ContainsKey("Max_size") ? "1000" : rowData[(collectorPty[("Max_size")])]); collector.SqlContent = !collectorPty.ContainsKey("SqlContent") ? "null" : rowData[(collectorPty[("SqlContent")])]; group = collector; if (collectorPty.ContainsKey("IP")) { collectorName = rowData[(collectorPty[("IP")])]; } else if (collectorPty.ContainsKey("url")) { collectorName = rowData[(collectorPty[("url")])]; } else if (collectorPty.ContainsKey("MAC")) { collectorName = rowData[(collectorPty[("MAC")])]; } // collectorName = collectorPty.containsKey("IP") ? // rowData.get(collectorPty.get("IP")) // : rowData.get(collectorPty.get("url")); collector.Name = collectorName; CollectorList.Add(collector); if (CollectorPropertyValues[(protocol)].ContainsKey(collectorName)) { CollectorPropertyValues[(protocol)][collectorName] = new Dictionary(); } else { CollectorPropertyValues[(protocol)].Add(collectorName, new Dictionary()); } if (PointPropertyValues.ContainsKey(collectorName)) { PointPropertyValues[collectorName] = new Dictionary>(); } else { PointPropertyValues.Add(collectorName, new Dictionary>()); } if (ps.ContainsKey(collector.IP)) { ps[collector.IP] = new List(); } else { ps.Add(collector.IP, new List()); } for (int j = 1; j < rowData.Count; j++) { CollectorPropertyValues[(protocol)][(collectorName)] .Add(collectorPtyValue[j], rowData[j]); } } } } CollectorPointSetList[protocol] = ps; ProtocolCollectorList[protocol] = CollectorList; //CollectorPointSetList.Add(protocol, ps); //ProtocolCollectorList.Add(protocol, CollectorList); } private static void excuteFunctions(Dictionary> sheetData) { int begin = 65535; int sbegin = 65535; int end = 65535; Dictionary functionPty = new Dictionary(); Dictionary functionPtyValue = new Dictionary(); String group = ""; for (int i = 0; i <= sheetData.Count; i++) { if (!sheetData.ContainsKey(i)) { continue; } Dictionary rowData = sheetData[i]; if (rowData.ContainsKey(0) && "Threshold".Equals(rowData[0])) { begin = i; sbegin = 65535; // Logger.Log("Functions begin: " + i); } else if (rowData.ContainsKey(0) && "Function".Equals(rowData[0])) { sbegin = i; // Logger.Log("Function begin: " + i); //for (int j = 1; j < rowData.Count; j++) //{ // functionPty.Add(rowData[j], j); // functionPtyValue.Add(j, rowData[j]); //} } else if (rowData.ContainsKey(0) && (rowData[0].Length > 0) && !("Function".Equals(rowData[0]))) { end = i; begin = 65535; sbegin = 65535; end = 65535; functionPty = new Dictionary(); functionPtyValue = new Dictionary(); group = ""; // Logger.Log("Functions end: " + i); } else if (i > sbegin && i < end) { //if (rowdata.containskey(1) && rowdata[1].length > 0) //{ // // logger.log("function add: " + i); // string function_new = rowdata[functionpty["new"]]; // string function_old = rowdata[functionpty["old"]]; // // function // string function = function_new; // // dataconvert_group // string dataconvert_group = !functionpty.containskey("dataconvert_group") ? "null" // : rowdata[functionpty["dataconvert_group"]]; // function_old_new[group].add(function_old, function_new); // function_new_old[group].add(function_new, function_old); // if (!dataconvert.containskey(dataconvert_group)) // { // function_new_dataconvert.add(function_new, null); // } // else // { // function_new_dataconvert.add(function_new, dataconvert[dataconvert_group]); // } // function_new_site[group].add(function_new, !functionpty.containskey("site") ? "0" // : rowdata[functionpty["site"]]); // function_new_subsite[group].add(function_new, !functionpty.containskey("subsite") // ? "0" : rowdata[functionpty["subsite"]]); // function_old_type[group].add(function_old, // !functionpty.containskey("type") ? "double" : rowdata[functionpty["type"]]); // function_new_type[group].add(function_new, // !functionpty.containskey("type") ? "double" : rowdata[functionpty["type"]]); // function_new_reverse[group].add(function_new, // !functionpty.containskey("reverse") ? "false" : rowdata[functionpty["reverse"]]); // function_old_convtype[group].add(function_old, // !functionpty.containskey("convtype") ? "0" : rowdata[functionpty["convtype"]]); // function_old_size[group].add(function_old, // !functionpty.containskey("size") ? "1" : rowdata[functionpty["size"]]); // function_old_radio[group].add(function_old, // !functionpty.containskey("radio") ? "1" : rowdata[functionpty["radio"]]); // functionpropertyvalues[group].add(function, new dictionary()); // for (int j = 1; j < rowdata.count; j++) // { // functionpropertyvalues[group][function].add(functionptyvalue[j], // rowdata[j]); // } //} } else if (i > begin && i < end) { if (rowData.ContainsKey(1) && rowData[1].Length > 0) { Function_Threshold.Add(rowData[1].Trim() + ","+rowData[2].Trim() + "," + rowData[3].Trim()); } //if (rowData.ContainsKey(1) && rowData[1].Length > 0) //{ // // Logger.Log("Functions add: " + i); // group = rowData[1]; // Function_Old_New.Add(group, new Dictionary()); // Function_New_Old.Add(group, new Dictionary()); // Function_New_Site.Add(group, new Dictionary()); // Function_New_SubSite.Add(group, new Dictionary()); // Function_Old_Type.Add(group, new Dictionary()); // Function_New_Type.Add(group, new Dictionary()); // Function_New_Reverse.Add(group, new Dictionary()); // Function_Old_CONVType.Add(group, new Dictionary()); // Function_Old_Size.Add(group, new Dictionary()); // Function_Old_Radio.Add(group, new Dictionary()); // FunctionPropertyValues.Add(group, new Dictionary>()); //} } } //foreach (var a in Function_Threshold) { // Console.WriteLine(a); //} } private static void excuteDataConvert(Dictionary> sheetData) { int begin = 65535; int sbegin = 65535; int end = 65535; String group = ""; for (int i = 0; i <= sheetData.Count; i++) { if (!sheetData.ContainsKey(i)) { continue; } Dictionary rowData = sheetData[i]; if (!rowData.ContainsKey(0)) { continue; } if ("DataConvert".Equals(rowData[0])) { begin = i; sbegin = 65535; // Logger.Log("DataConvert begin: " + i); } else if ("Convert".Equals(rowData[0])) { sbegin = i; // Logger.Log("Convert begin: " + i); } else if ((rowData[0].Length > 0) && !("Convert".Equals(rowData[0]))) { begin = 65535; sbegin = 65535; end = 65535; group = ""; // Logger.Log("DataConvert end: " + i); } else if (i > sbegin && i < end) { if (!rowData.ContainsKey(1)) { continue; } if (rowData[1].Length > 0) { DataConvert[group].Add(rowData[1], rowData[2]); // Logger.Log("Convert add: " + i); } } else if (i > begin && i < end) { if (!rowData.ContainsKey(1)) { continue; } if (rowData[1].Length > 0) { DataConvert.Add(rowData[1], new Dictionary()); group = rowData[1]; // Logger.Log("DataConvert add: " + i); } } } } public static bool IsIP(string ip) { if (ip != null||!"".Equals(ip)) { //判断是否为IP return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$"); } return false; } public static bool IsNumStr(String theStr) { if (theStr != null||!"".Equals(theStr))//注意加非空判断,否则报错 { System.Text.RegularExpressions.Regex rex =new System.Text.RegularExpressions.Regex(@"^\d+$");//^开始,\d匹配一个数字字符,+出现至少一次,$结尾 if (rex.IsMatch(theStr)) { return true; } } return false; } private static bool CheckCellFormat(String SheetName, int rowNum , int colNum ,String cellContent) { if ("bacnetipv2".Equals(SheetName)) { if (colNum == 1 || colNum == 2 || colNum == 4 || colNum == 5) { if ("".Equals(cellContent) || IsIP(cellContent) || IsNumStr(cellContent) || "IP".Equals(cellContent) || "BuildingSign".Equals(cellContent) || "Port".Equals(cellContent) || "MeterSign".Equals(cellContent) || "DeviceId".Equals(cellContent) || "InstanceNumber".Equals(cellContent)|| "Functions_Group_ID".Equals(cellContent) ||"MIN".Equals(cellContent)||"MAX".Equals(cellContent)) { return true; } } else { return true; } } return false; } private static Dictionary> readExcel(string file, string sheetName) { Dictionary> result = new Dictionary>(); using (FileStream fp = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var book = new HSSFWorkbook(fp); for (int sheetNum = 0; sheetNum < book.NumberOfSheets; sheetNum++) { var sheet = book.GetSheetAt(sheetNum); if (sheetName.Equals(sheet.SheetName)) { if (Settings.Localdebug) { Logger.Log("Received:" + sheet.SheetName); } else { Console.WriteLine("Received:" + sheet.SheetName); } if (sheet.FirstRowNum < 0 || sheet.FirstRowNum >= sheet.LastRowNum) continue; for (var rowNum = sheet.FirstRowNum; rowNum <= sheet.LastRowNum; rowNum++) { try { var rowContent = sheet.GetRow(rowNum); result.Add(rowNum, new Dictionary()); if (rowContent != null) { if (rowContent.FirstCellNum < 0 || rowContent.FirstCellNum >= rowContent.LastCellNum || rowContent == null) continue; for (var colNum = rowContent.FirstCellNum; colNum <= rowContent.LastCellNum; colNum++) { try { DataFormatter formatter = new DataFormatter(); String cellContent = formatter.FormatCellValue(sheet.GetRow(rowNum).GetCell(colNum)); //var cellContent = rowContent.GetCell(colNum); if (CheckCellFormat(sheetName, (int)rowNum, (int)colNum, cellContent)) { result[rowNum].Add(colNum, cellContent); if (Settings.Localdebug) { Logger.Log("(" + (rowNum + 1) + "," + (colNum + 1) + ")=" + cellContent); } } else { Logger.Error("DataFormatterError_rowNum_In_Pointlist :" + (rowNum + 1) + ", colNum: " + (colNum + 1) + ", EMsg: " + cellContent.ToString()); } } catch (Exception exp) { if (Settings.Localdebug) { Logger.Error("DataFormatterError_rowNum:" + (rowNum + 1) + ", colNum: " + (colNum + 1) + ", EMsg: " + exp.ToString()); } } } } } catch (Exception exp) { } } } } } return result; } private static void LoadSettingFromXML(string file) { XmlDocument xml = new XmlDocument(); xml.Load(file); XmlNodeList nodeList; //RunMode nodeList = xml.SelectNodes("/root/RunMode"); foreach (XmlNode item in nodeList) { RunMode = item.InnerXml; } //BreakPoint nodeList = xml.SelectNodes("/root/BreakPoint"); foreach (XmlNode item in nodeList) { BreakPoint = item.InnerXml; } //StorageClass nodeList = xml.SelectNodes("/root/StorageClass"); foreach (XmlNode item in nodeList) { StorageClass = item.InnerXml; } //StoragePath nodeList = xml.SelectNodes("/root/StoragePath"); foreach (XmlNode item in nodeList) { StoragePath = item.InnerXml; } //PointsFrom nodeList = xml.SelectNodes("/root/PointsFrom"); foreach (XmlNode item in nodeList) { PointsFrom = item.InnerXml; } //IntervalType nodeList = xml.SelectNodes("/root/IntervalType"); foreach (XmlNode item in nodeList) { IntervalType = item.InnerXml; } //CollectInterval nodeList = xml.SelectNodes("/root/CollectInterval"); foreach (XmlNode item in nodeList) { CollectInterval = item.InnerXml; } //SendCount nodeList = xml.SelectNodes("/root/SendCount"); foreach (XmlNode item in nodeList) { SendCount = int.Parse(item.InnerXml); } //SendInterval nodeList = xml.SelectNodes("/root/SendInterval"); foreach (XmlNode item in nodeList) { SendInterval = item.InnerXml; } //HandleDataThread nodeList = xml.SelectNodes("/root/HandleDataThread"); foreach (XmlNode item in nodeList) { HandleDataThread = int.Parse(item.InnerXml); } //BuildingQaurry nodeList = xml.SelectNodes("/root/BuildingQaurry"); foreach (XmlNode item in nodeList) { BuildingQaurry = item.InnerXml; } //BuildingControl nodeList = xml.SelectNodes("/root/BuildingControl"); foreach (XmlNode item in nodeList) { BuildingControl = item.InnerXml; } //WaitingTimeControl nodeList = xml.SelectNodes("/root/WaitingTimeControl"); foreach (XmlNode item in nodeList) { WaitingTimeControl = item.InnerXml; } //NodeMac nodeList = xml.SelectNodes("/root/NodeMac"); foreach (XmlNode item in nodeList) { NodeMac = item.InnerXml; } //ReportVersion nodeList = xml.SelectNodes("/root/ReportVersion"); foreach (XmlNode item in nodeList) { ReportVersion = item.InnerXml; } //UploadList nodeList = xml.SelectNodes("/root/UploadList/Upload"); foreach (XmlNode item in nodeList) { XmlNodeList nodes; nodes = item.SelectNodes("IP"); foreach (XmlNode n in nodes) { LocalUdpIP = n.InnerXml; } nodes = item.SelectNodes("Port"); foreach (XmlNode n in nodes) { LocalUdpPort = int.Parse(n.InnerXml); } nodes = item.SelectNodes("ServerIP"); foreach (XmlNode n in nodes) { RemoteUdpIP = n.InnerXml; } nodes = item.SelectNodes("ServerPort"); foreach (XmlNode n in nodes) { RemoteUdpPort = int.Parse(n.InnerXml); } } } static void BeginHeartBeat() { var heartBeatInterval = Settings.HeartBeatInterval; while (true) { StringBuilder sb = new StringBuilder(); Thread.Sleep(heartBeatInterval); foreach (string building in Meter_Building.Values) { sb.AppendLine(SendUdpConn(building, GetCurrentUdpId())); break; } Thread.Sleep(1000); sb = new StringBuilder(); foreach (string building in Meter_Building.Values) { sb.AppendLine(SendUdpHeart(building, GetCurrentUdpId())); break; } Logger.Log(" ^ Heart Beat ^ " + GetHeartBeatIndex()); } } static void InitBacnet_client() { try { // Bacnet_client = new BacnetClient(new BacnetIpUdpProtocolTransport(Settings.LocalBacPort, false)); Bacnet_client = new BacnetClient(new BacnetIpUdpProtocolTransport(LocalBacPort, false, false, 1472, LocalBacIP)); Bacnet_client.OnIam -= new BacnetClient.IamHandler(handler_OnIam); Bacnet_client.OnIam += new BacnetClient.IamHandler(handler_OnIam); // Bacnet_client.Iam(999999); Bacnet_client.Start(); Bacnet_client.WhoIs(); //List iplist = new List(); //if (Settings.RollCall) //{ // foreach (var list in Collector_Device_Point) // { // foreach (var list1 in list.Value) // { // Console.WriteLine(list1); // //String ip = list1.ToString().Split(":")[0]; // //ip = ip.Split("[")[1]; // //iplist.Add(ip); // } // } // //var ipdist = (from li in iplist select li).Distinct(); // //foreach (var ip in ipdist) // //{ // // Console.WriteLine(ip); // // Bacnet_client.RemoteWhoIs(ip); // //} //} //else { // foreach (var list in Collector_Device_Point) // { // foreach (var list1 in list.Value) // { // Console.WriteLine(list1); // String listStr = list1.ToString().Split(",")[0]; // listStr = listStr.Split("[")[1]; // String[] listinfo = listStr.Split("-"); // for (int i = 0; i < listinfo.Count(); i++) // { // //Console.WriteLine(listinfo[1]); // if (IsNumStr(listinfo[1])) // { // iplist.Add(listinfo[1]); // } // } // //var targetObjId = new BacnetObjectId(BacnetObjectTypes.OBJECT_DEVICE, (uint)10); // //var targetBacnetAddress = new BacnetAddress(BacnetAddressTypes.IP, "192.168.1.1"); // //var rez = Bacnet_client.ReadPropertyAsync(targetBacnetAddress, targetObjId, BacnetPropertyIds.PROP_OBJECT_LIST); // //rez.ContinueWith((sender) => // //{ // // var result = sender.Result; // // foreach (var item in result) // // { // // //do stuff // // Console.WriteLine(item.Value); // // } // //}); // //String ip = list1.ToString().Split(":")[0]; // //ip = ip.Split("[")[1]; // //iplist.Add(ip); // } // } // var ipdist = (from li in iplist select li).Distinct(); // iplist = ipdist.OrderBy(s => int.Parse(Regex.Match(s, @"^\d+$").Value)).ToList(); // foreach (var i in iplist) // { // // Console.WriteLine(i); // Bacnet_client.WhoIs(int.Parse(i),int.Parse(i)); // Thread.Sleep(100); // } //} } catch (Exception exp) { Logger.Error("InitBacnet_client: ", exp); } } static void InitUdp_Client() { try { //本机节点 // var LocalUdpPort = Settings.LocalUdpPort; IPEndPoint localEP = new IPEndPoint(IPAddress.Parse(LocalUdpIP), LocalUdpPort); // 远程节点 //var RemoteUdpIP = IPAddress.Parse(Settings.RemoteUdpIP); //var RemoteUdpPort = Settings.RemoteUdpPort; IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(RemoteUdpIP), RemoteUdpPort); Udp_Client = new AsyncUdpClient(localEP, remoteEP, false, new NullLogger()); //Receive new Thread(new ThreadStart(() => { while (true) { var str = Udp_Client.PopReceive(); if (!string.IsNullOrEmpty(str)) { StringBuilder sb = new StringBuilder(); Logger.Log("Receive UdpCallback:" + str); string[] rList = Regex.Split(System.Convert.ToString(str), ";", RegexOptions.IgnoreCase); if ("pointcount".Equals(rList[2])) { sb = pointcount(rList); } else if ("pointlist".Equals(rList[2])) { sb = pointlist(rList); } else if ("senddownread".Equals(rList[2])) { sb = senddownread(rList); } else if ("senddownset".Equals(rList[2])) { sb = senddownset(rList); //BacnetObjectId oid = new BacnetObjectId(BacnetObjectTypes.OBJECT_ANALOG_INPUT, 0); //BacnetAddress adr; //BacnetPropertyIds propertyId = BacnetPropertyIds.PROP_PRESENT_VALUE; //BacnetValue[] NoScalarValue = {new BacnetValue(Convert.ToSingle(1))}; //byte invokeId = 0; //foreach (BacDevice device in DevicesList) //{ // bool result = Bacnet_client.WritePropertyRequest(device.Address, oid, propertyId, NoScalarValue, invokeId); //} } else if ("reportack".Equals(rList[2]) || "reportaddtionack".Equals(rList[2])) { } else if ("connectack".Equals(rList[2]) || "heartack".Equals(rList[2])) { } else { } Console.WriteLine("Slength: " + sb.Length + ",MSg: " + sb.ToString()); if (sb.Length > 0) { Udp_Client.PushSend(sb.ToString()); } } Thread.Sleep(100); } })).Start(); Udp_Client.Start(); } catch (Exception exp) { Logger.Error("InitUdp_Client: ", exp); } } private static StringBuilder senddownset(string[] rList) { //1101070037;1;senddownset;;123;1001;11;3.1 StringBuilder sb = new StringBuilder(); string buildingSign = rList[0]; string meterSign = rList[5]; string funcID = rList[6]; string dataSet = rList[7]; Point point = Meter_Point[meterSign]; bool unanimously = false; if (!RecordAddress.ContainsKey(buildingSign + "-" + meterSign + "-" + funcID)) { return null; } int address = RecordAddress[buildingSign + "-" + meterSign + "-" + funcID]; if (double.Parse(RecordList[address].data).Equals(double.Parse(dataSet))) { unanimously = true; } { if (unanimously) { if (Settings.Localdebug) { Logger.Log("Unanimously!" + " Buildingsign:" + buildingSign + ", Meter:" + meterSign + ", FunctionID:" + funcID + ", Data:" + RecordList[address].receivetime + " " + RecordList[address].data + ", DataSet:" + dataSet); sb.AppendWithSplit(rList[0]); sb.AppendWithSplit(rList[1]); sb.AppendWithSplit("senddownsetack"); sb.AppendWithSplit((DateTime.Now.ToString(@"yyyyMMddHHmmss"))); sb.AppendWithSplit(rList[4]); sb.AppendWithSplit(rList[5]); sb.AppendWithSplit(rList[6]); sb.AppendWithSplit("success"); //1101070037;1;senddownsetack;20010203040506;123;1001;11;success } else { Console.WriteLine("Unanimously!" + " Buildingsign:" + buildingSign + ", Meter:" + meterSign + ", FunctionID:" + funcID + ", Data:" + RecordList[address].receivetime + " " + RecordList[address].data + ", DataSet:" + dataSet); sb.AppendWithSplit(rList[0]); sb.AppendWithSplit(rList[1]); sb.AppendWithSplit("senddownsetack"); sb.AppendWithSplit((DateTime.Now.ToString(@"yyyyMMddHHmmss"))); sb.AppendWithSplit(rList[4]); sb.AppendWithSplit(rList[5]); sb.AppendWithSplit(rList[6]); sb.AppendWithSplit("success"); } } else { Collector c = Meter_Collector[meterSign]; if (c != null) { bool result = false; BacnetObjectId oid = new BacnetObjectId(getObjectType(point.type), uint.Parse(point.instanceNumber)); //BacnetAddress adr; BacnetPropertyIds propertyId = BacnetPropertyIds.PROP_PRESENT_VALUE; BacnetValue[] NoScalarValue = { new BacnetValue(Convert.ToSingle(double.Parse(dataSet))) }; byte invokeId = 0; foreach (BacDevice device in DevicesList) { if (Convert.ToString(device.Address).Equals(c.IP + ":" + c.Port)) { if (uint.Parse(Convert.ToString(device.DeviceId)).Equals(uint.Parse(point.deviceId))) { result = Bacnet_client.WritePropertyRequest(device.Address, oid, propertyId, NoScalarValue, invokeId); break; } } } if (result) { sb.AppendWithSplit(rList[0]); sb.AppendWithSplit(rList[1]); sb.AppendWithSplit("senddownsetack"); sb.AppendWithSplit((DateTime.Now.ToString(@"yyyyMMddHHmmss"))); sb.AppendWithSplit(rList[4]); sb.AppendWithSplit(rList[5]); sb.AppendWithSplit(rList[6]); sb.AppendWithSplit("success"); } else { sb.AppendWithSplit(rList[0]); sb.AppendWithSplit(rList[1]); sb.AppendWithSplit("senddownsetack"); sb.AppendWithSplit((DateTime.Now.ToString(@"yyyyMMddHHmmss"))); sb.AppendWithSplit(rList[4]); sb.AppendWithSplit(rList[5]); sb.AppendWithSplit(rList[6]); sb.AppendWithSplit("fail:error"); } } } } return sb; } private static BacnetObjectTypes getObjectType(String type) { // TODO Auto-generated method stub if ("analogInput".Equals(type)) { return BacnetObjectTypes.OBJECT_ANALOG_INPUT; } else if ("analogOutput".Equals(type)) { return BacnetObjectTypes.OBJECT_ANALOG_OUTPUT; } else if ("analogValue".Equals(type)) { return BacnetObjectTypes.OBJECT_ANALOG_VALUE; } else if ("binaryInput".Equals(type)) { return BacnetObjectTypes.OBJECT_BINARY_INPUT; } else if ("binaryOutput".Equals(type)) { return BacnetObjectTypes.OBJECT_BINARY_OUTPUT; } else if ("binaryValue".Equals(type)) { return BacnetObjectTypes.OBJECT_BINARY_VALUE; } else if ("multiStateInput".Equals(type)) { return BacnetObjectTypes.OBJECT_MULTI_STATE_INPUT; } else if ("multiStateOutput".Equals(type)) { return BacnetObjectTypes.OBJECT_MULTI_STATE_OUTPUT; } else if ("multiStateValue".Equals(type)) { return BacnetObjectTypes.OBJECT_MULTI_STATE_VALUE; } return BacnetObjectTypes.OBJECT_ANALOG_INPUT; } private static StringBuilder senddownread(string[] list) { // TODO Auto-generated method stub StringBuilder sb = new StringBuilder(); Record record = new Record(); record = getCacheData(list); sb.Append(list[0]).Append(";").Append(list[1]).Append(";").Append("senddownreadack").Append(";") .Append(record.receivetime).Append(";").Append(list[4]).Append(";") .Append(record.meterSign).Append(";").Append(record.funcID).Append(";").Append(record.data).Append(";"); return sb; } private static Record getCacheData(String[] list) { // TODO Auto-generated method stub Record record = new Record(); if (RecordAddress.ContainsKey(list[0] + "-" + list[5] + "-" + list[6])) { int address = RecordAddress[(list[0] + "-" + list[5] + "-" + list[6])]; record = RecordList[(address)]; // Constant.info("get pointread by address !"); } else { foreach (Record r in RecordList) { if (list[0].Equals(r.buildingSign) && list[5].Equals(r.meterSign) && int.Parse(list[6]).Equals(r.funcID)) { record = r; // Constant.info("get pointread by for circle !"); break; } } } return record; } private static StringBuilder pointlist(String[] list) { // TODO Auto-generated method stub int no = 0; int count = 0; int from = int.Parse(list[5]) * (int.Parse(list[7]) - 1); int to = int.Parse(list[5]) * (int.Parse(list[7])); StringBuilder sb = new StringBuilder(); sb.Append(list[0]).Append(";").Append(list[1]).Append(";").Append("pointlistack").Append(";;").Append(list[4]) .Append(";").Append(list[5]).Append(";").Append(list[6]).Append(";").Append(list[7]).Append(";"); if (to > getCount(list[0])) { count = getCount(list[0]) - from; } else { count = to - from; } sb.Append(count).Append(";"); foreach (var deviceList in Collector_Device_Point) { foreach (var device in deviceList.Value) { if (list[0].Equals(device.Value.buildingSign)) { foreach (Function function in device.Value.functionList) { no++; if (no < from) { continue; } if (no > to) { continue; } sb.Append(device.Value.meterSign).Append(";").Append(function.functionID).Append(";"); } } } } return sb; } private static StringBuilder pointcount(String[] list) { // TODO Auto-generated method stub StringBuilder sb = new StringBuilder(); sb.Append(list[0]).Append(";").Append(list[1]).Append(";").Append("pointcountack").Append(";;").Append(list[4]) .Append(";").Append(getCount(list[0])).Append(";"); return sb; } private static int getCount(String buildingSign) { // TODO Auto-generated method stub int count = 0; foreach (var deviceList in Collector_Device_Point) { foreach (var device in deviceList.Value) { if (buildingSign.Equals(device.Value.buildingSign)) { foreach (Function function in device.Value.functionList) { count++; } } } } return count; } //发现设备 static bool IsDetecteDeviceFinished = false; static void handler_OnIam(BacnetClient sender, BacnetAddress adr, uint deviceId, uint maxAPDU, BacnetSegmentations segmentation, ushort vendorId) { try { if (IsDetecteDeviceFinished) return; if (DevicesList == null) DevicesList = new List(); lock (DevicesList) { if (DevicesList.Any(x => x.DeviceId == deviceId)) return; var device = new BacDevice(adr, deviceId); string ip = Regex.Split(System.Convert.ToString(device.Address), ":", RegexOptions.IgnoreCase)[0]; Console.WriteLine("Chack_ip: " + ip + ", " + Collector_Device_Point.ContainsKey(Convert.ToString(ip))); if (!Collector_Device_Point.ContainsKey(Convert.ToString(ip))) { return; } if (Settings.Localdebug) { Logger.Log(@"Detect Device: " + ip + " " + deviceId); } else { Console.WriteLine(@"Detect Device: " + ip + " " + deviceId); } device.LoadProperties(device.DeviceId, Collector_Device_Point[Convert.ToString(ip)]); //device.LoadPropertiesFromExcel(Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "\\" + Constants.AimExcelDir, "" + deviceId + ".xls")); DevicesList.Add(device); } } catch (Exception exp) { Logger.Error("handler_OnIam", exp); //InitBacnet_client(); //InitUdp_Client(); } } static void LoadSettingFromExcel(string file) { try { if (!File.Exists(file)) return; using (FileStream fp = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var book = new HSSFWorkbook(fp); var sheet = book.GetSheetAt(0); var rowContent = sheet.GetRow(1); LocalBacIP = rowContent.GetCell(0).ToString(); LocalBacPort = Convert.ToInt32(rowContent.GetCell(1).ToString()); LocalUdpIP = rowContent.GetCell(2).ToString(); LocalUdpPort = Convert.ToInt32(rowContent.GetCell(3).ToString()); RemoteUdpIP = rowContent.GetCell(4).ToString(); RemoteUdpPort = Convert.ToInt32(rowContent.GetCell(5).ToString()); } } catch (Exception exp) { Logger.Error("BacDevice.LoadPropertiesFromExcel: ", exp); } } static void ThreadProc(Object device) { ScanBac((BacDevice)device); } //扫点 static void BeginScanBac() { try { Logger.Log("BeginScanBac"); IsDetecteDeviceFinished = true; if (Settings.RollCall) { InitBacnet_clientRollCall(); Thread.Sleep(Settings.WaitTime); if (DevicesListScan == null) return; } else { InitBacnet_client(); Thread.Sleep(Settings.WaitTime); if (DevicesList == null) return; } while (true) { DevicesListScan = DevicesListScan.Where(x => x != null).OrderBy(x => x.DeviceId).ToList(); foreach (var deviceScan in DevicesListScan) { if (DevicesList == null) { DevicesList = DevicesListScan; } if (!DevicesList.Contains(deviceScan)) { DevicesList.Add(deviceScan); } } DevicesList = DevicesList.Where(x => x != null).OrderBy(x => x.DeviceId).ToList(); foreach (var device in DevicesList) { ThreadPool.QueueUserWorkItem(o=> ThreadProc(device)); } try { Thread.Sleep(1000 * Settings.AcquisitionFrequency); } catch (Exception exp) { } } } catch (Exception exp) { Logger.Error("BeginScanBac_Error", exp); //BeginScanBac(); } } //扫点轮次 static int ScanIndex = 0; static void ScanBac(BacDevice device) { if (device == null || device.Address == null) return; StringBuilder sb = new StringBuilder(); try { if (Settings.Localdebug) { Logger.Log(" @DeviceScan " + device.Address + "-" + device.DeviceId + " Scan " //+ device.ScanIndex ); } else { Console.WriteLine(" @DeviceScan " + device.Address + "-" + device.DeviceId + " Scan " //+ device.ScanIndex ); } var adr = device.Address; var deviceid = device.DeviceId; List rList = new List(); rList.Add(new BacnetPropertyReference((uint)BacnetPropertyIds.PROP_PRESENT_VALUE, uint.MaxValue)); var group = device.Properties.Partition(Settings.BacSplitSize); foreach (var subGroup in group) { try { if (deviceid == 1) continue; List properties = subGroup.Select(pro => new BacnetReadAccessSpecification(pro.ObjectId, rList)).ToList(); IList lstAccessRst; //foreach (var item in properties) { // Logger.Error("Input_Address: " + adr + ",properties:" + item.propertyReferences.ToString()); //} var bRst = Bacnet_client.ReadPropertyMultipleRequest(adr, properties, out lstAccessRst, GetCurrentInvokeId()); Thread.Sleep(15 * Settings.AcquisitionFrequency); if (!bRst) continue; if (lstAccessRst == null || lstAccessRst.Count == 0) continue; //sb.AppendLine("=== properties.Count:" + properties.Count + " ,lstAccessRst.Count: " + lstAccessRst.Count); foreach (var aRst in lstAccessRst) { var bPValue = aRst.values.First(); if (bPValue.value == null || bPValue.value.Count == 0) continue; var bValue = bPValue.value.First(); var strBValue = "" + bValue.Value; if (Settings.Localdebug) { Logger.Log(" @ReceiveMsg: " + device.Address + "-" + device.DeviceId + "-" + getType(aRst.objectIdentifier.type) + "-" + aRst.objectIdentifier.instance + " " + strBValue); } //string addr = System.Convert.ToString(device.Address); //string[] sArray = Regex.Split(addr, ":", RegexOptions.IgnoreCase); string ip = Regex.Split(System.Convert.ToString(device.Address), ":", RegexOptions.IgnoreCase)[0]; //Logger.Log("ip: " + ip); Console.WriteLine("ip: " + ip); Console.WriteLine("RD1: " + !Collector_Device_Point.ContainsKey(ip)); Console.WriteLine("RD2: " + !Collector_Device_Point[ip].ContainsKey(device.Address + "-" + device.DeviceId + "-" + getType(aRst.objectIdentifier.type) + "-" + aRst.objectIdentifier.instance)); if (!Collector_Device_Point.ContainsKey(ip) || !Collector_Device_Point[ip].ContainsKey(device.Address + "-" + device.DeviceId + "-" + getType(aRst.objectIdentifier.type) + "-" + aRst.objectIdentifier.instance)) { continue; } Console.WriteLine("================"); Point point = Collector_Device_Point[ip][device.Address + "-" + device.DeviceId + "-" + getType(aRst.objectIdentifier.type) + "-" + aRst.objectIdentifier.instance]; Console.WriteLine("RD3:" + point.ToString()); // var pro = device.Properties.FirstOrDefault(x => x.ObjectId == aRst.objectIdentifier); // try { } catch (Exception e) { } BacProperty pro = device.Properties.FirstOrDefault(x => x.ObjectId == aRst.objectIdentifier); // Console.WriteLine("RD4:" + pro.ToString()); if (pro == null) continue; //值没变,忽略 //if (string.Equals(strBValue, pro.PROP_PRESENT_VALUE)) //{ // // sb.AppendLine($"值没变,忽略 {pro.PROP_DESCRIPTION} : { strBValue}"); // continue; //} // var preValue = pro.PROP_PRESENT_VALUE; var preValue = strBValue; //Logger.Log("RD5_0_strBValue:" + strBValue); // pro.PROP_PRESENT_VALUE = strBValue; //因为霍尼韦尔的误报,消防报警后面跟的故障报警暂时不报(临时) //if (string.Equals(strBValue, "3", StringComparison.CurrentCultureIgnoreCase) && // string.Equals(preValue, "2", StringComparison.CurrentCultureIgnoreCase)) //{ // //sb.AppendLine("因为霍尼韦尔的误报,消防报警后面跟的故障报警暂时不报(临时)"); // continue; //} //if (!Settings.IgnoreFirstValue || device.ScanIndex != 0)//初始值也转发 // { //sb.AppendLine(SendUdpMessage(pro, GetCurrentUdpId())); Console.WriteLine("RD5:" + preValue.Length +","+ preValue.ToString()); if (preValue != null && preValue.Length > 0) { Console.WriteLine(" @ConSole_ReceiveMsg: " + device.Address + "-" + device.DeviceId + "-" + getType(aRst.objectIdentifier.type) + "-" + aRst.objectIdentifier.instance + " " + strBValue); Thread.Sleep(Settings.AcquisitionFrequency*10); StringBuilder pFuncid = new StringBuilder(); foreach (var funcidlsit in point.functionList) { pFuncid.AppendWithSplit(funcidlsit.functionID); } var PFuncidStrArr = pFuncid.ToString().Trim().Split(";"); var PFuncidStr = PFuncidStrArr[0]; foreach (var funcT in Function_Threshold) { Console.WriteLine("PFuncidStr: "+ PFuncidStr + " ,funcT :"+ funcT +" ,bool: "+ funcT.Trim().IndexOf(PFuncidStr.Trim())); if (funcT.Trim().IndexOf(PFuncidStr.Trim())>-1) { String[] funcTArr = funcT.Trim().Split(","); Double min = Convert.ToDouble(int.Parse(funcTArr[1].Trim())); min = min * 1.000000; Double max = Convert.ToDouble(int.Parse(funcTArr[2].Trim())); max = max * 1.000000; Double pvalue = Double.Parse(preValue); Console.WriteLine("min: " + min + " ,max: " + max + " ,pvalue: " + pvalue + " ,first: " + isequal(min, max, pvalue)); if (isequal(min, max, pvalue)) { sb.AppendLine(SendUdpMessage(point, preValue, GetCurrentUdpId())); } else { continue; } } } } //} //sb.AppendLine("" + pro.PROP_OBJECT_NAME + " , " + strBValue + " ; "); } } catch (Exception exp) { if (Settings.Localdebug) { Logger.Error("ScanBac_1 Error: " + device.Address + "-" + device.DeviceId + "-" + exp.ToString()); } } } } catch (Exception exp) { if (Settings.Localdebug) { Logger.Error("ScanBac_2 Error: " + device.Address + " " + device.DeviceId + " " + exp); } } finally { if (Settings.Localdebug) { Logger.Log("finally: " + sb.ToString()); } else { Console.WriteLine("finally: " + sb.ToString()); } //扫描完一轮 ScanIndex++; if (ScanIndex == int.MaxValue) ScanIndex = 0; //device.ScanIndex = ScanIndex; // ScanBac(device); } } private static bool isequal(object a, object b, object c) { if (a == null || b == null) return (a == b); if (a == b) { return true; } double da, db, dc; if (Double.TryParse(a.ToString(), out da) && Double.TryParse(b.ToString(), out db)&& Double.TryParse(c.ToString(), out dc)) return DoubleEquals(da, db, dc); return false; } public static bool DoubleEquals(double value1, double value2,double value3) { //双精度误差 var DOUBLE_DELTA = 1E-6; //bool f = Math.Abs(value2 - value1) > DOUBLE_DELTA; bool f= (value3.CompareTo(value1)> DOUBLE_DELTA ? true : false) && (value3.CompareTo(value2)< DOUBLE_DELTA ? true: false) ; return f; } public static bool DoubleEqualsBak(double value1, double value2) { //双精度误差 var DOUBLE_DELTA = 1E-6; return value1 == value2 || Math.Abs(value1 - value2) < DOUBLE_DELTA; } static String getType(BacnetObjectTypes objectType) { if (objectType.Equals(BacnetObjectTypes.OBJECT_ANALOG_INPUT)) { return "analogInput"; } else if (objectType.Equals(BacnetObjectTypes.OBJECT_ANALOG_OUTPUT)) { return "analogOutput"; } else if (objectType.Equals(BacnetObjectTypes.OBJECT_ANALOG_VALUE)) { return "analogValue"; } else if (objectType.Equals(BacnetObjectTypes.OBJECT_BINARY_INPUT)) { return "binaryInput"; } else if (objectType.Equals(BacnetObjectTypes.OBJECT_BINARY_OUTPUT)) { return "binaryOutput"; } else if (objectType.Equals(BacnetObjectTypes.OBJECT_BINARY_VALUE)) { return "binaryValue"; } else if (objectType.Equals(BacnetObjectTypes.OBJECT_MULTI_STATE_INPUT)) { return "multiStateInput"; } else if (objectType.Equals(BacnetObjectTypes.OBJECT_MULTI_STATE_OUTPUT)) { return "multiStateOutput"; } else if (objectType.Equals(BacnetObjectTypes.OBJECT_MULTI_STATE_VALUE)) { return "multiStateValue"; } return null; } //上传UDP static string SendUdpMessage( BacProperty pro, int udpid = 0) { try { if (Udp_Client == null || string.IsNullOrEmpty(Settings.BuildingSign) || pro == null) return string.Empty; StringBuilder sb = new StringBuilder(); sb.AppendWithSplit(pro.building); sb.AppendWithSplit(Settings.Gateway); sb.AppendWithSplit(Settings.SendType); sb.AppendWithSplit(DateTime.Now.ToString(@"yyyyMMddHHmmss")); sb.AppendWithSplit(udpid == 0 ? GetCurrentUdpId() : udpid); sb.AppendWithSplit(pro.meter); sb.AppendWithSplit(1); sb.AppendWithSplit(pro.funcid); sb.Append(pro.PROP_PRESENT_VALUE); var str = sb.ToString(); // for (int i = 0; i < 5; i++) // { Udp_Client.PushSend(str); Thread.Sleep(100); // } return "SendUdpMessage: " + str; } catch (Exception exp) { Logger.Error("SendUdpMessage", exp); return string.Empty; } } private static void handleData(string buildingSign, string meterSign, long funcID, string receivetime, string data) { // 已有数据更新 if (RecordAddress.ContainsKey(buildingSign + "-" + meterSign + "-" + funcID) && RecordAddress[(buildingSign + "-" + meterSign + "-" + funcID)] > 0) { int address = RecordAddress[(buildingSign + "-" + meterSign + "-" + funcID)]; try { RecordList[(address)].receivetime = (receivetime); RecordList[(address)].data = data; if (Settings.Localdebug) { Logger.Log((address + 1) + "/" + RecordList.Count + " UPDATE " + RecordList[(address)].buildingSign + "." + RecordList[(address)].meterSign + "." + RecordList[(address)].funcID + ":" + receivetime + " " + RecordList[(address)].data); } else { Console.WriteLine((address + 1) + "/" + RecordList.Count + " UPDATE " + RecordList[(address)].buildingSign + "." + RecordList[(address)].meterSign + "." + RecordList[(address)].funcID + ":" + receivetime + " " + RecordList[(address)].data); } } catch (Exception e) { if (Settings.Localdebug) { Logger.Error("handleData_Error_1: " + e); } } } else { // 新增数据并记录地址 try { Record record = new Record(); record.buildingSign = buildingSign; record.meterSign = meterSign; record.funcID = System.Convert.ToString(funcID); record.receivetime = (receivetime); record.data = data; RecordAddress.Add(buildingSign + "-" + meterSign + "-" + funcID, RecordList.Count()); RecordList.Add(record); if (Settings.Localdebug) { Logger.Log(" " + RecordList.Count + "/" + RecordList.Count + " ADD " + record.buildingSign + "." + record.meterSign + "." + record.funcID + ":" + (record.receivetime) + " " + record.data); } else { Console.WriteLine(" " + RecordList.Count + "/" + RecordList.Count + " ADD " + record.buildingSign + "." + record.meterSign + "." + record.funcID + ":" + (record.receivetime) + " " + record.data); } } catch (Exception e) { // TODO Auto-generated catch block if (Settings.Localdebug) { Logger.Error("handleData_Error_2: " + e); } } } } static string SendUdpMessage(Point point, string value, int udpid = 0) { try { if (Udp_Client == null || string.IsNullOrEmpty(Settings.BuildingSign) || point == null) return string.Empty; StringBuilder sb = new StringBuilder(); string buildingSign = point.buildingSign; string meterSign = point.meterSign; string receivetime = DateTime.Now.ToString(@"yyyyMMddHHmmss"); sb.AppendWithSplit(buildingSign); sb.AppendWithSplit(Settings.Gateway); sb.AppendWithSplit(Settings.SendType); sb.AppendWithSplit(receivetime); sb.AppendWithSplit(udpid == 0 ? GetCurrentUdpId() : udpid); sb.AppendWithSplit(meterSign); sb.AppendWithSplit(point.functionList.Count); foreach (var funcid in point.functionList) { sb.AppendWithSplit(funcid.functionID); sb.Append(value); handleData(buildingSign, meterSign, funcid.functionID, receivetime, value); } var str = sb.ToString(); // for (int i = 0; i < 5; i++) // { Udp_Client.PushSend(str); Thread.Sleep(100); // } return "SendUdpMessage: " + str; } catch (Exception exp) { Logger.Error("SendUdpMessage", exp); return string.Empty; } } static string SendUdpHeart(string buildingSign, int udpid = 0) { try { if (Udp_Client == null) return string.Empty; StringBuilder sb = new StringBuilder(); //1101070037;1;heart sb.AppendWithSplit(buildingSign); sb.AppendWithSplit(Settings.Gateway); sb.AppendWithSplit("heart"); var str = sb.ToString(); Udp_Client.PushSend(str); Thread.Sleep(100); return "SendUdpHeart: " + str; } catch (Exception exp) { Logger.Error("SendUdpHeart", exp); return string.Empty; } } static string SendUdpConn(string buildingSign, int udpid = 0) { try { if (Udp_Client == null) return string.Empty; StringBuilder sb = new StringBuilder(); //1101070037;1;connect sb.AppendWithSplit(buildingSign); sb.AppendWithSplit(Settings.Gateway); sb.AppendWithSplit("connect"); var str = sb.ToString(); Udp_Client.PushSend(str); Thread.Sleep(100); return "SendUdpConn: " + str; } catch (Exception exp) { Logger.Error("SendUdpConn", exp); return string.Empty; } } } public class NullLogger : ILogger { public void Debug(string message) { } public void Error(string message) { } public void Fatal(string message) { } public void Info(string message) { } public void Warn(string message) { } } static class LinqExtensions { public static IEnumerable> Split(this IEnumerable items, int numOfParts) { int i = 0; return items.GroupBy(x => i++ % numOfParts); } public static IEnumerable> Partition(this IEnumerable items, int partitionSize) { int i = 0; return items.GroupBy(x => i++ / partitionSize).ToArray(); } } public class Collector { public String Name; public String IP; public int Port; public String User; public String Password; public String ProgId; public String BroadcastAddress; public String MAC; public String PROTOCOL; public String Mode; public int Max_size; public String SqlContent; } public class Point { public String MAC; public String Item; public String buildingSign; public String meterSign; public String deviceId; public String type; public String instanceNumber; public HashSet functionList = new HashSet(); //增加编辑定义函数分组 public String funcGroupID; } public class Function { public long functionID; public Dictionary DataConvert; } public class PointSet { public String uploadName; public String[] content; public String mac; public int ID; public double sendTime = 0; public double recTime = 0; public String status; public String buildingSign; public String buildingSignNew; public String meterSign; public int funcID; public String collectorMAC; public String cmd; public double dataSet; } public class Record { public String buildingSign; public String meterSign; public String funcID; public String receivetime; public String data; public String addtion; } }