package com.szpg.rmi; import java.util.HashSet; import java.util.Set; import org.apache.log4j.Logger; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; import com.szpg.db.dao.PgAcuCmdDao; import com.szpg.db.dao.PgAcuDao; import com.szpg.db.dao.PgHjsbblDao; import com.szpg.db.dao.impl.PgAcuCmdDaoImpl; import com.szpg.db.dao.impl.PgAcuDaoImpl; import com.szpg.db.dao.impl.PgHjsbblDaoImpl; import com.szpg.db.data.PgAcu; import com.szpg.db.data.PgAcuCmd; import com.szpg.db.data.PgHjsbbl; import com.szpg.plc.message.CommandResponse; import com.szpg.plc.message.command.write.SetDsRstBitCommand; import com.szpg.plc.message.command.write.SetJgUnlockBitCommand; import com.szpg.plc.message.command.write.SetZmOffBitCommand; import com.szpg.plc.message.command.write.SetZmOnBitCommand; import com.szpg.plc.protocol.DTProtocolInterface; import com.szpg.plc.protocol.ProtocolFactory; import com.szpg.plc.protocol.fins.FINSConstants; import com.szpg.plc.server.ACUClient; import com.szpg.plc.server.ACUClientUtil; import com.szpg.plc.util.ByteUtil; import com.szpg.util.Configure; import com.szpg.util.UnicodeConvertor; import z.json.JSONObject; public class RemoteControlCommandAction extends ActionSupport { /** * */ private static final long serialVersionUID = -577795045445769331L; private Set<String> eqsb = new HashSet<String>(); //二期四标段风机所属舱段 private Logger logger = Logger.getLogger(this.getClass().getName()); private String format; private String jsoncallback; private String zcbh; public RemoteControlCommandAction() { // 二期四标段风机控制 eqsb.add("THXC.ACU801"); eqsb.add("THXC.ACU802"); eqsb.add("THXC.ACU803"); eqsb.add("THXC.ACU804"); eqsb.add("THXC.ACU806"); } public String getZcbh() { return zcbh; } public void setZcbh(String zcbh) { this.zcbh = zcbh; } public String getFormat() { return format; } public void setFormat(String format) { this.format = format; } public String getJsoncallback() { return jsoncallback; } public void setJsoncallback(String jsoncallback) { this.jsoncallback = jsoncallback; } /** * 远程打开照明 * @return * @throws Exception */ public String trunOnZm() throws Exception { // 返回结果 JSONObject jResult = new JSONObject(); PgAcuDao acuDao = new PgAcuDaoImpl(); PgHjsbblDao blDao = new PgHjsbblDaoImpl(); if (null == zcbh || zcbh.equals("") == true) { jResult.put("success", false); jResult.put("code", "1"); jResult.put("resaon", UnicodeConvertor.string2Unicode("资产编号为空")); returnToFront(jResult); return null; } // String acucode = deviceDao.findAcuCodeByCode(zcbh); String acucode = zcbh.substring(0, zcbh.indexOf(".", 6)); PgAcu acu = acuDao.findACUByCode(acucode); if (null == acu) { jResult.put("success", false); jResult.put("code", "2"); jResult.put("resaon", UnicodeConvertor.string2Unicode("未找到资产对应的PLC主机")); returnToFront(jResult); return null; } ACUClient client = ACUClientUtil.getInstance().getClients().get(acu.getAcu_host() + ":" + acu.getAcu_port()); if (null != client) { // 源地址 String sour = Configure.getProperty("sys", "LOCALHOST.NET") + Configure.getProperty("sys", "LOCALHOST.NODE") + Configure.getProperty("sys", "LOCALHOST.UNIT"); // 目标地址 String dest = client.getNet() + client.getNode() + client.getUnit(); DTProtocolInterface finspi = ProtocolFactory.getDefaultDTProtocol(); // 1首先将停止位置0 SetZmOffBitCommand clearOffCmd = new SetZmOffBitCommand(); clearOffCmd.setZmoff(SetZmOffBitCommand.ZM_OFF_DISABLE); PgHjsbbl offBlObj = blDao.findBlByBh(zcbh + ".OFF"); if (null != offBlObj) { clearOffCmd.setMessageProducerId(sour); clearOffCmd.setDestinationId(dest); // SID在new对象的时候已经生成 // 内存区域——按位写 clearOffCmd.setMemoryArea(FINSConstants.MEMORY_WORK_AREA_BIT); int start = offBlObj.getKszdz(); int end = offBlObj.getJszdz(); int bit = offBlObj.getSzw(); // 开始字地址 clearOffCmd.setStartAddress(ByteUtil.binToHexString(ByteUtil.intToBins(start, 2))); // 位地址 clearOffCmd.setBit(bit); // 位数 clearOffCmd.setCount(end - start + 1); // 位内容 clearOffCmd.setValue(new byte[] {(byte) clearOffCmd.getZmoff()} ); // 解析命令对象为字节数组 byte[] content = finspi.messageToBytes(clearOffCmd); // 通过socket接口发送出去 ACUClientUtil.getInstance().sendACUCommand(client, content); } else { jResult.put("success", false); jResult.put("code", "4"); jResult.put("reason", UnicodeConvertor.string2Unicode("未找到资产对应的关灯变量")); returnToFront(jResult); return null; } // 暂停1秒后发送远程打开照明的命令 try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO 阻塞线程被打断,需要处理异常 // 目前的处理流程为1)记录日志 logger.error("清除停止位后的阻塞等待线程被打断", e); } // 2 发送设置启动位的命令 SetZmOnBitCommand setOnCmd = new SetZmOnBitCommand(); setOnCmd.setZmon(SetZmOnBitCommand.ZM_ON_ENABLE); PgHjsbbl onBlObj = blDao.findBlByBh(zcbh + ".ON"); if (null != onBlObj) { setOnCmd.setMessageProducerId(sour); setOnCmd.setDestinationId(dest); // SID在new对象的时候已经生成 // 内存区域——按位写 setOnCmd.setMemoryArea(FINSConstants.MEMORY_WORK_AREA_BIT); int start = onBlObj.getKszdz(); int end = onBlObj.getJszdz(); int bit = onBlObj.getSzw(); // 开始字地址 setOnCmd.setStartAddress(ByteUtil.binToHexString(ByteUtil.intToBins(start, 2))); // 位地址 setOnCmd.setBit(bit); // 位数 setOnCmd.setCount(end - start + 1); // 位内容 setOnCmd.setValue(new byte[] {(byte) setOnCmd.getZmon()} ); // 解析命令对象为字节数组 byte[] content = finspi.messageToBytes(setOnCmd); // 通过socket接口发送出去 ACUClientUtil.getInstance().sendACUCommand(client, content); } else { jResult.put("success", false); jResult.put("code", "4"); jResult.put("reason", UnicodeConvertor.string2Unicode("未找到资产对应的开灯变量")); returnToFront(jResult); return null; } // 3将命令存入数据库 PgAcuCmdDao cmdDao = new PgAcuCmdDaoImpl(); PgAcuCmd cmd = new PgAcuCmd(); cmd.setCmd_type(setOnCmd.getCommandType()); cmd.setDest_acu_code(acucode); cmd.setTm(setOnCmd.getTime().getTime()); cmdDao.addCmdRecord(cmd); // 4阻塞,循环查找响应消息池,找到对应的响应消息 boolean flag = false; int times = 0; CommandResponse response = null; while (flag == false && times < 240) { response = ACUClientUtil.getInstance().responsePool.getResponse(cmd.getId()); if (null != response && response.equals("") == false) { flag = true; } times++; try { Thread.sleep(500); } catch (InterruptedException e) { // 目前的处理流程为1)记录日志;2)将命令置为超时 logger.error("在响应池中查找命令的响应消息阻塞线程被异常打断", e); cmdDao.updateCmdRecordTimeout(cmd.getId()); jResult.put("success", false); jResult.put("code", "5"); jResult.put("reason", UnicodeConvertor.string2Unicode("查找命令的响应消息时异常")); returnToFront(jResult); return null; } } // 5若未超时,将值存入数据库 if (null != response) { // 6根据命令类型的不同将监测值存入对应的数据库 response.afterAction(); // 成功返回 jResult.put("success", true); jResult.put("code", "0"); returnToFront(jResult); return null; } else { // 9超时,将命令的超时标志位置1 logger.warn("命令超时" + cmd.getId()); cmdDao.updateCmdRecordTimeout(cmd.getId()); jResult.put("success", false); jResult.put("code", "6"); jResult.put("reason", UnicodeConvertor.string2Unicode("命令发送超时")); returnToFront(jResult); return null; } } else { jResult.put("success", false); jResult.put("code", "3"); jResult.put("resaon", UnicodeConvertor.string2Unicode("PLC主机不在线")); returnToFront(jResult); return null; } } /** * 远程关闭照明 * @return * @throws Exception */ public String turnOffZm() throws Exception { // 返回结果 JSONObject jResult = new JSONObject(); // 查找ACU的信息 PgAcuDao acuDao = new PgAcuDaoImpl(); PgHjsbblDao blDao = new PgHjsbblDaoImpl(); if (null == zcbh || zcbh.equals("") == true) { jResult.put("success", false); jResult.put("code", "1"); jResult.put("resaon", UnicodeConvertor.string2Unicode("资产编号为空")); returnToFront(jResult); return null; } String acucode = zcbh.substring(0, zcbh.indexOf(".", 6)); PgAcu acu = acuDao.findACUByCode(acucode); if (null == acu) { jResult.put("success", false); jResult.put("code", "2"); jResult.put("resaon", UnicodeConvertor.string2Unicode("未找到资产对应的PLC主机")); returnToFront(jResult); return null; } ACUClient client = ACUClientUtil.getInstance().getClients().get(acu.getAcu_host() + ":" + acu.getAcu_port()); if (null != client) { // 源地址 String sour = Configure.getProperty("sys", "LOCALHOST.NET") + Configure.getProperty("sys", "LOCALHOST.NODE") + Configure.getProperty("sys", "LOCALHOST.UNIT"); // 目标地址 String dest = client.getNet() + client.getNode() + client.getUnit(); DTProtocolInterface finspi = ProtocolFactory.getDefaultDTProtocol(); // 1首先将启动位置0 SetZmOnBitCommand clearOnCmd = new SetZmOnBitCommand(); clearOnCmd.setZmon(SetZmOnBitCommand.ZM_ON_DISABLE); PgHjsbbl onBlObj = blDao.findBlByBh(zcbh + ".ON"); if (null != onBlObj) { clearOnCmd.setMessageProducerId(sour); clearOnCmd.setDestinationId(dest); // SID在new对象的时候已经生成 // 内存区域——按位写 clearOnCmd.setMemoryArea(FINSConstants.MEMORY_WORK_AREA_BIT); int start = onBlObj.getKszdz(); int end = onBlObj.getJszdz(); int bit = onBlObj.getSzw(); // 开始字地址 clearOnCmd.setStartAddress(ByteUtil.binToHexString(ByteUtil.intToBins(start, 2))); // 位地址 clearOnCmd.setBit(bit); // 位数 clearOnCmd.setCount(end - start + 1); // 位内容 clearOnCmd.setValue(new byte[] {(byte) clearOnCmd.getZmon()} ); // 解析命令对象为字节数组 byte[] content = finspi.messageToBytes(clearOnCmd); // 通过socket接口发送出去 ACUClientUtil.getInstance().sendACUCommand(client, content); } // 暂停1秒后发送远程关闭照明的命令 try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO 阻塞线程被打断,需要处理异常 // 目前的处理流程为1)记录日志 logger.error("清除启动位后的阻塞等待线程被打断", e); } // 2 发送设置启动位的命令 SetZmOffBitCommand setOffCmd = new SetZmOffBitCommand(); setOffCmd.setZmoff(SetZmOffBitCommand.ZM_OFF_ENABLE); PgHjsbbl offBlObj = blDao.findBlByBh(zcbh + ".OFF"); if (null != offBlObj) { setOffCmd.setMessageProducerId(sour); setOffCmd.setDestinationId(dest); // SID在new对象的时候已经生成 // 内存区域——按位写 setOffCmd.setMemoryArea(FINSConstants.MEMORY_WORK_AREA_BIT); int start = offBlObj.getKszdz(); int end = offBlObj.getJszdz(); int bit = offBlObj.getSzw(); // 开始字地址 setOffCmd.setStartAddress(ByteUtil.binToHexString(ByteUtil.intToBins(start, 2))); // 位地址 setOffCmd.setBit(bit); // 位数 setOffCmd.setCount(end - start + 1); // 位内容 setOffCmd.setValue(new byte[] {(byte) setOffCmd.getZmoff()} ); // 解析命令对象为字节数组 byte[] content = finspi.messageToBytes(setOffCmd); // 通过socket接口发送出去 ACUClientUtil.getInstance().sendACUCommand(client, content); } else { jResult.put("success", false); jResult.put("code", "4"); jResult.put("reason", UnicodeConvertor.string2Unicode("未找到资产对应的关灯变量")); returnToFront(jResult); return null; } // 3将命令存入数据库 PgAcuCmdDao cmdDao = new PgAcuCmdDaoImpl(); PgAcuCmd cmd = new PgAcuCmd(); cmd.setCmd_type(setOffCmd.getCommandType()); cmd.setDest_acu_code(acucode); cmd.setTm(setOffCmd.getTime().getTime()); cmdDao.addCmdRecord(cmd); // 4阻塞,循环查找响应消息池,找到对应的响应消息 boolean flag = false; int times = 0; CommandResponse response = null; while (flag == false && times < 240) { response = ACUClientUtil.getInstance().responsePool.getResponse(cmd.getId()); if (null != response && response.equals("") == false) { flag = true; } times++; try { Thread.sleep(500); } catch (InterruptedException e) { // 目前的处理流程为1)记录日志;2)将命令置为超时 logger.error("在响应池中查找命令的响应消息阻塞线程被异常打断", e); cmdDao.updateCmdRecordTimeout(cmd.getId()); jResult.put("success", false); jResult.put("code", "5"); jResult.put("reason", UnicodeConvertor.string2Unicode("查找命令的响应消息时异常")); returnToFront(jResult); return null; } } // 5若未超时,将值存入数据库 if (null != response) { // 6根据命令类型的不同将监测值存入对应的数据库 response.afterAction(); // 成功返回 jResult.put("success", true); jResult.put("code", "0"); returnToFront(jResult); return null; } else { // 9超时,将命令的超时标志位置1 logger.warn("命令超时" + cmd.getId()); cmdDao.updateCmdRecordTimeout(cmd.getId()); jResult.put("success", false); jResult.put("code", "6"); jResult.put("reason", UnicodeConvertor.string2Unicode("命令发送超时")); returnToFront(jResult); return null; } } else { jResult.put("success", false); jResult.put("code", "3"); jResult.put("resaon", UnicodeConvertor.string2Unicode("PLC主机不在线")); returnToFront(jResult); return null; } } /** * 远程解锁井盖 * @return * @throws Exception */ public String unlockJg() throws Exception { // 返回结果 JSONObject jResult = new JSONObject(); if (null == zcbh || zcbh.equals("") == true) { jResult.put("success", false); jResult.put("code", "1"); jResult.put("resaon", UnicodeConvertor.string2Unicode("资产编号为空")); returnToFront(jResult); return null; } // 查找ACU的信息 PgAcuDao acuDao = new PgAcuDaoImpl(); PgHjsbblDao blDao = new PgHjsbblDaoImpl(); String acucode = zcbh.substring(0, zcbh.indexOf(".", 6)); PgAcu acu = acuDao.findACUByCode(acucode); if (null == acu) { jResult.put("success", false); jResult.put("code", "2"); jResult.put("resaon", UnicodeConvertor.string2Unicode("未找到资产对应的PLC主机")); returnToFront(jResult); return null; } ACUClient client = ACUClientUtil.getInstance().getClients().get(acu.getAcu_host() + ":" + acu.getAcu_port()); if (null != client) { // 源地址 String sour = Configure.getProperty("sys", "LOCALHOST.NET") + Configure.getProperty("sys", "LOCALHOST.NODE") + Configure.getProperty("sys", "LOCALHOST.UNIT"); // 目标地址 String dest = client.getNet() + client.getNode() + client.getUnit(); DTProtocolInterface finspi = ProtocolFactory.getDefaultDTProtocol(); // 发送设置解锁位的命令 SetJgUnlockBitCommand setUnlockCmd = new SetJgUnlockBitCommand(); setUnlockCmd.setUnlock(SetJgUnlockBitCommand.JG_UNLOCK); PgHjsbbl unlockBlObj = blDao.findBlByBh(zcbh + ".Lock"); if (null != unlockBlObj) { setUnlockCmd.setMessageProducerId(sour); setUnlockCmd.setDestinationId(dest); // SID在new对象的时候已经生成 // 内存区域——按位写 setUnlockCmd.setMemoryArea(FINSConstants.MEMORY_WORK_AREA_BIT); int start = unlockBlObj.getKszdz(); int end = unlockBlObj.getJszdz(); int bit = unlockBlObj.getSzw(); // 开始字地址 setUnlockCmd.setStartAddress(ByteUtil.binToHexString(ByteUtil.intToBins(start, 2))); // 位地址 setUnlockCmd.setBit(bit); // 位数 setUnlockCmd.setCount(end - start + 1); // 位内容 setUnlockCmd.setValue(new byte[] {(byte) SetJgUnlockBitCommand.JG_UNLOCK} ); // 解析命令对象为字节数组 byte[] content = finspi.messageToBytes(setUnlockCmd); // 通过socket接口发送出去 ACUClientUtil.getInstance().sendACUCommand(client, content); } else { jResult.put("success", false); jResult.put("code", "4"); jResult.put("reason", UnicodeConvertor.string2Unicode("未找到资产对应的解锁井盖变量")); returnToFront(jResult); return null; } // 3将命令存入数据库 PgAcuCmdDao cmdDao = new PgAcuCmdDaoImpl(); PgAcuCmd cmd = new PgAcuCmd(); cmd.setCmd_type(setUnlockCmd.getCommandType()); cmd.setDest_acu_code(acucode); cmd.setTm(setUnlockCmd.getTime().getTime()); cmdDao.addCmdRecord(cmd); // 4阻塞,循环查找响应消息池,找到对应的响应消息 boolean flag = false; int times = 0; CommandResponse response = null; while (flag == false && times < 240) { response = ACUClientUtil.getInstance().responsePool.getResponse(cmd.getId()); if (null != response && response.equals("") == false) { flag = true; } times++; try { Thread.sleep(500); } catch (InterruptedException e) { // 目前的处理流程为1)记录日志;2)将命令置为超时 logger.error("在响应池中查找命令的响应消息阻塞线程被异常打断", e); cmdDao.updateCmdRecordTimeout(cmd.getId()); jResult.put("success", false); jResult.put("code", "5"); jResult.put("reason", UnicodeConvertor.string2Unicode("查找命令的响应消息时异常")); returnToFront(jResult); return null; } } // 5若未超时,将值存入数据库 if (null != response) { // 6根据命令类型的不同将监测值存入对应的数据库 response.afterAction(); // 成功返回 jResult.put("success", true); jResult.put("code", "0"); returnToFront(jResult); return null; } else { // 9超时,将命令的超时标志位置1 logger.warn("命令超时" + cmd.getId()); cmdDao.updateCmdRecordTimeout(cmd.getId()); jResult.put("success", false); jResult.put("code", "6"); jResult.put("reason", UnicodeConvertor.string2Unicode("命令发送超时")); returnToFront(jResult); return null; } } else { jResult.put("success", false); jResult.put("code", "3"); jResult.put("resaon", UnicodeConvertor.string2Unicode("PLC主机不在线")); returnToFront(jResult); return null; } } /** * 远程锁定井盖 * @return * @throws Exception */ public String lockJg() throws Exception { // 返回结果 JSONObject jResult = new JSONObject(); if (null == zcbh || zcbh.equals("") == true) { jResult.put("success", false); jResult.put("code", "1"); jResult.put("resaon", UnicodeConvertor.string2Unicode("资产编号为空")); returnToFront(jResult); return null; } // 查找ACU的信息 PgAcuDao acuDao = new PgAcuDaoImpl(); PgHjsbblDao blDao = new PgHjsbblDaoImpl(); String acucode = zcbh.substring(0, zcbh.indexOf(".", 6)); PgAcu acu = acuDao.findACUByCode(acucode); if (null == acu) { jResult.put("success", false); jResult.put("code", "2"); jResult.put("resaon", UnicodeConvertor.string2Unicode("未找到资产对应的PLC主机")); returnToFront(jResult); return null; } ACUClient client = ACUClientUtil.getInstance().getClients().get(acu.getAcu_host() + ":" + acu.getAcu_port()); if (null != client) { // 源地址 String sour = Configure.getProperty("sys", "LOCALHOST.NET") + Configure.getProperty("sys", "LOCALHOST.NODE") + Configure.getProperty("sys", "LOCALHOST.UNIT"); // 目标地址 String dest = client.getNet() + client.getNode() + client.getUnit(); DTProtocolInterface finspi = ProtocolFactory.getDefaultDTProtocol(); SetJgUnlockBitCommand setLockCmd = new SetJgUnlockBitCommand(); setLockCmd.setUnlock(SetJgUnlockBitCommand.JG_LOCK); PgHjsbbl lockBlObj = blDao.findBlByBh(zcbh + ".Lock"); if (null != lockBlObj) { setLockCmd.setMessageProducerId(sour); setLockCmd.setDestinationId(dest); // SID在new对象的时候已经生成 // 内存区域——按位写 setLockCmd.setMemoryArea(FINSConstants.MEMORY_WORK_AREA_BIT); int start = lockBlObj.getKszdz(); int end = lockBlObj.getJszdz(); int bit = lockBlObj.getSzw(); // 开始字地址 setLockCmd.setStartAddress(ByteUtil.binToHexString(ByteUtil.intToBins(start, 2))); // 位地址 setLockCmd.setBit(bit); // 位数 setLockCmd.setCount(end - start + 1); // 位内容 setLockCmd.setValue(new byte[] {(byte) SetJgUnlockBitCommand.JG_LOCK} ); // 解析命令对象为字节数组 byte[] content = finspi.messageToBytes(setLockCmd); // 通过socket接口发送出去 ACUClientUtil.getInstance().sendACUCommand(client, content); } else { jResult.put("success", false); jResult.put("code", "4"); jResult.put("reason", UnicodeConvertor.string2Unicode("未找到资产对应的锁定井盖变量")); returnToFront(jResult); return null; } // 3将命令存入数据库 PgAcuCmdDao cmdDao = new PgAcuCmdDaoImpl(); PgAcuCmd cmd = new PgAcuCmd(); cmd.setCmd_type(setLockCmd.getCommandType()); cmd.setDest_acu_code(acucode); cmd.setTm(setLockCmd.getTime().getTime()); cmdDao.addCmdRecord(cmd); // 4阻塞,循环查找响应消息池,找到对应的响应消息 boolean flag = false; int times = 0; CommandResponse response = null; while (flag == false && times < 240) { response = ACUClientUtil.getInstance().responsePool.getResponse(cmd.getId()); if (null != response && response.equals("") == false) { flag = true; } times++; try { Thread.sleep(500); } catch (InterruptedException e) { // 目前的处理流程为1)记录日志;2)将命令置为超时 logger.error("在响应池中查找命令的响应消息阻塞线程被异常打断", e); cmdDao.updateCmdRecordTimeout(cmd.getId()); jResult.put("success", false); jResult.put("code", "5"); jResult.put("reason", UnicodeConvertor.string2Unicode("查找命令的响应消息时异常")); returnToFront(jResult); return null; } } // 5若未超时,将值存入数据库 if (null != response) { // 6根据命令类型的不同将监测值存入对应的数据库 response.afterAction(); // 成功返回 jResult.put("success", true); jResult.put("code", "0"); returnToFront(jResult); return null; } else { // 9超时,将命令的超时标志位置1 logger.warn("命令超时" + cmd.getId()); cmdDao.updateCmdRecordTimeout(cmd.getId()); jResult.put("success", false); jResult.put("code", "6"); jResult.put("reason", UnicodeConvertor.string2Unicode("命令发送超时")); returnToFront(jResult); return null; } } else { jResult.put("success", false); jResult.put("code", "3"); jResult.put("resaon", UnicodeConvertor.string2Unicode("PLC主机不在线")); returnToFront(jResult); return null; } } /** * 清除对射报警 * @return * @throws Exception */ public String clearDsAlarm() throws Exception { // 返回结果 JSONObject jResult = new JSONObject(); if (null == zcbh || zcbh.equals("") == true) { jResult.put("success", false); jResult.put("code", "1"); jResult.put("resaon", UnicodeConvertor.string2Unicode("资产编号为空")); returnToFront(jResult); return null; } // 查找ACU的信息 PgAcuDao acuDao = new PgAcuDaoImpl(); PgHjsbblDao blDao = new PgHjsbblDaoImpl(); String acucode = zcbh.substring(0, zcbh.indexOf(".", 6)); PgAcu acu = acuDao.findACUByCode(acucode); if (null == acu) { jResult.put("success", false); jResult.put("code", "2"); jResult.put("resaon", UnicodeConvertor.string2Unicode("未找到资产对应的PLC主机")); returnToFront(jResult); return null; } ACUClient client = ACUClientUtil.getInstance().getClients().get(acu.getAcu_host() + ":" + acu.getAcu_port()); if (null != client) { // 源地址 String sour = Configure.getProperty("sys", "LOCALHOST.NET") + Configure.getProperty("sys", "LOCALHOST.NODE") + Configure.getProperty("sys", "LOCALHOST.UNIT"); // 目标地址 String dest = client.getNet() + client.getNode() + client.getUnit(); DTProtocolInterface finspi = ProtocolFactory.getDefaultDTProtocol(); // 发送设置解锁位的命令 SetDsRstBitCommand setRstCmd = new SetDsRstBitCommand(); PgHjsbbl onBlObj = blDao.findBlByBh(zcbh + ".RST"); if (null != onBlObj) { setRstCmd.setMessageProducerId(sour); setRstCmd.setDestinationId(dest); // SID在new对象的时候已经生成 // 内存区域——按位写 setRstCmd.setMemoryArea(FINSConstants.MEMORY_WORK_AREA_BIT); int start = onBlObj.getKszdz(); int end = onBlObj.getJszdz(); int bit = onBlObj.getSzw(); // 开始字地址 setRstCmd.setStartAddress(ByteUtil.binToHexString(ByteUtil.intToBins(start, 2))); // 位地址 setRstCmd.setBit(bit); // 位数 setRstCmd.setCount(end - start + 1); // 位内容 setRstCmd.setValue(new byte[] {(byte) SetDsRstBitCommand.DS_RST} ); // 解析命令对象为字节数组 byte[] content = finspi.messageToBytes(setRstCmd); // 通过socket接口发送出去 ACUClientUtil.getInstance().sendACUCommand(client, content); } else { jResult.put("success", false); jResult.put("code", "4"); jResult.put("reason", UnicodeConvertor.string2Unicode("未找到资产对应的清除对射报警变量")); returnToFront(jResult); return null; } // 3将命令存入数据库 PgAcuCmdDao cmdDao = new PgAcuCmdDaoImpl(); PgAcuCmd cmd = new PgAcuCmd(); cmd.setCmd_type(setRstCmd.getCommandType()); cmd.setDest_acu_code(acucode); cmd.setTm(setRstCmd.getTime().getTime()); cmdDao.addCmdRecord(cmd); // 4阻塞,循环查找响应消息池,找到对应的响应消息 boolean flag = false; int times = 0; CommandResponse response = null; while (flag == false && times < 240) { response = ACUClientUtil.getInstance().responsePool.getResponse(cmd.getId()); if (null != response && response.equals("") == false) { flag = true; } times++; try { Thread.sleep(500); } catch (InterruptedException e) { // 目前的处理流程为1)记录日志;2)将命令置为超时 logger.error("在响应池中查找命令的响应消息阻塞线程被异常打断", e); cmdDao.updateCmdRecordTimeout(cmd.getId()); jResult.put("success", false); jResult.put("code", "5"); jResult.put("reason", UnicodeConvertor.string2Unicode("查找命令的响应消息时异常")); returnToFront(jResult); return null; } } // 5若未超时,将值存入数据库 if (null != response) { // 6根据命令类型的不同将监测值存入对应的数据库 response.afterAction(); // 成功返回 jResult.put("success", true); jResult.put("code", "0"); returnToFront(jResult); return null; } else { // 9超时,将命令的超时标志位置1 logger.warn("命令超时" + cmd.getId()); cmdDao.updateCmdRecordTimeout(cmd.getId()); jResult.put("success", false); jResult.put("code", "6"); jResult.put("reason", UnicodeConvertor.string2Unicode("命令发送超时")); returnToFront(jResult); return null; } } else { jResult.put("success", false); jResult.put("code", "3"); jResult.put("resaon", UnicodeConvertor.string2Unicode("PLC主机不在线")); returnToFront(jResult); return null; } } /** * 给前端返回 * @param jResult * @throws Exception */ private void returnToFront(JSONObject jResult) throws Exception { // 返回jsonp格式的数据 if (null != format && format.equalsIgnoreCase("jsonp") == true) { ServletActionContext.getResponse().getWriter().write(jsoncallback + "(" + jResult.toString() + ");"); } ServletActionContext.getResponse().getWriter().write(jResult.toString()); } }