package com.szpg.task; import org.apache.log4j.Logger; import com.szpg.db.dao.PgAcuCmdDao; import com.szpg.db.dao.PgAcuDao; import com.szpg.db.dao.PgDeviceDao; 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.PgDeviceDaoImpl; 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.SetFjOffBitCommand; import com.szpg.plc.message.command.write.SetFjOnBitCommand; 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; public class TurnOnFjTask implements Runnable { private Logger logger = Logger.getLogger(this.getClass().getName()); private String deviceCode; private PgHjsbblDao blDao = new PgHjsbblDaoImpl(); public TurnOnFjTask(String deviceCode) { this.deviceCode = deviceCode; } @Override public void run() { // 查找ACU的信息 PgAcuDao acuDao = new PgAcuDaoImpl(); PgDeviceDao deviceDao = new PgDeviceDaoImpl(); String acucode = deviceDao.findAcuCodeByCode(deviceCode); PgAcu acu = acuDao.findACUByCode(acucode); 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 SetFjOffBitCommand clearOffCmd = new SetFjOffBitCommand(); clearOffCmd.setFjoff(SetFjOffBitCommand.FJ_OFF_DISABLE); PgHjsbbl offBlObj = blDao.findBlByBh(deviceCode + ".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.getFjoff()} ); // 解析命令对象为字节数组 byte[] content = finspi.messageToBytes(clearOffCmd); // 通过socket接口发送出去 ACUClientUtil.getInstance().sendACUCommand(client, content); } try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO 阻塞线程被打断,需要处理异常 // 目前的处理流程为1)记录日志 logger.error("清除停止位后的阻塞等待线程被打断", e); } // 2 发送设置启动位的命令 SetFjOnBitCommand setOnCmd = new SetFjOnBitCommand(); setOnCmd.setFjon(SetFjOnBitCommand.FJ_ON_ENABLE); PgHjsbbl onBlObj = blDao.findBlByBh(deviceCode + ".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.getFjon()} ); // 解析命令对象为字节数组 byte[] content = finspi.messageToBytes(setOnCmd); // 通过socket接口发送出去 ACUClientUtil.getInstance().sendACUCommand(client, content); } // 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) { // TODO 阻塞线程被打断,需要处理异常 // 目前的处理流程为1)记录日志;2)将命令置为超时 logger.error("在响应池中查找命令的响应消息阻塞线程被异常打断", e); cmdDao.updateCmdRecordTimeout(cmd.getId()); return; } } // 5若未超时,将值存入数据库 if (null != response) { // 6根据命令类型的不同将监测值存入对应的数据库 response.afterAction(); } else { // 9超时,将命令的超时标志位置1 logger.warn("命令超时" + cmd.getId()); cmdDao.updateCmdRecordTimeout(cmd.getId()); } } } }