/* * 根据接收的byte数组更新终端的实时信息, array1[]为16字节的参数(此函数在主线程中执行) * 返回true表示更新成功, 否则更新失败(未找到匹配的终端) * 与主线程同步执行 */ void UpdateTerInfoByBytes(object array) { if (!isPlayBackMode) //若不是回放模式 { byte[] array1 = (byte[])array; if (AppUtil.bytesToInt(array1, 1, 3) == SysConfig.Setting.groupNumber) //若组号匹配 { int index = 255; for (int i = 0; i < users.Count; i++) { if (users[i].BasicInfo.terminalNO == (byte)array1[4]) { index = i; break; } } if (index != 255) //若找到了匹配的终端 { //改变标志 users[index].isChanged = true; users[index].isRecvPack = true; //压力, 单位为MPa users[index].TerminalInfo.Pressure = User.GetPressDoubleByBytes(array1, 5); //电压, 单位为V users[index].TerminalInfo.Voltage = User.GetVoltageDoubleByBytes(array1, 7); //温度 users[index].TerminalInfo.Temperature = array1[9];// User.GetTemeratureIntByByte(array1[9]); //开机时间 users[index].TerminalInfo.PowerONTime = User.GetTimeIntByBytes(array1, 10); //状态 users[index].TerminalInfo.TerminalStatus = array1[15]; //计算剩余时间 double A = 0; //由30s下降值计算出来的时间 double B = 0; //由气压值计算出来的时间 bool isAvalid = false; //计算的A值是否有效标志: 若30s内无下降, 则计算出来的置为A无效 if (users[index].TerminalInfo.Pressure <= 2.0) //若当前气压小于2, 则计算的结果肯定是负数, 则将A和B都置0, 剩余时间当做0 { A = 0; B = 0; } else //若当前气压大于2, 则需要计算A 和 B, 取小的那一个 { //计算A ---- 由30s下降值计算出来的时间 if (users[index].TerminalInfo.PressDropDownIn30s > 0) //若30s内气压值是下降的, 则可以计算A { isAvalid = true; A = (users[index].TerminalInfo.Pressure - 2) / (users[index].TerminalInfo.PressDropDownIn30s * 2); //由30s下降值计算出来的时间 } else { A = 0; isAvalid = false; } //计算B ---- 由气压值计算出来的时间 if (users[index].BasicInfo.terminalCapSpec == "6.8") //6.8L的气瓶 { B = (users[index].TerminalInfo.Pressure - 2) * 6.8 * 10 / 50; } else if (users[index].BasicInfo.terminalCapSpec == "9") //9L的气瓶 { B = (users[index].TerminalInfo.Pressure - 2) * 9 * 10 / 50; } } //更新剩余时间, 取A、B中小的一方 if (A < B) { if (isAvalid) //若A有效, 则取A, 否则取B { users[index].TerminalInfo.RemainTime = (int)A; } else { users[index].TerminalInfo.RemainTime = (int)B; } } else { users[index].TerminalInfo.RemainTime = (int)B; } //若用户状态不是撤出中, 则更改用户状态 if (users[index].UStatus != USERSTATUS.RetreatingStatus) { if (users[index].TerminalInfo.Pressure > 10) //安全状态 { users[index].UStatus = USERSTATUS.SafeStatus; } else if (users[index].TerminalInfo.Pressure > 6) //轻度危险 { users[index].UStatus = USERSTATUS.MildDangerousStatus; } else { users[index].UStatus = USERSTATUS.DangerousStatus; //危险状态 } } else //否则更新气压 { users[index].UStatus = USERSTATUS.RetreatingStatus; } //若当前详情窗口显示的是本用户, 则更新详情窗口的显示 if (users[index] == detailsForm.CurUser) { detailsForm.UpdateDetailForm(); } //判断是否报警 //若终端不是关机、不存在状态, 则需要设置其报警状态 if (users[index].UStatus != USERSTATUS.NoExistStatus && users[index].UStatus != USERSTATUS.PowerOffStatus) { try { users[index].AlarmFlagForLost = false; bool IsUserExceedTh = false; //用户是否超出阈值标识 //1. 分析用户是否超阈值, 存储在标志IsUserExceedTh中 if (SysConfig.Setting.alarmThreshold == 0) //若设定阈值为气瓶容量的50% { double terminalCapSpec = double.Parse(users[index].BasicInfo.terminalCapSpec); //获取气瓶容量 if (users[index].TerminalInfo.Pressure < (terminalCapSpec / 2.0)) //若小于气瓶容量的50%--超出阈值 { IsUserExceedTh = true; //用户超阈值 } else { IsUserExceedTh = false; //没有超出阈值 } } else if (SysConfig.Setting.alarmThreshold == 1) //若设定阈值为10MPa { if (users[index].TerminalInfo.Pressure < 10.0) //若小于10MPa--超出阈值 { IsUserExceedTh = true; //用户超阈值 } else //没有超出阈值 { IsUserExceedTh = false; //没有超出阈值 } } else if (SysConfig.Setting.alarmThreshold == 2) //若设定阈值为6MPa { if (users[index].TerminalInfo.Pressure < 6.0) //若小于6MPa--超出阈值 { IsUserExceedTh = true; //用户超阈值 } else //没有超出阈值 { IsUserExceedTh = false; //没有超出阈值 } } //2. 更新当前用户的"超阈值报警标志" if (IsUserExceedTh) //若用户超阈值 { if (users[index].IsExceedThreshold == false) //若上一次没有超过阈值, 但本次超出阈值, 则开启"超阈值报警" { users[index].AlarmFlagForExceedTh = true; } else //若上一次超过阈值, 且本次继续超出阈值, 则不去处理 { } } else //若用户没有超阈值 { if (users[index].IsExceedThreshold == true) //若上一次超过阈值, 但本次没有超出阈值, 则停止"超阈值报警" { users[index].AlarmFlagForExceedTh = false; } else //若上一次没有超过阈值, 且本次继续没有超出阈值, 则不去处理 { } } //3. 更新用户超阈值标志 users[index].IsExceedThreshold = IsUserExceedTh; } catch (Exception ex) { Console.WriteLine(ex.Message); } } //写入用户状态记录到日志文件中 worklog.LogQueue_Enqueue(LogCommand.getUserStatusRecord(users[index])); //写入用户状态记录到回放日志文件中 //worklogplay.LogPlayQueue_Enqueue(LogPlayCommand.getUserStatusRecord(users[index])); //若开启了实时上传 且 服务器已连接, 则上传到服务器 if (isRealTimeUploading && netcom.isConnected && isAuthPass && isInternetAvailiable) //若网络连接正常 且 验证通过 且 服务器在线 { //netcom.NetSendQueue_Enqueue(NetCommand.NetUploadUserPacket(users[index])); } } } } }
/* * 改变用户状态, terminalNO为终端号 * 与主线程同步执行 */ public void ChangeUserState(object statusPara1) { UserStatusPara statusPara = (UserStatusPara)statusPara1; int index = 255; if (!isPlayBackMode) //若不是回放模式 { for (int i = 0; i < users.Count; i++) { if (users[i].BasicInfo.terminalNO == (int)(statusPara.teriminalNO)) { index = i; break; } } if (index != 255) //找到匹配的终端 { users[index].UStatus = statusPara.status; //改变标志 users[index].isChanged = true; //若当前详情窗口显示的是本用户, 则更新详情窗口的显示 if (users[index] == detailsForm.CurUser) { detailsForm.Update(); } //判断用户是否需要报警 if (users[index].UStatus == USERSTATUS.LoseContactStatus) //失去联系需要报警 { users[index].AlarmFlagForLost = true; users[index].isRecvPack = false; } else if (users[index].UStatus == USERSTATUS.RetreatFailStatus) //撤出失败需要报警 { users[index].AlarmFlagForRetreat = true; users[index].isRecvPack = false; } else if (users[index].UStatus == USERSTATUS.PowerOffStatus) //撤出失败需要清除报警标志和超出阈值标志 { users[index].IsExceedThreshold = false; users[index].AlarmFlagForExceedTh = false; users[index].AlarmFlagForLost = false; users[index].AlarmFlagForRetreat = false; users[index].isRecvPack = true; } else //否则将失去联系与撤出失败报警标志清除 { users[index].AlarmFlagForLost = false; users[index].AlarmFlagForRetreat = false; users[index].isRecvPack = true; } //写入用户状态记录到日志文件中 worklog.LogQueue_Enqueue(LogCommand.getUserStatusRecord(users[index])); //写入用户状态记录到回放日志文件中 //worklogplay.LogPlayQueue_Enqueue(LogPlayCommand.getUserStatusRecord(users[index])); //上传到服务器 if (isRealTimeUploading && netcom.isConnected && isAuthPass && isInternetAvailiable) //若网络连接正常 且 验证通过 且 服务器在线 { //netcom.NetSendQueue_Enqueue(NetCommand.NetUploadUserPacket(users[index])); } } } }