package com.szpg.plc.protocol.fins;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import com.szpg.plc.message.AppMessage;
import com.szpg.plc.message.AppMessageConstants;
import com.szpg.plc.message.UnKnownMessage;
import com.szpg.plc.message.command.LinkCommand;
import com.szpg.plc.message.command.ReadMemoryCommand;
import com.szpg.plc.message.command.WriteMemoryCommand;
import com.szpg.plc.message.command.write.SetJgUnlockBitCommand;
import com.szpg.plc.message.response.LinkCommandResponse;
import com.szpg.plc.message.response.WriteMemoryCommandResponse;
import com.szpg.plc.message.response.read.*;
import com.szpg.plc.message.response.write.*;
import com.szpg.plc.protocol.DTProtocolInterface;
import com.szpg.plc.protocol.fins.frame.FINSByteFrame;
import com.szpg.plc.protocol.fins.frame.FINSByteFrameTool;
import com.szpg.plc.util.ByteUtil;
import com.szpg.plc.util.Bytes;

public class FINSDTProtocolImp implements DTProtocolInterface {
	
	/**
	 * 从重叠消息中提取规范消息
	 */
	@Override
	public List<byte[]> extractByteMessage(byte[] byteMessage) {
		List<byte[]> bytesList = new ArrayList<byte[]>();
		int count = 0;
		
		try {
			int i = 0;
			while (i < byteMessage.length) {
				if (byteMessage[i] == FINSByteFrame.HEADER[0] && 
					byteMessage[i + 1] == FINSByteFrame.HEADER[1] &&
					byteMessage[i + 2] == FINSByteFrame.HEADER[2] &&
					byteMessage[i + 3] == FINSByteFrame.HEADER[3]) {
					
					// 匹配上FINS帧头
					int length = ByteUtil.binToInt(new byte[]{byteMessage[i + 4], byteMessage[i + 5], byteMessage[i + 6], byteMessage[i + 7]});
					if (i + length + 8 <= byteMessage.length) {
						Bytes bytes = new Bytes();
						bytes.append(byteMessage[i]).append(byteMessage[i + 1]).append(byteMessage[i + 2]).append(byteMessage[i + 3]); //FINS帧头
						bytes.append(byteMessage[i + 4]).append(byteMessage[i + 5]).append(byteMessage[i + 6]).append(byteMessage[i + 7]); //FINS长度
						
						// FINS的数据区
						for (int j = 0; j < length; j++) {
							bytes.append(byteMessage[i + 8 + j]);
						}
						
						i = i + length + 8;
						bytesList.add(bytes.toBytes());
						count++;
					} else {
						i++;
					}
				} else {
					i++;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			bytesList.clear();
			bytesList.add(byteMessage);
			return bytesList;
		}
		
		if (count == 0) {
			bytesList.add(byteMessage);
		}
		
		return bytesList;
	}

	/**
	 * 将字节数组解析为收到的消息对象
	 * 
	 * @param byteMessage
	 * @return RecievedMessage
	 */
	public AppMessage bytesToMessage(byte[] byteMessage) {

		AppMessage received = null;

		FINSByteFrame finsFrame = new FINSByteFrame(byteMessage);
		if (!finsFrame.valid) {
			received = new UnKnownMessage(byteMessage);
			received.setTime(Calendar.getInstance());
			return received;
		}

		// 根据不同字节内容，解析为各类型应用消息
		String commandStr = FINSByteFrameTool.getCommandStr(byteMessage);
		
		// 握手消息的响应
		if (commandStr.equalsIgnoreCase("00000001")) {
			received = bytesToLinkCommandResponse(finsFrame);
		} else if (commandStr.equalsIgnoreCase("00000002")) {
			// 读写命令的响应
			String commandCode = FINSByteFrameTool.getFinsCommandCode(byteMessage);
			String commandType = FINSByteFrameTool.getControlSID(byteMessage); //用SID字节来代表命令类型，与APPMessageConstants中的命令类型值保持一致
			
			if (commandCode.equalsIgnoreCase("0101")) {
				// 读内存命令响应的解析
				// 3根据参数类型调用相应的方法进行解析
				switch(commandType) {
					case AppMessageConstants.CMD_TYPE_READCH4VALUE:
						received = bytesToReadCH4ValueCommandResponse(finsFrame);
						break;
					case AppMessageConstants.CMD_TYPE_READCH4STATUS:
						received = bytesToReadCH4StatusCommandResponse(finsFrame);
						break;
							
					case AppMessageConstants.CMD_TYPE_READWSVALUE:
						received = bytesToReadWSValueCommandResponse(finsFrame);
						break;
					case AppMessageConstants.CMD_TYPE_READWSSTATUS:
						received = bytesToReadWSStatusCommandResponse(finsFrame);
						break;
							
					case AppMessageConstants.CMD_TYPE_READCOVALUE:
						received = bytesToReadCOValueCommandResponse(finsFrame);
						break;
					case AppMessageConstants.CMD_TYPE_READCOSTATUS:
						received = bytesToReadCOStatusCommandResponse(finsFrame);
						break;
							
					case AppMessageConstants.CMD_TYPE_READO2VALUE:
						received = bytesToReadO2ValueCommandResponse(finsFrame);
						break;
					case AppMessageConstants.CMD_TYPE_READO2STATUS:
						received = bytesToReadO2StatusCommandResponse(finsFrame);
						break;
							
					case AppMessageConstants.CMD_TYPE_READHSVALUE:
						received = bytesToReadHSValueCommandResponse(finsFrame);
						break;
					case AppMessageConstants.CMD_TYPE_READHSSTATUS:
						received = bytesToReadHSStatusCommandResponse(finsFrame);
						break;
							
					case AppMessageConstants.CMD_TYPE_READYWSTATUS:
						received = bytesToReadYWStatusCommandResponse(finsFrame);
						break;
							
					case AppMessageConstants.CMD_TYPE_READDSSTATUS:
						received = bytesToReadDSStatusCommandResponse(finsFrame);
						break;
							
					case AppMessageConstants.CMD_TYPE_READFJSTAT:
						received = bytesToReadFjStatCommandResponse(finsFrame);
						break;
					case AppMessageConstants.CMD_TYPE_READFJRUNTIME:
						received = bytesToReadFjRtCommandResponse(finsFrame);
						break;
							
					case AppMessageConstants.CMD_TYPE_READSBSTAT:
						received = bytesToReadSbStatCommandResponse(finsFrame);
						break;
					case AppMessageConstants.CMD_TYPE_READSBRUNTIME:
						received = bytesToReadSbRtCommandResponse(finsFrame);
						break;
							
					case AppMessageConstants.CMD_TYPE_READZMSTAT:
						received = bytesToReadZmStatCommandResponse(finsFrame);
						break;
					case AppMessageConstants.CMD_TYPE_READZMRUNTIME:
						received = bytesToReadZmRtCommandResponse(finsFrame);
						break;
							
					case AppMessageConstants.CMD_TYPE_READJGSTATUS:
						received = bytesToReadJgStatusCommandResponse(finsFrame);
						break;
							
					case AppMessageConstants.CMD_TYPE_READWSYQVALUE:
						received = bytesToReadWSYQValueCommandResponse(finsFrame);
						break;

					case AppMessageConstants.CMD_TYPE_READHSCH4VALUE:
						received = bytesToReadHSCH4ValueCommandResponse(finsFrame);
						break;
				}
			} else if (commandCode.equalsIgnoreCase("0102")) {
				switch (commandType) {
					case AppMessageConstants.CMD_TYPE_SETJGON:
						received = bytesToOpenJGCommandResponse(finsFrame);
						break;
					case AppMessageConstants.CMD_TYPE_SETJGOFF:
						received = bytesToCloseJGCommandResponse(finsFrame);
						break;
					case AppMessageConstants.CMD_TYPE_SETJGUNLOCK:
						received = bytesToUnlockJGCommandResponse(finsFrame);
						break;
					case AppMessageConstants.CMD_TYPE_SETJGLOCK:
						received = bytesToLockJGCommandResponse(finsFrame);
						break;

					case AppMessageConstants.CMD_TYPE_SETZMON:
						received = bytesToTurnOnZmCommandResponse(finsFrame);
						break;
					case AppMessageConstants.CMD_TYPE_SETZMOFF:
						received = bytesToTurnOffZmCommandResponse(finsFrame);
						break;

					default:
						received = bytesToDefaultWriteMemoryCommandResponse(finsFrame);
						((WriteMemoryCommandResponse) received).setCommandType(commandType);
						break;
				}


			}
		} else {
			received = new UnKnownMessage(byteMessage);
			received.setTime(Calendar.getInstance());
		}

		return received;
	}

	

	/**
	 * 将握手响应字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToLinkCommandResponse(FINSByteFrame finsFrame) {
		LinkCommandResponse lcr = new LinkCommandResponse();

		byte[] data = finsFrame.TEXT_DATA_BODY;
		lcr.setResponseData(data);
		
		return lcr;
	}

	/**
	 * 将查询甲烷参数响应消息字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadCH4ValueCommandResponse(FINSByteFrame finsFrame) {
		ReadCH4ValueCommandResponse rcvcr = new ReadCH4ValueCommandResponse();
		rcvcr.setCommandType(AppMessageConstants.CMD_TYPE_READCH4VALUE);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rcvcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rcvcr.setResponseData(data);
		} else {
			rcvcr.setValid(false);
		}

		return rcvcr;
	}
	
	
	/**
	 * 将查询甲烷报警状态响应消息字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadCH4StatusCommandResponse(FINSByteFrame finsFrame) {
		ReadCH4StatusCommandResponse rcscr = new ReadCH4StatusCommandResponse();
		rcscr.setCommandType(AppMessageConstants.CMD_TYPE_READCH4STATUS);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rcscr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rcscr.setResponseData(data);
		} else {
			rcscr.setValid(false);
		}
	
		return rcscr;
	}

	/**
	 * 将读取温湿度监测值响应字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadWSValueCommandResponse(FINSByteFrame finsFrame) {
		ReadWSValueCommandResponse rwvcr = new ReadWSValueCommandResponse();
		rwvcr.setCommandType(AppMessageConstants.CMD_TYPE_READWSVALUE);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rwvcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rwvcr.setResponseData(data);
		}

		return rwvcr;
	}
	
	
	private AppMessage bytesToReadWSStatusCommandResponse(FINSByteFrame finsFrame) {
		ReadWSStatusCommandResponse rwsscr = new ReadWSStatusCommandResponse();
		rwsscr.setCommandType(AppMessageConstants.CMD_TYPE_READWSSTATUS);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rwsscr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rwsscr.setResponseData(data);
		}
	
		return rwsscr;
	}
	
	
	/**
	 * 将查询一氧化碳参数响应消息字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadCOValueCommandResponse(FINSByteFrame finsFrame) {
		ReadCOValueCommandResponse rcvcr = new ReadCOValueCommandResponse();
		rcvcr.setCommandType(AppMessageConstants.CMD_TYPE_READCOVALUE);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rcvcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rcvcr.setResponseData(data);
		}

		return rcvcr;
	}
	
	
	/**
	 * 将查询一氧化碳报警状态响应消息字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadCOStatusCommandResponse(FINSByteFrame finsFrame) {
		ReadCOStatusCommandResponse rcscr = new ReadCOStatusCommandResponse();
		rcscr.setCommandType(AppMessageConstants.CMD_TYPE_READCOSTATUS);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rcscr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rcscr.setResponseData(data);
		}
		
		return rcscr;
	}
	
	
	/**
	 * 将查询氧气参数响应消息字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadO2ValueCommandResponse(FINSByteFrame finsFrame) {
		ReadO2ValueCommandResponse rovcr = new ReadO2ValueCommandResponse();
		rovcr.setCommandType(AppMessageConstants.CMD_TYPE_READO2VALUE);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rovcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rovcr.setResponseData(data);
		}

		return rovcr;
	}
	
	
	/**
	 * 将查询氧气报警状态响应消息字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadO2StatusCommandResponse(FINSByteFrame finsFrame) {
		ReadO2StatusCommandResponse roscr = new ReadO2StatusCommandResponse();
		roscr.setCommandType(AppMessageConstants.CMD_TYPE_READO2STATUS);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		roscr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			roscr.setResponseData(data);
		}
	
		return roscr;
	}

	
	/**
	 * 将查询硫化氢参数响应消息字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadHSValueCommandResponse(FINSByteFrame finsFrame) {
		ReadHSValueCommandResponse rhvcr = new ReadHSValueCommandResponse();
		rhvcr.setCommandType(AppMessageConstants.CMD_TYPE_READHSVALUE);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rhvcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rhvcr.setResponseData(data);
		}

		return rhvcr;
	}
	
	
	/**
	 * 将查询硫化氢报警状态响应消息字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadHSStatusCommandResponse(FINSByteFrame finsFrame) {
		ReadHSStatusCommandResponse rhscr = new ReadHSStatusCommandResponse();
		rhscr.setCommandType(AppMessageConstants.CMD_TYPE_READHSSTATUS);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rhscr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rhscr.setResponseData(data);
		}
	
		return rhscr;
	}
	
	/**
	 * 将查询爆管液位报警状态响应消息字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadYWStatusCommandResponse(FINSByteFrame finsFrame) {
		ReadYWStatusCommandResponse ryscr = new ReadYWStatusCommandResponse();
		ryscr.setCommandType(AppMessageConstants.CMD_TYPE_READYWSTATUS);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		ryscr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			ryscr.setResponseData(data);
		}
	
		return ryscr;
	}
	
	/**
	 * 将查询对射报警状态响应消息字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadDSStatusCommandResponse(FINSByteFrame finsFrame) {
		ReadDSStatusCommandResponse rdscr = new ReadDSStatusCommandResponse();
		rdscr.setCommandType(AppMessageConstants.CMD_TYPE_READDSSTATUS);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rdscr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rdscr.setResponseData(data);
		}
	
		return rdscr;
	}
	
	
	/**
	 * 将查询风机运行状态响应消息字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadFjStatCommandResponse(FINSByteFrame finsFrame) {
		ReadFjStatCommandResponse rfscr = new ReadFjStatCommandResponse();
		rfscr.setCommandType(AppMessageConstants.CMD_TYPE_READFJSTAT);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rfscr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rfscr.setResponseData(data);
		}
	
		return rfscr;
	}
	
	
	/**
	 * 将读取风机运行时长响应字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadFjRtCommandResponse(FINSByteFrame finsFrame) {
		ReadFjRtCommandResponse rfrcr = new ReadFjRtCommandResponse();
		rfrcr.setCommandType(AppMessageConstants.CMD_TYPE_READFJRUNTIME);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rfrcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rfrcr.setResponseData(data);
		}

		return rfrcr;
	}
	
	
	/**
	 * 将查询水泵运行状态响应消息字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadSbStatCommandResponse(FINSByteFrame finsFrame) {
		ReadSbStatCommandResponse rsscr = new ReadSbStatCommandResponse();
		rsscr.setCommandType(AppMessageConstants.CMD_TYPE_READSBSTAT);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rsscr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rsscr.setResponseData(data);
		}
	
		return rsscr;
	}
	
	
	/**
	 * 将读取水泵运行时长响应字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadSbRtCommandResponse(FINSByteFrame finsFrame) {
		ReadSbRtCommandResponse rsrcr = new ReadSbRtCommandResponse();
		rsrcr.setCommandType(AppMessageConstants.CMD_TYPE_READSBRUNTIME);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rsrcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rsrcr.setResponseData(data);
		}

		return rsrcr;
	}
	
	
	/**
	 * 将查询照明运行状态响应消息字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadZmStatCommandResponse(FINSByteFrame finsFrame) {
		ReadZmStatCommandResponse rsscr = new ReadZmStatCommandResponse();
		rsscr.setCommandType(AppMessageConstants.CMD_TYPE_READZMSTAT);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rsscr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rsscr.setResponseData(data);
		}
	
		return rsscr;
	}
	
	
	/**
	 * 将读取照明运行时长响应字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadZmRtCommandResponse(FINSByteFrame finsFrame) {
		ReadZmRtCommandResponse rsrcr = new ReadZmRtCommandResponse();
		rsrcr.setCommandType(AppMessageConstants.CMD_TYPE_READZMRUNTIME);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rsrcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rsrcr.setResponseData(data);
		}

		return rsrcr;
	}
	
	
	/**
	 * 将查询井盖状态响应消息字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadJgStatusCommandResponse(FINSByteFrame finsFrame) {
		ReadJgStatusCommandResponse rjscr = new ReadJgStatusCommandResponse();
		rjscr.setCommandType(AppMessageConstants.CMD_TYPE_READJGSTATUS);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rjscr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rjscr.setResponseData(data);
		}
	
		return rjscr;
	}
	
	
	/**
	 * 将读取温湿度及氧气监测值响应字节数组转换为消息对象
	 * 
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadWSYQValueCommandResponse(FINSByteFrame finsFrame) {
		ReadWSYQValueCommandResponse rwvcr = new ReadWSYQValueCommandResponse();
		rwvcr.setCommandType(AppMessageConstants.CMD_TYPE_READWSYQVALUE);
		
		byte[] body = finsFrame.TEXT_DATA_BODY;
		rwvcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rwvcr.setResponseData(data);
		}

		return rwvcr;
	}

	/**
	 * 将读取硫化氢及甲烷监测值响应字节数组转换为消息对象
	 *
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToReadHSCH4ValueCommandResponse(FINSByteFrame finsFrame) {
		ReadHSCH4ValueCommandResponse rwvcr = new ReadHSCH4ValueCommandResponse();
		rwvcr.setCommandType(AppMessageConstants.CMD_TYPE_READHSCH4VALUE);

		byte[] body = finsFrame.TEXT_DATA_BODY;
		rwvcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));
		if (body[2] == 0x00 && body[3] == 0x00) {
			// 正常返回
			byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存
			rwvcr.setResponseData(data);
		}

		return rwvcr;
	}

	/**
	 * 将默认写内存指令响应字节数组转换为消息对象
	 *
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToDefaultWriteMemoryCommandResponse(FINSByteFrame finsFrame) {
		WriteMemoryCommandResponse wmcr = new WriteMemoryCommandResponse();

		// 写内存命令响应
		byte[] body = finsFrame.TEXT_DATA_BODY;
		wmcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));

		if (body.length == 4) {
			if (body[2] == 0x00 && body[3] == 0x00) {
				// 写入成功
				wmcr.setSuccess(true);
			} else {
				wmcr.setSuccess(false);
			}
			wmcr.setValid(true);
		} else {
			wmcr.setValid(false);
		}

		return wmcr;
	}

	/**
	 * 将打开井盖指令响应字节数组转换为消息对象
	 *
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToOpenJGCommandResponse(FINSByteFrame finsFrame) {
		SetJgOnBitCommandResponse sjcr = new SetJgOnBitCommandResponse();
		sjcr.setCommandType(AppMessageConstants.CMD_TYPE_SETJGON);

		// 写内存命令响应
		byte[] body = finsFrame.TEXT_DATA_BODY;
		sjcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));

		if (body.length == 4) {
			if (body[2] == 0x00 && body[3] == 0x00) {
				// 写入成功
				sjcr.setSuccess(true);
			} else {
				sjcr.setSuccess(false);
			}
			sjcr.setValid(true);
		} else {
			sjcr.setValid(false);
		}

		return sjcr;
	}


	/**
	 * 将关闭井盖指令响应字节数组转换为消息对象
	 *
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToCloseJGCommandResponse(FINSByteFrame finsFrame) {
		SetJgOffBitCommandResponse sjcr = new SetJgOffBitCommandResponse();
		sjcr.setCommandType(AppMessageConstants.CMD_TYPE_SETJGOFF);

		// 写内存命令响应
		byte[] body = finsFrame.TEXT_DATA_BODY;
		sjcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));

		if (body.length == 4) {
			if (body[2] == 0x00 && body[3] == 0x00) {
				// 写入成功
				sjcr.setSuccess(true);
			} else {
				sjcr.setSuccess(false);
			}
			sjcr.setValid(true);
		} else {
			sjcr.setValid(false);
		}

		return sjcr;
	}

	/**
	 * 将解锁井盖指令响应字节数组转换为消息对象
	 *
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToUnlockJGCommandResponse(FINSByteFrame finsFrame) {
		SetJgUnlockBitCommandResponse sjcr = new SetJgUnlockBitCommandResponse();
		sjcr.setCommandType(AppMessageConstants.CMD_TYPE_SETJGUNLOCK);

		// 写内存命令响应
		byte[] body = finsFrame.TEXT_DATA_BODY;
		sjcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));

		if (body.length == 4) {
			if (body[2] == 0x00 && body[3] == 0x00) {
				// 写入成功
				sjcr.setSuccess(true);
			} else {
				sjcr.setSuccess(false);
			}
			sjcr.setValid(true);
		} else {
			sjcr.setValid(false);
		}

		return sjcr;
	}


	/**
	 * 将锁定井盖指令响应字节数组转换为消息对象
	 *
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToLockJGCommandResponse(FINSByteFrame finsFrame) {
		SetJgLockBitCommandResponse sjcr = new SetJgLockBitCommandResponse();
		sjcr.setCommandType(AppMessageConstants.CMD_TYPE_SETJGLOCK);

		// 写内存命令响应
		byte[] body = finsFrame.TEXT_DATA_BODY;
		sjcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));

		if (body.length == 4) {
			if (body[2] == 0x00 && body[3] == 0x00) {
				// 写入成功
				sjcr.setSuccess(true);
			} else {
				sjcr.setSuccess(false);
			}
			sjcr.setValid(true);
		} else {
			sjcr.setValid(false);
		}

		return sjcr;
	}

	/**
	 * 将打开照明指令响应字节数组转换为消息对象
	 *
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToTurnOnZmCommandResponse(FINSByteFrame finsFrame) {
		SetZmOnBitCommandResponse sjcr = new SetZmOnBitCommandResponse();
		sjcr.setCommandType(AppMessageConstants.CMD_TYPE_SETZMON);

		// 写内存命令响应
		byte[] body = finsFrame.TEXT_DATA_BODY;
		sjcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));

		if (body.length == 4) {
			if (body[2] == 0x00 && body[3] == 0x00) {
				// 写入成功
				sjcr.setSuccess(true);
			} else {
				sjcr.setSuccess(false);
			}
			sjcr.setValid(true);
		} else {
			sjcr.setValid(false);
		}

		return sjcr;
	}


	/**
	 * 将关闭照明指令响应字节数组转换为消息对象
	 *
	 * @param finsFrame
	 * @return
	 */
	private AppMessage bytesToTurnOffZmCommandResponse(FINSByteFrame finsFrame) {
		SetZmOffBitCommandResponse sjcr = new SetZmOffBitCommandResponse();
		sjcr.setCommandType(AppMessageConstants.CMD_TYPE_SETZMOFF);

		// 写内存命令响应
		byte[] body = finsFrame.TEXT_DATA_BODY;
		sjcr.setMessageProducerId(FINSByteFrameTool.getControlDest(finsFrame));

		if (body.length == 4) {
			if (body[2] == 0x00 && body[3] == 0x00) {
				// 写入成功
				sjcr.setSuccess(true);
			} else {
				sjcr.setSuccess(false);
			}
			sjcr.setValid(true);
		} else {
			sjcr.setValid(false);
		}

		return sjcr;
	}
	

	/**
	 * 将消息对象解析为字节数组
	 * 
	 * @param message
	 * @return byte[]
	 */
	public byte[] messageToBytes(AppMessage message) {
		byte[] frame = null;

		// 握手命令
		if (message instanceof LinkCommand) {
			frame = LinkCommandToBytes((LinkCommand) message);
		}
		
		// 读内存命令
		if (message instanceof ReadMemoryCommand) {
			frame = readMemoryCommandToBytes((ReadMemoryCommand) message);
		}
		
		// 写内存命令
		if (message instanceof WriteMemoryCommand) {
			frame = writeMemoryCommandToBytes((WriteMemoryCommand) message);
		}
		
		return frame;
	}



	/**
	 * 将握手命令转换为字节数组
	 * 
	 * @param link
	 * @return byte[]
	 */
	private byte[] LinkCommandToBytes(LinkCommand link) {
		FINSByteFrame finsFrame = new FINSByteFrame(link.getMessageProducerId());

		return finsFrame.toBytes();
	}
	
	/**
	 * 将读取PLC内存命令转换为字节数组
	 * 
	 * @param message
	 * @return
	 */
	private byte[] readMemoryCommandToBytes(ReadMemoryCommand message) {
		byte[] start = ByteUtil.hexStringToBytes(message.getStartAddress(), 3);
		
		FINSByteFrame finsFrame = new FINSByteFrame(message.getDestinationId(), 
													message.getMessageProducerId(), 
													message.getCommandType(),
													message.getMemoryArea(), 
													start, 
													message.getCountWord());
		
		return finsFrame.toBytes();
	}
	
	/**
	 * 将写PLC内存命令转换为字节数组
	 * @param message
	 * @return
	 */
	private byte[] writeMemoryCommandToBytes(WriteMemoryCommand message) {
		if (message.getMemoryArea() == FINSConstants.MEMORY_WORK_AREA_BIT) {
			// 按位操作
			byte[] start = ByteUtil.hexStringToBytes(message.getStartAddress(), 2);
			
			FINSByteFrame finsFrame = new FINSByteFrame(message.getDestinationId(), 
														message.getMessageProducerId(), 
														message.getCommandType(), 
														message.getMemoryArea(), 
														start, 
														message.getBit(),
														message.getCount(), 
														message.getValue());
			
			return finsFrame.toBytes();
		} else if (message.getMemoryArea() == FINSConstants.MEMORY_WORK_AREA_WORD) {
			// 按字操作
			byte[] start = ByteUtil.hexStringToBytes(message.getStartAddress(), 3);
			
			FINSByteFrame finsFrame = new FINSByteFrame(message.getDestinationId(), 
														message.getMessageProducerId(), 
														message.getCommandType(), 
														message.getMemoryArea(), 
														start, 
														message.getCount(), 
														message.getValue());
			
			return finsFrame.toBytes();
		} else if (message.getMemoryArea() == FINSConstants.MEMORY_DM_AREA) {
			// 写D区，按字操作
			byte[] start = ByteUtil.hexStringToBytes(message.getStartAddress(), 3);
			
			FINSByteFrame finsFrame = new FINSByteFrame(message.getDestinationId(), 
														message.getMessageProducerId(), 
														message.getCommandType(), 
														message.getMemoryArea(), 
														start, 
														message.getCount(), 
														message.getValue());

			return finsFrame.toBytes();
		} else {
			return null;
		}
	}
}
