package com.szpg.rmi; import com.opensymphony.xwork2.ActionSupport; import com.szpg.db.dao.PgAcuDao; import com.szpg.db.dao.PgDeviceDao; import com.szpg.db.dao.PgFjDao; import com.szpg.db.dao.impl.PgAcuDaoImpl; import com.szpg.db.dao.impl.PgDeviceDaoImpl; import com.szpg.db.dao.impl.PgFjDaoImpl; import com.szpg.db.data.PgAcu; import com.szpg.db.data.PgDevice; import com.szpg.db.data.PgFjStat; import com.szpg.plc.message.AppMessageConstants; import com.szpg.plc.message.command.ReadMemoryCommand; 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.service.ReadControllerStatusService; import com.szpg.service.RemoteDeviceControlService; import com.szpg.service.command.ExhaustFanCommandService; import com.szpg.util.Configure; import com.szpg.util.HttpRequest; import com.szpg.util.UnicodeConvertor; import org.apache.log4j.Logger; import org.apache.struts2.ServletActionContext; import z.json.JSONObject; import java.util.List; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class RemoteFJCommandAction extends ActionSupport { /** * */ private static final long serialVersionUID = 2221187086461756012L; private String zcbh; private String format; private String jsoncallback; private Logger logger = Logger.getLogger(this.getClass().getName()); 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 readFjStatus() throws Exception { // 返回结果 JSONObject jResult = new JSONObject(); PgAcuDao acuDao = new PgAcuDaoImpl(); 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) { ReadMemoryCommand command = ReadMemoryCommand.getInstance(AppMessageConstants.CMD_TYPE_READFJSTAT); String sour = Configure.getProperty("sys", "LOCALHOST.NET") + Configure.getProperty("sys", "LOCALHOST.NODE") + Configure.getProperty("sys", "LOCALHOST.UNIT"); command.setMessageProducerId(sour); command.setMessageProducerHost(client.getHost()); String dest = client.getNet() + client.getNode() + client.getUnit(); command.setDestinationId(dest); command.setMemoryArea(FINSConstants.MEMORY_WORK_AREA_WORD); //按字读取内容 // 二期风机状态所在内存区域为D区 if (client.getFlag().equals("23") || client.getFlag().equals("24")) { command.setMemoryArea(FINSConstants.MEMORY_DM_AREA); } try { // 没有找到对应的配置项,直接返回 String start = Configure.getProperty("acubl", client.getAcucode() + ".FJSTAT.START"); String countWord = Configure.getProperty("acubl", client.getAcucode() + ".FJSTAT.WORDCOUNT"); if (null == start || start.equals("")) { jResult.put("success", false); jResult.put("code", "4"); jResult.put("resaon", UnicodeConvertor.string2Unicode("未找到对应的变量配置项")); returnToFront(jResult); return null; } // 设置读取的地址范围 // 从配置文件读取而来 command.setStartAddress(ByteUtil.binToHexString(ByteUtil.intToBins(Integer.parseInt(start), 2)) + "00"); command.setCountWord(Integer.parseInt(countWord)); // 调用服务过程执行命令发送服务 ReadControllerStatusService service = new ReadControllerStatusService(); service.executeService(client, command); logger.info(command); } catch (Exception ex) { logger.error("发送查询风机状态指令异常" + ex); } jResult.put("success", true); jResult.put("resaon", 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 turnOnFj() 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(); 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 // 该逻辑取消,由设备自行控制 // 2 发送设置启动位的命令 // 构建打开风机指令 SetFjOnBitCommand setOnCmd = ExhaustFanCommandService.buildTurnOnCommand(sour, dest, zcbh); if (null != setOnCmd) { setOnCmd.setMessageProducerHost(client.getHost()); RemoteDeviceControlService service = new RemoteDeviceControlService(); service.executeService(client, setOnCmd, zcbh); Logger.getLogger(this.getClass().getName()).info(setOnCmd); } else { jResult.put("success", false); jResult.put("code", "4"); jResult.put("reason", UnicodeConvertor.string2Unicode("未找到资产对应的打开风机变量")); returnToFront(jResult); return null; } // 20190515增加的逻辑,在置1打开位一秒钟后,将该位复位 Thread.sleep(1 * 1000); setOnCmd = ExhaustFanCommandService.buildResetTurnOnCommand(sour, dest, zcbh); if (null != setOnCmd) { byte[] content = finspi.messageToBytes(setOnCmd); ACUClientUtil.getInstance().sendACUCommand(client, content); Logger.getLogger(this.getClass().getName()).info("[打开风机置1位复位]"); } // 5秒后查询一次风机的状态 new ScheduledThreadPoolExecutor(1).schedule(new ReadFjStatusTask(zcbh), 5, TimeUnit.SECONDS); // 返回成功给界面 jResult.put("success", true); jResult.put("code", "0"); 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 turnOffFj() 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(); 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 // 逻辑取消,由PLC设备自行控制 // 2 发送设置停止位的命令 SetFjOffBitCommand setOffCmd = ExhaustFanCommandService.buildTurnOffCommand(sour, dest, zcbh); if (null != setOffCmd) { setOffCmd.setMessageProducerHost(client.getHost()); RemoteDeviceControlService service = new RemoteDeviceControlService(); service.executeService(client, setOffCmd, zcbh); Logger.getLogger(this.getClass().getName()).info(setOffCmd); } else { jResult.put("success", false); jResult.put("code", "4"); jResult.put("reason", UnicodeConvertor.string2Unicode("未找到资产对应的关闭风机变量")); returnToFront(jResult); return null; } // 20190515增加的逻辑,在置1打开位一秒钟后,将该位复位 Thread.sleep(1 * 1000); setOffCmd = ExhaustFanCommandService.buildResetTurnOffCommand(sour, dest, zcbh); if (null != setOffCmd) { byte[] content = finspi.messageToBytes(setOffCmd); ACUClientUtil.getInstance().sendACUCommand(client, content); Logger.getLogger(this.getClass().getName()).info("[关闭风机置1位复位]"); } // 5秒后查询一次风机的状态 new ScheduledThreadPoolExecutor(1).schedule(new ReadFjStatusTask(zcbh), 5, TimeUnit.SECONDS); // 返回成功给界面 jResult.put("success", true); jResult.put("code", "0"); returnToFront(jResult); return null; } else { jResult.put("success", false); jResult.put("code", "3"); jResult.put("resaon", UnicodeConvertor.string2Unicode("PLC主机不在线")); returnToFront(jResult); return null; } } public String readFjStatusFromDB() throws Exception { // 返回结果 JSONObject jResult = new JSONObject(); PgDeviceDao deviceDao = new PgDeviceDaoImpl(); PgFjDao fjDao = new PgFjDaoImpl(); int deviceId = deviceDao.findDeviceIdByCode(zcbh); if (deviceId > 0) { PgFjStat fjStat = fjDao.findLatestStatByDevice(deviceId); if (null != fjStat) { jResult.put("fjStat", fjStat.toJson()); } } returnToFront(jResult); return null; } /** * 根据报警的资产编号联动打开风机 * @return * @throws Exception */ public String turnOnFjReactAlarm() throws Exception { PgDeviceDao deviceDao = new PgDeviceDaoImpl(); String acucode = zcbh.substring(0, zcbh.indexOf(".", 6)); String cabin = zcbh.substring(zcbh.lastIndexOf(".") + 1, zcbh.lastIndexOf(".") + 2); List<PgDevice> fjs = deviceDao.findDeviceByPositionAndType(acucode, "F", cabin); if (null != fjs && fjs.isEmpty() == false) { String baseURL = Configure.getProperty("sys", "PGDSC_API_URL"); // 打开舱内的一个风机即可 String fjzcbh = fjs.get(0).getAssetcode(); // 调用远程接口启动风机 HttpRequest.sendGet(baseURL + "remote/turnOnFj.action", "zcbh=" + fjzcbh); } 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()); } /** * 执行风机操作之后的查询风机状态单次任务 */ class ReadFjStatusTask implements Runnable { private String zcbh; public ReadFjStatusTask(String zcbh) { this.zcbh = zcbh; } @Override public void run() { // 调用远程接口查询风机状态 String baseURL = Configure.getProperty("sys", "PGDSC_API_URL"); HttpRequest.sendGet(baseURL + "remote/readFjStatus.action", "zcbh=" + zcbh); } } }