diff --git a/langguanApi.xml b/langguanApi.xml index 0e9e02d..30ecfb0 100644 --- a/langguanApi.xml +++ b/langguanApi.xml @@ -472,7 +472,7 @@ - 获取清洁运输列表 + 清洁运输:获取门禁数据和详情 @@ -499,14 +499,14 @@ - 获取洗车机列表 + 洗车机:获取洗车机列表和右侧洗车状态等数据,默认右侧显示第一条的记录 - 获取洗车机历史记录(起始时间和结束时间非空,根据起始时间和结束时间筛选数据,如果为空,默认获取30条数据) + 洗车机:获取历史记录 和导出历史记录 @@ -520,7 +520,7 @@ - 获取清洁运输(门禁和地磅组合,地磅获取总重量,后期会用地磅重量-车辆车辆) + 清洁运输:获取清洁运输列表和饼图比例数据 @@ -759,6 +759,56 @@ 车牌类型 + + + 排放类型 + + + + + 清洁运输总记录 + + + + + 国五百分比 + + + + + 国五运输量百分比 + + + + + 国六百分比 + + + + + 国六运输量百分比 + + + + + 电动百分比 + + + + + 电动运输量百分比 + + + + + 其他百分比 + + + + + 其他运输量百分比 + + @@ -1957,7 +2007,7 @@ - 排放标准 + 排放标准(0-7是国1-7,D:电动 X:无排放阶段) @@ -2315,21 +2365,6 @@ 运行状态(RunStatus,0表示异常,1表示正常) - - - 水压报警(WPAlarm 0表示异常,1表示正常) - - - - - 相序报警(PSAlarm0表示异常,1表示正常) - - - - - 故障报警(FaultAlarm 0表示异常,1表示正常) - - 冲洗压力 @@ -2345,26 +2380,6 @@ 冲洗电压(RinseVoltage 单位V) - - - 水流量(Discharge 单位T) - - - - - 电量(Electricity KW/H) - - - - - 电流(Current A) - - - - - 水压(WaterPressure MPa) - - 洗车机编码 @@ -3146,7 +3161,7 @@ - 获取清洁运输列表(门禁和地磅组合) + 获取清洁运输趋势列表(门禁和地磅组合,地磅获取总重量,后期会用地磅重量-车辆车辆) @@ -3158,6 +3173,13 @@ + + + 排放标准(0-7是国1-7,D:电动 X:无排放阶段) + + + + 新加 @@ -3247,7 +3269,7 @@ - 获取洗车机历史记录 + 获取洗车机历史记录(起始时间和结束时间非空,根据起始时间和结束时间筛选数据,如果为空,默认获取30条数据) diff --git a/langguanApi/Controllers/HomeController.cs b/langguanApi/Controllers/HomeController.cs index cbcd0c7..cbcbafa 100644 --- a/langguanApi/Controllers/HomeController.cs +++ b/langguanApi/Controllers/HomeController.cs @@ -45,27 +45,8 @@ namespace langguanApi.Controllers { // 示例数据(需替换为实际接收到的协议数据) string hexData = "787811010868120321167279808D3202001AB12F0D0A"; - byte[] protocolData = HexStringToByteArray(hexData); - // 进行转义还原 - byte[] restoredData = RestoreEscape(protocolData); - - // 验证校验码 - if (!VerifyChecksum(restoredData)) - { - Console.WriteLine("Checksum verification failed."); - } - Position? position = ParsePosition(restoredData); - - if (position.HasValue) - { - Console.WriteLine($"Latitude: {position.Value.Latitude}"); - Console.WriteLine($"Longitude: {position.Value.Longitude}"); - Console.WriteLine($"Altitude: {position.Value.Altitude}"); - } - else - { - Console.WriteLine("Failed to parse position."); - } + byte[] loginPacket = BuildLoginPacket("123456789012345"); // 替换为实际的IMEI + // Console.WriteLine("经度:" + lon + " 纬度:" + lat); // string rawText = "数据报:##0250QN=20240424224800000;ST=22;CN=2011;PW=123456;MN=LGYC022024690001;Flag=5;CP=&&DataTime=20240424224800;a34001-Rtd=356.2"; @@ -108,58 +89,109 @@ namespace langguanApi.Controllers }; } - private static bool VerifyChecksum(byte[] data) + static byte[] BuildLoginPacket(string imei) { - // 校验码在数据包的倒数第二个字节 - byte receivedChecksum = data[data.Length - 2]; - byte calculatedChecksum = 0; - - // 校验范围是从第一个字节到倒数第三个字节 - for (int i = 0; i < data.Length - 2; i++) + using (MemoryStream ms = new MemoryStream()) { - calculatedChecksum ^= data[i]; + BinaryWriter writer = new BinaryWriter(ms); + + writer.Write(new byte[] { 0x78, 0x78 }); // 起始位 + writer.Write((byte)0x0D); // 包长度 + writer.Write((byte)0x01); // 协议号 + + byte[] imeiBytes = Encoding.ASCII.GetBytes(imei); + writer.Write(imeiBytes); + + writer.Write((short)0x0001); // 信息序列号 + + byte[] content = ms.ToArray(); + short crc = CalculateCRC(content, 2, content.Length - 2); + writer.Write(crc); // 错误校验 + + writer.Write(new byte[] { 0x0D, 0x0A }); // 停止位 + + return ms.ToArray(); } - - return receivedChecksum == calculatedChecksum; } - private static byte[] RestoreEscape(byte[] data) + static short CalculateCRC(byte[] data, int start, int length) { - List result = new List(); - for (int i = 0; i < data.Length; i++) + // CRC计算方法(参考协议中的CRC-ITU算法) + ushort crc = 0xFFFF; + + for (int i = start; i < start + length; i++) { - if (data[i] == 0x7D) + crc = (ushort)(crc ^ (data[i] << 8)); + + for (int j = 0; j < 8; j++) { - if (i + 1 < data.Length) + if ((crc & 0x8000) != 0) { - if (data[i + 1] == 0x02) - { - result.Add(0x7E); - i++; - } - else if (data[i + 1] == 0x01) - { - result.Add(0x7D); - i++; - } + crc = (ushort)((crc << 1) ^ 0x1021); + } + else + { + crc <<= 1; } } - else + } + + return (short)crc; + } + static void ParseServerResponse(byte[] data, int length) + { + if (length < 10) // 根据协议响应包最小长度 + { + Console.WriteLine("响应包长度错误"); + return; + } + + if (data[0] == 0x78 && data[1] == 0x78) + { + Console.WriteLine("起始位正确"); + + byte protocolNumber = data[3]; + if (protocolNumber == 0x01) { - result.Add(data[i]); + Console.WriteLine("协议号正确: 登录信息包响应"); + + byte[] sequenceNumber = new byte[2]; + Array.Copy(data, 4, sequenceNumber, 0, 2); + Console.WriteLine($"信息序列号: {BitConverter.ToString(sequenceNumber)}"); + + byte[] crc = new byte[2]; + Array.Copy(data, length - 4, crc, 0, 2); + Console.WriteLine($"CRC: {BitConverter.ToString(crc)}"); } } - return result.ToArray(); } - private static byte[] HexStringToByteArray(string hex) + static void ParseLocationPacket(byte[] data, int length) { - int NumberChars = hex.Length; - byte[] bytes = new byte[NumberChars / 2]; - for (int i = 0; i < NumberChars; i += 2) + if (length < 16) // 根据协议位置数据包最小长度 { - bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); + Console.WriteLine("位置数据包长度错误"); + return; + } + + if (data[0] == 0x78 && data[1] == 0x78) + { + Console.WriteLine("起始位正确"); + + byte protocolNumber = data[3]; + if (protocolNumber == 0x12) // 位置数据包协议号 + { + Console.WriteLine("协议号正确: 位置数据包"); + + int latitude = (data[5] & 0xFF) << 24 | (data[6] & 0xFF) << 16 | (data[7] & 0xFF) << 8 | (data[8] & 0xFF); + int longitude = (data[9] & 0xFF) << 24 | (data[10] & 0xFF) << 16 | (data[11] & 0xFF) << 8 | (data[12] & 0xFF); + + double lat = latitude / 1800000.0; + double lon = longitude / 1800000.0; + + Console.WriteLine($"纬度: {lat}, 经度: {lon}"); + } } - return bytes; } + public struct Position { public double Latitude; diff --git a/langguanApi/Service/HJ212SocketServer.cs b/langguanApi/Service/HJ212SocketServer.cs index 2110bd5..4d07fa6 100644 --- a/langguanApi/Service/HJ212SocketServer.cs +++ b/langguanApi/Service/HJ212SocketServer.cs @@ -98,6 +98,7 @@ namespace langguanApi.Service if (hj.DecodeData(rawText)) { var body = JsonConvert.SerializeObject(hj.CP); + Console.WriteLine("解析成功: " + body); var entity = JsonConvert.DeserializeObject(body); entity.deviceMN = hj.DATA_HEAD["MN"];