/// <summary> /// 解包定位信息 /// </summary> public void Unpackate() { var nsew = CustomConvert.IntToDigit(latlng[0], CustomConvert.BIN, 8); //nsew = CustomConvert.reserve(nsew); report = (byte)(nsew[7] == '1' ? 1 : 0); eng = (byte)(nsew[6] == '1' ? 1 : 0); NSI = nsew[1] == '1' ? 'S' : 'N'; EWI = nsew[0] == '1' ? 'W' : 'E'; Latitude = latlng[1]; byte[] tmp = new byte[2]; Buffer.BlockCopy(latlng, 2, tmp, 0, 2); //tmp = CustomConvert.reserve(tmp); var u16 = BitConverter.ToUInt16(tmp, 0); double mm = u16 / Math.Pow(10, u16.ToString().Length); // 将ddmmmm转换成dd.dddd //mm = Wbs.Protocol.TX300.Analyse.GPSInfo.DDMM2DDDD(mm); Latitude += mm; Longitude = latlng[4]; Buffer.BlockCopy(latlng, 5, tmp, 0, 2); //tmp = CustomConvert.reserve(tmp); u16 = BitConverter.ToUInt16(tmp, 0); mm = u16 / Math.Pow(10, u16.ToString().Length); // 将ddmmmm转换成dd.dddd //mm = Wbs.Protocol.TX300.Analyse.GPSInfo.DDMM2DDDD(mm); Longitude += mm; }
private void Handle0x7030(TX300 obj, TB_Tracker tracker) { _0x7030 x7030 = new _0x7030(); x7030.Content = obj.MsgContent; x7030.Unpackage(); string provider = "gps"; var bin = "0000000000000000"; if (obj.TerminalType == TerminalTypes.TX10GAPP) { bin = CustomConvert.IntToDigit(obj.PackageID, CustomConvert.BIN, 8) + CustomConvert.IntToDigit(obj.TotalPackage, CustomConvert.BIN, 8); } int cnt = 0; foreach (var pos in x7030.Positions) { if (pos.Available) { provider = GetTrackerProvider(bin[cnt]);//bin[cnt] == '0' ? "gps" : "network"; SaveTrackerPosition(obj.TerminalID, (null == tracker ? "" : tracker.CarNumber), (null == tracker ? -1 : tracker.id), provider, pos, "Tracking", tracker.LastActionAt.Value); } cnt++; } }
/// <summary> /// 计算指定日期的MTMSN /// </summary> /// <param name="date">当前日期</param> /// <param name="ExistsNumber">已存在了的号码</param> /// <returns></returns> public static ushort CalculateMTMSN(DateTime date, ushort ExistsNumber) { var month = CustomConvert.IntToDigit(date.Month, CustomConvert.BIN, 4); var num = CustomConvert.IntToDigit((ExistsNumber + 1) % 4096, CustomConvert.BIN, 12); var n = CustomConvert.DigitToInt(month + num, CustomConvert.BIN); return((ushort)n); }
/// <summary> /// 处理命令回复状态 /// </summary> /// <param name="tx300"></param> private void HandleCommandResponsed(TX300 tx300) { CommandInstance.Update(f => f.DestinationNo == tx300.TerminalID && f.Command == "0x" + CustomConvert.IntToDigit(tx300.CommandID, CustomConvert.HEX, 4) && f.ScheduleTime >= DateTime.Now.AddMinutes(-3) && f.Status >= (byte)CommandStatus.SentByTCP && f.Status <= (byte)CommandStatus.SentToDest, act => { act.Status = (byte)CommandStatus.Returned; }); }
/// <summary> /// 组包 /// </summary> private void Package() { var bin = CustomConvert.BIN; var str = string.Format("{0}{1}{2}{3}{4}", CustomConvert.IntToDigit(Packet, bin, 3), CipherCode, CustomConvert.IntToDigit(CommunicateType, bin, 2), TransferType, Flag); _type = (byte)CustomConvert.DigitToInt(str, bin); }
private string GetInStatus() { var ret = ""; var str = CustomConvert.IntToDigit(IN, CustomConvert.BIN, 8); ret += "入站许可:" + (str[0] == '1' ? "可以" : "不可以"); ret += "\t抑制状态:" + (str[1] == '1' ? "抑制" : "非抑制"); return(ret); }
/// <summary> /// 更新在线时间和在线状态 /// </summary> private void HandleOnline(string sim, ushort CommandID, AsyncUserDataBuffer data) { using (var bll = new EquipmentBLL()) { bll.Update(f => f.TB_Terminal.Sim.Equals(sim), act => { act.IP = data.IP; act.Port = data.Port; act.Socket = data.SocketHandle; act.OnlineTime = data.ReceiveTime; // 处理当发送报警信息时设备已经是OFF状态的情况:不处理 if (act.OnlineStyle == (byte)LinkType.OFF && CommandID == 0x2000) { // 收到报警时不处理已经是OFF状态 } else { act.OnlineStyle = GetOnlineStyleByPackage(data.PackageType); } act.LastAction = "0x" + CustomConvert.IntToDigit(CommandID, CustomConvert.HEX, 4); act.LastActionBy = GetOnlineStyle(data.PackageType); act.LastActionTime = data.ReceiveTime; }); } using (var bll = new TerminalBLL()) { bll.Update(f => f.Sim.Equals(sim), act => { act.Socket = data.SocketHandle; if (act.OnlineStyle == (byte)LinkType.OFF && CommandID == 0x2000) { // 收到报警但此时已经是OFF状态时,不更新在线状态 } else { act.OnlineStyle = GetOnlineStyleByPackage(data.PackageType); } act.OnlineTime = data.ReceiveTime; }); } // 查看是否为TX10G的命令 if (CommandID >= 0x7000 && CommandID <= 0x7040) { using (var bll = new TrackerBLL()) { bll.Update(f => f.SimCard.Equals(sim), act => { // 标记为在线状态 act.State = 1; act.LastActionAt = DateTime.Now; act.Socket = data.SocketHandle; }); } } }
/// <summary> /// 将通信信息类别的各个字段打包成一个字节 /// </summary> private void Package() { var bin = CustomConvert.BIN; var tmp = string.Format("{0}{1}{2}{3}{4}{5}", CustomConvert.IntToDigit(Communicate, bin, 2), MessageType, Receipt, CustomConvert.IntToDigit(CommunicateType, bin, 2), CipherCode, CustomConvert.IntToDigit(Allowance, bin, 2)); _type = (byte)CustomConvert.DigitToInt(tmp, bin); }
/// <summary> /// 拆解 /// </summary> private void Unpackage() { var bin = CustomConvert.IntToDigit(_type, CustomConvert.BIN, 8); var str = bin.Substring(0, 3); Packet = (byte)CustomConvert.DigitToInt(str, CustomConvert.BIN); CipherCode = byte.Parse(bin.Substring(3, 1)); str = bin.Substring(4, 2); CommunicateType = (byte)CustomConvert.DigitToInt(str, CustomConvert.BIN); TransferType = byte.Parse(bin.Substring(6, 1)); Flag = byte.Parse(bin.Substring(7)); }
/// <summary> /// 将通信申请信息类别的各个字段转换成字符串显示 /// </summary> /// <returns></returns> public override string ToString() { var bin = CustomConvert.BIN; StringBuilder sb = new StringBuilder(); sb.Append("\t报文通信:").Append(Packet).Append("\tBin:") .Append(CustomConvert.IntToDigit(Packet, bin, 3)).Append(Environment.NewLine); sb.Append("\t密 钥:").Append(CipherCode).Append("\tBin:") .Append(CustomConvert.IntToDigit(CipherCode, bin, 1)).Append(Environment.NewLine); sb.Append("\t通信类别:").Append(CommunicateType).Append("\tBin:") .Append(CustomConvert.IntToDigit(CommunicateType, bin, 2)).Append(Environment.NewLine); sb.Append("\t传输方式:").Append(TransferType).Append("\tBin:") .Append(CustomConvert.IntToDigit(TransferType, bin, 1)).Append("(0汉字,1代码)").Append(Environment.NewLine); sb.Append("\t标 志:").Append(Flag).Append("\tBin:") .Append(CustomConvert.IntToDigit(Flag, bin, 1)).Append(Environment.NewLine); return(sb.ToString()); }
/// <summary> /// 将通信信息信息类别的各个字段显示成字符 /// </summary> /// <returns></returns> public override string ToString() { var bin = CustomConvert.BIN; StringBuilder sb = new StringBuilder(); sb.Append("\t通信类别:").Append(Communicate).Append("\tBin:") .Append(CustomConvert.IntToDigit(Communicate, bin, 2)).Append(Environment.NewLine); sb.Append("\t电文形式:").Append(MessageType).Append("\tBin:") .Append(CustomConvert.IntToDigit(MessageType, bin, 1)).Append(Environment.NewLine); sb.Append("\t是否回执:").Append(Receipt).Append("\tBin:") .Append(CustomConvert.IntToDigit(Receipt, bin, 1)).Append(Environment.NewLine); sb.Append("\t通信方式:").Append(CommunicateType).Append("\tBin:") .Append(CustomConvert.IntToDigit(CommunicateType, bin, 1)).Append(Environment.NewLine); sb.Append("\t密 钥:").Append(CipherCode).Append("\tBin:") .Append(CustomConvert.IntToDigit(CipherCode, bin, 1)).Append(Environment.NewLine); sb.Append("\t余 量:").Append(Allowance).Append("\tBin:") .Append(CustomConvert.IntToDigit(Allowance, bin, 2)).Append(Environment.NewLine); return(sb.ToString()); }
/// <summary> /// 更新在线时间和在线状态 /// </summary> private void HandleOnline(string sim, ushort CommandID, AsyncUserDataBuffer data) { EquipmentInstance.Update(f => f.TB_Terminal.Sim.Equals(sim), act => { act.IP = data.IP; act.Port = data.Port; act.Socket = data.SocketHandle; act.OnlineTime = data.ReceiveTime; act.OnlineStyle = (byte)(data.PackageType == AsyncDataPackageType.TCP ? LinkType.TCP : LinkType.UDP); act.LastAction = "0x" + CustomConvert.IntToDigit(CommandID, CustomConvert.HEX, 4); act.LastActionBy = data.PackageType == AsyncDataPackageType.TCP ? "TCP" : "UDP"; act.LastActionTime = data.ReceiveTime; }); TerminalInstance.Update(f => f.Sim.Equals(sim), act => { act.Socket = data.SocketHandle; act.OnlineStyle = (byte)(data.PackageType == AsyncDataPackageType.TCP ? LinkType.TCP : LinkType.UDP); act.OnlineTime = data.ReceiveTime; }); }
/// <summary> /// 保存数据到历史记录表 /// </summary> /// <param name="tx300"></param> private void SaveTX300History(TX300 tx300, DateTime receiveTime, string mac_id) { TB_HISTORIES obj = DataInstance.GetObject(); obj.command_id = "0x" + CustomConvert.IntToDigit(tx300.CommandID, CustomConvert.HEX, 4); obj.mac_id = mac_id; obj.message_content = CustomConvert.GetHex(tx300.MsgContent); obj.message_type = 1; obj.package_id = tx300.PackageID; obj.protocol_type = tx300.ProtocolType; obj.protocol_version = tx300.ProtocolVersion; obj.receive_time = receiveTime; obj.sequence_id = tx300.SequenceID.ToString(); obj.server_port = 31875; obj.terminal_id = tx300.TerminalID; obj.terminal_type = tx300.TerminalType; obj.total_length = (short)tx300.TotalLength; obj.total_package = tx300.TotalPackage; DataInstance.Add(obj); }
/// <summary> /// 更新在线时间和在线状态 /// </summary> private void HandleOnline(string sim, ushort CommandID) { // 更新设备在线状态为卫星通信 EquipmentInstance.Update(f => f.TB_Terminal.Sim.Equals(sim) && f.Deleted == false, act => { act.IP = ""; act.Port = 0; act.Socket = 0; act.OnlineTime = DateTime.Now; act.OnlineStyle = (byte)(LinkType.SATELLITE); act.LastAction = "0x" + CustomConvert.IntToDigit(CommandID, CustomConvert.HEX, 4); act.LastActionBy = "SAT"; act.LastActionTime = DateTime.Now; }); // 更新终端在线状态为卫星通信 TerminalInstance.Update(f => f.Sim.Equals(sim), act => { act.Socket = 0; act.OnlineStyle = (byte)(LinkType.SATELLITE); act.OnlineTime = DateTime.Now; }); }
/// <summary> /// 保存数据到历史记录表 /// </summary> /// <param name="tx300"></param> private void SaveTX300History(TX300 tx300, DateTime receiveTime, string mac_id) { using (var bll = new DataBLL()) { TB_HISTORIES obj = bll.GetObject(); obj.command_id = "0x" + CustomConvert.IntToDigit(tx300.CommandID, CustomConvert.HEX, 4); obj.mac_id = mac_id; obj.message_content = CustomConvert.GetHex(tx300.MsgContent); obj.message_type = 1; obj.package_id = tx300.PackageID; obj.protocol_type = tx300.ProtocolType; obj.protocol_version = tx300.ProtocolVersion; obj.receive_time = receiveTime; obj.sequence_id = tx300.SequenceID.ToString(); obj.server_port = (short)(tx300.ProtocolType == Protocol.ProtocolTypes.SATELLITE ? 10800 : tx300.ProtocolType == Protocol.ProtocolTypes.SMS ? 0 : 31875); obj.terminal_id = tx300.TerminalID; obj.terminal_type = tx300.TerminalType; obj.total_length = (short)tx300.TotalLength; obj.total_package = tx300.TotalPackage; bll.Add(obj); } }
/// <summary> /// 解析通信信息信息类别 /// </summary> private void Unpackage() { var bin = CustomConvert.IntToDigit(_type, CustomConvert.BIN, 8); var str = bin.Substring(0, 2); Communicate = (byte)CustomConvert.DigitToInt(str, CustomConvert.BIN); str = bin.Substring(2, 1); MessageType = byte.Parse(str); str = bin.Substring(3, 1); Receipt = byte.Parse(str); str = bin.Substring(4, 1); CommunicateType = byte.Parse(str); str = bin.Substring(5, 1); CipherCode = byte.Parse(str); str = bin.Substring(6); Allowance = (byte)CustomConvert.DigitToInt(str, CustomConvert.BIN); }
private void HandleEquipmentState(string sender, ushort Command) { var EquipmentInstance = new EquipmentBLL(); EquipmentInstance.Update(f => f.TB_Terminal.Sim.Equals(sender) && f.Deleted == false, act => { act.Socket = 0; act.OnlineTime = DateTime.Now; act.IP = ""; act.Port = 0; act.LastAction = "0x" + CustomConvert.IntToDigit(Command, CustomConvert.HEX, 4); act.LastActionBy = "SMS"; act.LastActionTime = DateTime.Now; if (act.OnlineStyle == (byte)LinkType.OFF && Command == 0x2000) { } else { act.OnlineStyle = (byte)LinkType.SMS; } }); var TerminalInstance = new TerminalBLL(); TerminalInstance.Update(f => f.Sim.Equals(sender), act => { act.Socket = 0; act.OnlineTime = DateTime.Now; if (act.OnlineStyle == (byte)LinkType.OFF && Command == 0x2000) { // 收到报警但此时已经是OFF状态时,不更新在线状态 } else { act.OnlineStyle = (byte)LinkType.SMS; } }); }
/// <summary> /// 处理GSM命令回复状态 /// </summary> /// <param name="tx300"></param> private void HandleGsmCommandResponsed(TX300 tx300) { using (var bll = new CommandBLL()) { // 查找定期时间内发送的相同命令记录,直取最后一条命令 var cmd = bll.FindList <TB_Command>(f => f.DestinationNo.Equals(tx300.TerminalID) && f.Command.Equals("0x" + CustomConvert.IntToDigit(tx300.CommandID, CustomConvert.HEX, 4)) && f.ScheduleTime >= DateTime.Now.AddMinutes(tx300.ProtocolType == Protocol.ProtocolTypes.SATELLITE ? -60 : -3), "ScheduleTime", true).FirstOrDefault(); if (null != cmd) { bll.Update(f => f.id == cmd.id, act => { act.Status = (byte)CommandStatus.Returned; }); } //bll.Update(f => f.DestinationNo == tx300.TerminalID && // f.Command == "0x" + CustomConvert.IntToDigit(tx300.CommandID, CustomConvert.HEX, 4) && // f.ScheduleTime >= DateTime.Now.AddMinutes(-3) //&& // //GsmStatus.Skip(2).Contains(f.Status.Value), // , act => { act.Status = (byte)CommandStatus.Returned; }); } }
/// <summary> /// 查询历史记录并开始画图 /// </summary> /// <param name="target"></param> private void chart(Stream target) { byte[,] times = new byte[24, 60 / _interval]; Int64 total_seconds = 0; // 初始化数组 for (int i = 0; i < times.GetLength(0); i++) { for (int j = 0; j < times.GetLength(1); j++) { times[i, j] = 10; } } // 获取数据库中今日启动情况 var data = new DataBLL(); var list = data.FindList(h => h.receive_time >= _start && h.receive_time <= _end && h.mac_id.Equals(_equipment) && (h.command_id.Equals("0x5000") || h.command_id.Equals("0x1000"))).OrderBy(o => o.receive_time); // 当日开机时间默认为凌晨零点。 TimeSpan lastOpen = new TimeSpan(_start.Ticks), lastClose; var lastIsOpen = true; var terType = 0; foreach (var obj in list) { // 非卫星方式回来的1000命令不处理 if (obj.command_id.Equals("0x1000")) { if (obj.protocol_type != ProtocolTypes.SATELLITE) { continue; } if (obj.message_content.Substring(0, 2) != "01") { continue; } } if (terType == 0) { var t = new TerminalBLL().Find(find => obj.terminal_id.IndexOf(find.Sim) >= 0); if (null != t) { terType = (byte)t.Type; } } string str = ""; DateTime dt; int hh, mm; //while (sdr.Read()) //{ if (obj.protocol_type == ProtocolTypes.SATELLITE) { byte[] msgc = CustomConvert.GetBytes(obj.message_content); string bin = CustomConvert.IntToDigit(msgc[4], CustomConvert.BIN, 8); msgc = null; str = bin[6] == '1' ? "F000" : "0000"; } else { str = terType == TerminalTypes.DX ? obj.message_content.Substring(0, 4) : (obj.message_content.Substring(8, 2) == "00" ? "F000" : "0000"); } dt = obj.receive_time.Value; hh = Convert.ToInt32(dt.ToString("HH")); mm = Convert.ToInt32(dt.ToString("mm")) / _interval; // 开机 if (0 < str.CompareTo("0000")) { times[hh, mm] = 1; lastOpen = new TimeSpan(dt.Ticks); lastIsOpen = true; } else { times[hh, mm] = 0; lastClose = new TimeSpan(dt.Ticks); if (lastIsOpen) { lastIsOpen = false; total_seconds += (long)(lastClose - lastOpen).Duration().TotalSeconds; } } //} } // 格式化显示今日的总开机时间 total_seconds = total_seconds / 60; string total_runtime = (total_seconds / 60) + " h " + (total_seconds % 60) + " m"; // 添加表格 bool is_open = false; int hn, mn; // 查看日期是否跟今天相同 DateTime date = DateTime.Parse(_date); if (date < DateTime.Now) { hn = 23; mn = 60 / _interval; } else { hn = Convert.ToInt32(DateTime.Now.ToString("HH")); mn = Convert.ToInt32(DateTime.Now.ToString("mm")) / _interval; } Bitmap b = new Bitmap(_width, _height); Graphics g = Graphics.FromImage(b); // 填充白色背景 g.Clear(Color.White); Pen p = new Pen(Color.FromArgb(0x00, 0x99, 0xCC)); Font f = new System.Drawing.Font("Arial", 9); Brush br = new SolidBrush(Color.FromArgb(0x00, 0x99, 0xCC)); int font_height = (int)g.MeasureString(_date, f).Height; // 画日期提示 g.DrawString(_date + ": " + total_runtime, f, br, 0, 0); // 画方框 g.DrawRectangle(p, 0, font_height, b.Width + 1, _barHeight); // 每一个区域块的宽度 int per_width = b.Width / (times.GetLength(0) * times.GetLength(1)); int ct = 0; bool kedu = false; for (int i = 0; i < times.GetLength(0); i++) { kedu = false; for (int j = 0; j < times.GetLength(1); j++) { if (times[i, j] == 1) { is_open = true; } if (times[i, j] == 0) { is_open = false; } if (i == hn) { if (j >= mn) { is_open = false; } } Rectangle r = new Rectangle(ct * per_width, font_height, per_width, _barHeight); if (is_open) { // 填充为实心区域 g.FillRectangle(br, r); // 画底部实线 g.DrawLine(p, r.Left, r.Top + _barHeight, r.Left + r.Width, r.Top + _barHeight); } else { // 画顶部实线 g.DrawLine(p, r.Left, r.Top, r.Left + r.Width, r.Top); // 画底部实线 g.DrawLine(p, r.Left, r.Top + _barHeight, r.Left + r.Width, r.Top + _barHeight); } //if (i % 4 == 0) { if (!kedu) { kedu = true; // 画刻度 g.DrawLine(p, r.Left, r.Top + _barHeight, r.Left, b.Height); // 显示刻度数字 g.DrawString(i.ToString("00"), new Font("tahoma", 8), br, r.Left + 1, r.Top + _barHeight + 1); } } // 画最右边的竖线 if (i == times.GetUpperBound(0) && j == times.GetUpperBound(1)) { g.DrawLine(p, r.Left + r.Width, r.Top, r.Left + r.Width, b.Height); } ct++; } } b.Save(target, ImageFormat.Png); p.Dispose(); g.Dispose(); b.Dispose(); }
/// <summary> /// 处理新版的卫星通讯协议 /// </summary> /// <param name="data"></param> private void HandleIridiumNewProtocolPackage(IridiumData data) { if (data.Payload[0] == 0x01) { // 新版的卫星通讯协议 uint thisWorkTime = BitConverter.ToUInt32(data.Payload, 13); string locks = CustomConvert.GetHex(data.Payload[1]); string alarms = CustomConvert.IntToDigit(data.Payload[2], CustomConvert.BIN, 8) + CustomConvert.IntToDigit(data.Payload[3], CustomConvert.BIN, 8); IridiumLocation location = new IridiumLocation(); location.LatLng = new byte[IridiumLocation.SIZE]; Buffer.BlockCopy(data.Payload, 4, location.LatLng, 0, IridiumLocation.SIZE); location.Unpackate(); // 通过卫星的IMEI号码查找终端 using (var tbll = new TerminalBLL()) { using (var ebll = new EquipmentBLL()) { var terminal = tbll.Find(f => f.TB_Satellite.CardNo.Equals(data.IMEI)); TB_Equipment equipment = null; if (null != terminal) { // 只有第一版的终端才需要计算补偿时间 var compensated = terminal.Version == 1; tbll.Update(f => f.id == terminal.id, act => { act.OnlineStyle = (byte)LinkType.SATELLITE; // 同时更新终端的最后链接时间 act.OnlineTime = data.Time; }); equipment = ebll.Find(f => f.Terminal == terminal.id); if (null != equipment) { // 旧的运转时间 var oldRuntime = equipment.Runtime; var interval = 0 == oldRuntime ? 0 : (thisWorkTime - oldRuntime); // 粗略增加的小时数,启动时加2小时 var addMin = interval > 60 ? interval / 60 : 1 + (location.EngFlag.Equals("On") ? 1 : 0); int addHour = (int)(interval > 60 ? interval / 60 : 1);// 显示历史记录 string oldCompensated = format("WorkHours {0}, UsedHours {1}, Efficiency {2}, AddHours {3}, Compensated {4}", equipment.WorkHours, equipment.UsedHours, equipment.HourWorkEfficiency, equipment.AddedHours, equipment.CompensatedHours); string newCompensated = ""; // 更新设备的总运转时间 HandleEquipmentRuntime(equipment, thisWorkTime); if (null != equipment) { string calculated = ""; ebll.Update(f => f.id == equipment.id, act => { act.OnlineStyle = (byte)LinkType.SATELLITE; act.OnlineTime = data.Time; // 更新设备的报警状态 2015/09/10 14:04 act.Alarm = alarms; act.LastAction = "0x1000"; act.LastActionBy = "SAT"; act.LastActionTime = data.Time; // 更新定位信息 2015/09/09 23:29 if (location.Available) { act.Latitude = location.Latitude; act.Longitude = location.Longitude; } // 更新启动与否状态 2015/08/31 act.Voltage = location.EngFlag.Equals("On") ? "G2400" : "G0000"; // 更新总运转时间 act.Runtime = equipment.Runtime; act.AccumulativeRuntime = equipment.AccumulativeRuntime; // 更新 version 终端为1的版本的运转时间的补偿 if (compensated && interval > 0) { // 实际工作小时数 act.WorkHours += interval / 60.0; // 实际所用小时数 act.UsedHours += addHour; // 重新计算每小时工作效率 act.HourWorkEfficiency = act.WorkHours / act.UsedHours; // 补偿的小时数 act.AddedHours += addMin / 60.0; // 实际补偿的小时数 act.CompensatedHours = act.AddedHours * act.HourWorkEfficiency; } // 如果回来的运转时间比当前时间大则更新成为On状态 暂时 2015/09/02 //if (worktime > act.Runtime) //{ // // act.Voltage = "G2400"; // act.Runtime = (int)worktime; //} //else //{ // if (worktime > 0) // { // // 运转时间不为零的话,更新运转时间 // act.Runtime = (int)worktime; // } //} // 锁车状态 2015/08/14 if (act.LockStatus != locks) { act.LockStatus = locks; } // 判断锁车的有效状态 if (locks.Equals("40") || locks.Equals("0F") || locks.Equals("FF")) { // 锁车时还有开机状态 if (location.EngFlag.Equals("On")) { // 锁车了,但未关机,还在工作中 if (act.LockEffected == (byte)LockEffect.Locked) { act.LockEffected = (byte)LockEffect.LockedAndStillWork; } else if (act.LockEffected == (byte)LockEffect.LockedAndEngineOff) { // 锁车了且已关机了,此时再开机则需要报警(没锁住车) act.LockEffected = (byte)LockEffect.LockedAndNoEffect; } } else { // 锁车了,且已关机了 if (act.LockEffected == (byte)LockEffect.Locked) { act.LockEffected = (byte)LockEffect.LockedAndEngineOff; } } } }); if (compensated && interval > 0) { equipment = ebll.Find(f => f.id == equipment.id); newCompensated = format("WorkHours {0}, UsedHours {1}, Efficiency {2}, AddHours {3}, Compensated {4}", equipment.WorkHours, equipment.UsedHours, equipment.HourWorkEfficiency, equipment.AddedHours, equipment.CompensatedHours); calculated = format("Compensate changed(interval: {0}){1} from {2}{3} to {4}", interval, Environment.NewLine, oldCompensated, Environment.NewLine, newCompensated); } if (!string.IsNullOrEmpty(calculated)) { OnUnhandledMessage(this, new Sockets.UIEventArgs() { Message = format("{0}{1}{2}", Now, calculated, Environment.NewLine) }); } } } else { OnUnhandledMessage(this, new Sockets.UIEventArgs() { Message = format("{0} Iridium has not bind with any equipment.", Now, Environment.NewLine) }); } } else { OnUnhandledMessage(this, new Sockets.UIEventArgs() { Message = format("{0} Satellite has no terminal, data will save as terminal number: \"{1}\".{2}", Now, data.IMEI.Substring(4), Environment.NewLine) }); } // 保存TX300历史记录 SaveTX300History(new TX300() { CommandID = 0x1000, MsgContent = data.Payload, ProtocolType = ProtocolTypes.SATELLITE, // 默认装载机终端类型 2015/09/22 09:40 TerminalType = null == terminal ? TerminalTypes.LD : terminal.Type.Value, // 没有终端时,用IMEI号码的末尾11位数字表示终端号码 2015/09/22 09:40 TerminalID = null == terminal ? data.IMEI.Substring(4) : terminal.Sim, TotalLength = (ushort)data.Payload.Length }, data.Time, ebll.GetFullNumber(equipment)); try { long?posId = null; if (location.Available) { using (var posbll = new PositionBLL()) { var pos = posbll.GetObject(); pos.Latitude = location.Latitude; pos.Longitude = location.Longitude; pos.NS = location.NSI; pos.EW = location.EWI; pos.StoreTimes = null == equipment ? 0 : equipment.StoreTimes; pos.GpsTime = data.Time; pos.Equipment = null == equipment ? (int?)null : equipment.id; // 没有终端时,用IMEI号码的末尾11位数字表示终端号码 2015/09/22 09:40 pos.Terminal = null == terminal?data.IMEI.Substring(4) : (terminal.Sim.Length < 11 ? (terminal.Sim + "000") : terminal.Sim); pos.Type = location.Report + "(Eng " + location.EngFlag + ")(SAT)"; posbll.Add(pos); posId = pos.id; } } // 处理报警信息 if (alarms != ALARM) { using (var armbll = new AlarmBLL()) { var arm = armbll.GetObject(); arm.Code = alarms; arm.AlarmTime = data.Time; arm.Equipment = null == equipment ? (int?)null : equipment.id; arm.Position = posId; arm.StoreTimes = null == equipment ? 0 : equipment.StoreTimes; // 没有终端时,用IMEI号码的末尾11位数字表示终端号码 2015/09/22 09:40 arm.Terminal = null == terminal?data.IMEI.Substring(4) : (terminal.Sim.Length < 11 ? (terminal.Sim + "000") : terminal.Sim); armbll.Add(arm); } } } catch (Exception e) { OnUnhandledMessage(this, new Sockets.UIEventArgs() { Message = format("{0}{1}{2}{3}", Now, e.Message, Environment.NewLine, e.StackTrace) }); } // 更新卫星方式的命令状态(只处理命令回复的1000,其他的命令在普通命令过程中处理) if (location.ReportType == 1 && data.Payload.Length <= 17) { HandleIridiumCommandResponseed(data); } location.Dispose(); location = null; } } } }
/// <summary> /// 判断Tracker的定位类型 /// </summary> /// <param name="type"></param> /// <returns></returns> private string GetTrackerProvider(byte type) { string bin = CustomConvert.IntToDigit(type, CustomConvert.BIN, 8); return(GetTrackerProvider(bin[0])); }
/// <summary> /// 查询指定日期范围内的运转时间并补偿相应的数量 /// </summary> /// <param name="averagable"></param> /// <returns></returns> private string HandleQueryEquipmentWorktime(bool averagable = true) { var ret = "{}"; var id = ParseInt(Utility.Decrypt(data)); var obj = EquipmentInstance.Find(f => f.id == id && f.Deleted == false); if (null != obj) { var date = DateTime.Parse(GetParamenter("date") + " 00:00:00"); // 如果不是求平均值则将日期往前推一天 //if (!averagable) { date = date.AddDays(-1); } var date1 = DateTime.Parse(GetParamenter("date1") + " 23:59:59"); List <WorktimeChart> avg = new List <WorktimeChart>(); List <WorktimeChart> work = new List <WorktimeChart>(); DateTime dt = date; // 循环每天一个节点 while (dt.Ticks < date1.Ticks) { avg.Add(new WorktimeChart() { date = dt.ToString("yyyy/MM/dd"), x = Utility.DateTimeToJavascriptDate(dt.Date), y = 0, min = 0 }); work.Add(new WorktimeChart() { date = dt.ToString("yyyy/MM/dd"), x = Utility.DateTimeToJavascriptDate(dt.Date), y = 0, min = 0 }); dt = dt.AddDays(1); } var macid = EquipmentInstance.GetFullNumber(obj); var cmds = new string[] { "0x1000", "0x600B" }; var runtimes = DataInstance.FindList(f => f.mac_id.Equals(macid) && cmds.Contains(f.command_id) && f.receive_time >= date && f.receive_time <= date1).OrderBy(o => o.receive_time); var list = new List <Worktime>(); if (null != runtimes) { long today = 0; long timeInterval = 0; foreach (var r in runtimes) { bool gps = r.command_id.Equals("0x1000"); if (today == 0) { dt = r.receive_time.Value; } else { // 计算与上一条数据的实际接收时间之间的时间差 timeInterval = (long)(r.receive_time.Value - dt).TotalSeconds; } var t = Utility.DateTimeToJavascriptDate(r.receive_time.Value.Date); // 日期不同则重置日期和运转时间 if (today != t) { today = t; } byte[] temp = null; int index = 0; if (gps) { if (r.protocol_type == ProtocolTypes.SATELLITE) { temp = CustomConvert.GetBytes(r.message_content); index = 13; } } else { temp = CustomConvert.GetBytes(r.message_content); index = 0; } // 增加一个节点 Worktime wt = new Worktime(); wt.date = r.receive_time.Value.ToString("yyyy/MM/dd HH:mm:ss"); wt.worktime = null == temp ? 0 : BitConverter.ToUInt32(temp, index); var bin = !gps ? "00000000" : CustomConvert.IntToDigit(temp[4], CustomConvert.BIN, 8); // 如果list已经有数据则计算与上一条数据之间的差值 var cnt = list.Count; if (cnt > 0) { if (wt.worktime < list[cnt - 1].worktime) { // 当前运转时间小于前一条时,小计为0 wt.interval = 0; } else { // 差值 wt.interval = !gps ? 0 : (wt.worktime - list[cnt - 1].worktime); // 计算差值与实际两条数据的接收时间差值的对比 if (wt.interval > timeInterval) { // 如果运转时间差超过了这两条数据接收时间的差值,则记为0 wt.interval = 0; } // 计算运转时间之间的差值 2016/08/15 15:00 if (wt.interval > 0) { uint hour = (uint)r.receive_time.Value.Hour, min = (uint)r.receive_time.Value.Minute; // 凌晨0点的运转时间需要分开到两个日期里 if (hour == 0) { // 时间间隔大于0点已过的分钟数,则需要把时间差分开到两个日期里 if (wt.interval > min) { list[cnt - 1].interval += wt.interval - min; wt.interval = min; } } } // 补偿的分钟 if (wt.interval > 0) { uint ad = 0; if (wt.interval > 60) { ad = wt.interval / 60; } else { ad = 1; } if (bin[6] == '1') { ad += 1; } wt.added = ad; } else { wt.interval = 0; } // 所用的小时 wt.hours = wt.interval > 0 ? (wt.interval > 60 ? wt.interval / 60 : 1) : 0; } } else { // 第一条数据小计为0 wt.interval = 0; } list.Add(wt); // 更新本日最后的运转时间 var wk = work.FirstOrDefault(f => f.x == today); if (null != wk) { //if (wk.min == 0) { wk.min = run; } wk.min = wt.worktime; } }// end of foreach // 工作时间总计 var totalWorkMins = list.Sum(s => s.interval); // 补偿的分钟 var totalAddMins = list.Sum(s => s.added); // 所用的小时数 var totalUsedHours = list.Sum(s => s.hours); // 工作效率 var compensate = totalWorkMins / 60.0 / totalUsedHours; // 最终增加的小时数 var finalAdded = totalAddMins / 60.0 * compensate; // 计算每日运转时间 foreach (var f in work) { f.y = Math.Round(list.Where(w => w.date.Contains(f.date)).Sum(s => s.interval) / 60.0, 2); f.add = finalAdded; } // 有工作时间的天数里平均加入补偿的小时数 var per = finalAdded / work.Count(c => c.y > 0); //per = Math.Round(per, 2); // 加入补偿 foreach (var w in work) { //if (!averagable) { w.y += w.y > 0 ? per : 0; // 如果超过24小时则直接设为24小时 2016/08/15 15:16 if (w.y >= 24) { w.y = 24; } } if (averagable) { w.y = Math.Round(w.y, 2); } } // 计算平均值 var avgg = Math.Round(work.Sum(s => s.y) * 1.0 / work.Count, 2); foreach (var a in avg) { a.y = avgg; } } if (averagable) { ret = string.Format("{0}\"Average\":{1},\"Worktime\":{2}{3}", "{", JsonConverter.ToJson(avg), JsonConverter.ToJson(work), "}"); } else { ret = JsonConverter.ToJson(work); } } return(ret); }
public override string ToString() { return(format("{0}, UniqueID: {1}, IMEI: {2}, DispositionFlags: {3}({4})", base.ToString(), UniqueID, IMEI, DispositionFlags, CustomConvert.IntToDigit(DispositionFlags, CustomConvert.HEX, 4))); }
/// <summary> /// 发送命令 /// </summary> /// <param name="Sim"></param> /// <param name="code"></param> /// <param name="sms"></param> /// <param name="sender">发送者的ID,一般为当前登陆者的ID</param> /// <returns></returns> public static int SendCommand(TB_Terminal terminal, string code, bool sms, int sender, string extra = "") { Command cmd = GetCommand(code); string content = cmd.Content; if (cmd.Code.Equals("6007")) { // 保安命令 // DX 的保安命令需要增加一个日期 content += DateTime.Now.ToString("yyMMddHHmm") + cmd.Param; // DX 的保安命令长度不一样 content = "1700" + content.Substring(4); } else if (cmd.Code.Equals("3000")) { // 装载机的锁车、解锁命令 content = content.Substring(0, content.Length - 4) + cmd.Param + "00"; } else if (cmd.Code.Equals("600B")) { uint time = uint.Parse(extra); byte[] tm = BitConverter.GetBytes(time); string t = tm[0].ToString("X2") + tm[1].ToString("X2") + tm[2].ToString("X2") + tm[3].ToString("X2"); content = content.Substring(0, content.Length - 8) + t; } else if (cmd.Code.Equals("DD02")) { content = content.Substring(0, content.Length - 8) + cmd.Param + "000000"; } else if (cmd.Code.Equals("4000")) { content = content.Substring(0, content.Length - 4) + cmd.Param + "00"; } string sim = terminal.Sim; sim = (sim[0] == '8' && sim[1] == '9' && sim.Length < 11) ? (sim + "000") : sim; content = content.Replace(SIMNO, sim); // 终端类型更改,电子式的挖掘机和装载机一个类型,普通DX挖掘机一个类型 byte ttype = terminal.Type.Value; ttype = (ttype == TerminalTypes.DXE || ttype == TerminalTypes.LD) ? TerminalTypes.LD : TerminalTypes.DX; var type = CustomConvert.IntToDigit(ttype, CustomConvert.HEX, 2); content = content.Substring(0, 6) + type + content.Substring(8); // 终端不是卫星方式连接且需要SMS方式发送时,发送SMS命令 //if (terminal.OnlineStyle != (byte)LinkType.SATELLITE && sms) //{ // return SendSMSCommand(terminal, content, sender); //} //else //{ using (var bll = new CommandBLL()) { var command = bll.GetObject(); command.DestinationNo = sim; // 终端是卫星方式连接则使用卫星方式发送命令 command.Status = (terminal.OnlineStyle == (byte)LinkType.SATELLITE ? (byte)CommandStatus.WaitingForSatellite : // SMS发送时值为 re-sending (byte)(sms ? CommandStatus.WaitingForSMS : CommandStatus.Waiting)); command.Content = content; command.SendUser = (0 == sender ? (int?)null : sender); command.Terminal = terminal.id; return(bll.Add(command).id); } //} }
/// <summary> /// 查询指定条件 /// </summary> /// <param name="query"></param> /// <param name="time1"></param> /// <param name="time2"></param> private void Query(Work query) { var cmds = new List <string>(); cmds.Add("0x1000"); cmds.Add("0x600B"); using (var bll = new DataBLL()) { Expression <Func <TB_HISTORIES, bool> > expression = PredicateExtensions.True <TB_HISTORIES>(); if (!string.IsNullOrEmpty(query.MacId)) { expression = expression.And(a => a.mac_id.Contains(query.MacId)); } expression = expression.And(a => cmds.Contains(a.command_id)); expression = expression.And(a => a.receive_time >= query.Time1 && a.receive_time <= query.Time2); var list = bll.FindList <TB_HISTORIES>(expression, "receive_time").ToList <TB_HISTORIES>(); var html = ""; int TotalAddedMinutes = 0, TotalWorkedMinutes = 0, TotalUsedHour = 0; if (null == list || list.Count() < 1) { html = "<tr><td colspan=\"13\" class=\"in-tab-title-b\">No records, you can change condition and try again.</td></tr>"; } else { uint lastworktime = 0; string macid = ""; byte maccount = 0; for (int i = 0, len = list.Count(); i < len; i++) { var obj = list[i]; if (!macid.Equals(obj.mac_id)) { macid = obj.mac_id; maccount++; } var data = CustomConvert.GetBytes(obj.message_content); var worktime = BitConverter.ToUInt32(data, obj.command_id.Equals("0x1000") ? 13 : 0); int interval = (int)(i == 0 ? 0 : (worktime - lastworktime)); // 两条数据之间接收时间之差 long minInterval = (long)((i == 0) ? 0 : (obj.receive_time.Value - list[i - 1].receive_time.Value).TotalSeconds); if (interval > minInterval) { // 如果这条数据与上一条数据的工作时间之差大于了这两条数据的接收时间之差则将其算做0 interval = 0; } TotalWorkedMinutes += obj.command_id.Equals("0x600B") ? 0 : (interval > 0 ? interval : 0); var bin = obj.command_id.Equals("0x600B") ? "00000000" : CustomConvert.IntToDigit(data[4], CustomConvert.BIN, 8); string eng, engflag; if (obj.command_id.Equals("0x600B")) { eng = EquipmentBLL.eng_off; engflag = "0"; } else if (data[1] == 0x40 || data[1] == 0x0F || data[1] == 0xFF) { eng = EquipmentBLL.eng_lock; engflag = "0"; } else { eng = (bin[6] == '1' ? EquipmentBLL.eng_on : EquipmentBLL.eng_off); engflag = (bin[6] == '1' ? "1" : "0"); } int added = (interval > 0 ? (obj.command_id.Equals("0x600B") ? 0 : (interval > 60 ? interval / 60 : 1)) : 0) + (engflag.Equals("1") ? 1 : 0); TotalAddedMinutes += added; TotalUsedHour += interval > 0 ? (obj.command_id.Equals("0x600B") ? 0 : (interval > 60 ? interval / 60 : 1)) : 0; html += "<tr>" + "<td class=\"in-tab-title-b\">" + (i + 1) + "</td>" + "<td class=\"in-tab-title-rb textoverflow\" style=\"text-align: left; \">" + obj.receive_time.Value.ToString("yyyy/MM/dd HH:mm:ss") + "</td>" + "<td class=\"in-tab-title-b\" style=\"text-align: right;\">" + EquipmentBLL.GetRuntime((int?)worktime) + "</td>" + "<td class=\"in-tab-title-b\" style=\"text-align: right;\">" + string.Format("{0:0,00}", worktime) + "</td>" + "<td class=\"in-tab-title-b\" style=\"text-align: right;\">" + (interval > 60 ? ("<font color=\"#FF0000\">" + interval + "</font>") : interval.ToString()) + "</td>" + "<td class=\"in-tab-title-rb\" style=\"text-align: right;\">" + added + "</td>" + "<td class=\"in-tab-title-b\" style=\"text-align: left;\">" + obj.command_id + "</td>" + "<td class=\"in-tab-title-b\" style=\"text-align: left;\">" + obj.terminal_id + "</td>" + "<td class=\"in-tab-title-rb textoverflow\" style=\"text-align: left;\">" + obj.mac_id + "</td>" + "<td class=\"in-tab-title-b\" style=\"text-align: center; width: 30px;\">" + eng + "</td>" + "<td class=\"in-tab-title-b\" style=\"text-align: center; width: 30px;\">" + engflag + "</td>" + "<td class=\"in-tab-title-b\" style=\"text-align: left;\">" + obj.message_content + "</td>" + "<td class=\"in-tab-title-b\"></td>" + "</tr>"; lastworktime = worktime; if (i == len - 1) { var compensate = (TotalWorkedMinutes / 60.0) / TotalUsedHour; var finalAdded = TotalAddedMinutes / 60.0 * compensate; var finalWork = worktime / 60.0 + finalAdded; string summary = "<tr>" + "<td class=\"in-tab-title-rb textoverflow\">" + obj.mac_id + "</td>" + "<td class=\"in-tab-title-rb\" style=\"text-align: right;\">" + EquipmentBLL.GetRuntime((int?)worktime) + "</td>" + "<td class=\"in-tab-title-b\" style=\"text-align: right;\">" + EquipmentBLL.GetRuntime(TotalWorkedMinutes) + "</td>" + "<td class=\"in-tab-title-b\" style=\"text-align: right;\">" + TotalUsedHour + "</td>" + "<td class=\"in-tab-title-rb\" style=\"text-align: right;\">" + compensate + "</td>" + "<td class=\"in-tab-title-b\" style=\"text-align: right;\">" + TotalAddedMinutes + "/" + EquipmentBLL.GetRuntime((int?)TotalAddedMinutes) + "</td>" + "<td class=\"in-tab-title-b\" style=\"text-align: right;\">" + finalAdded + "</td>" + "<td class=\"in-tab-title-rb\" style=\"text-align: right;\">" + finalWork + "</td>" + "<td class=\"in-tab-title-b\"></td>" + "</tr>"; tbodySummary.InnerHtml += summary; if (query.Id > 0) { // 只查询到一个设备时才更新统计数据,否则不需要更新 if (maccount <= 1) { new EquipmentBLL().Update(f => f.id == query.Id, act => { // 实际工作小时数 act.WorkHours = TotalWorkedMinutes / 60.0; // 粗略计算工作小时数 act.UsedHours = TotalUsedHour; // 工作效率 act.HourWorkEfficiency = compensate; // 补偿的小时数 act.AddedHours = TotalAddedMinutes / 60.0; // 实际补偿的小时数 act.CompensatedHours = finalAdded; }); } } } } } if (checkAnalyseDailyWork.Checked) { tbodyBody.InnerHtml = html; } } }