package com.szpg.plc.message.response.read;

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

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.szpg.db.dao.PgAlarmDao;
import com.szpg.db.dao.PgAlarmRuleDao;
import com.szpg.db.dao.PgDeviceDao;
import com.szpg.db.dao.PgO2Dao;
import com.szpg.db.dao.PgWsDao;
import com.szpg.db.dao.impl.PgAlarmDaoImpl;
import com.szpg.db.dao.impl.PgAlarmRuleDaoImpl;
import com.szpg.db.dao.impl.PgDeviceDaoImpl;
import com.szpg.db.dao.impl.PgO2DaoImpl;
import com.szpg.db.dao.impl.PgWsDaoImpl;
import com.szpg.db.data.PgAlarm;
import com.szpg.db.data.PgAlarmRule;
import com.szpg.db.data.PgDevice;
import com.szpg.plc.message.response.ReadMemoryCommandResponse;
import com.szpg.util.Configure;
import com.szpg.util.DataPushInterface;
import com.szpg.util.HttpRequest;
import com.szpg.util.NumberFormat;
import com.szpg.util.TimeFormat;

/**
 * 解析二期温湿度及氧气实时值响应
 * @author admin
 *
 */
public class ReadWSYQValueCommandResponse extends ReadMemoryCommandResponse {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 2964733118081941174L;

	private final Logger logger = Logger.getLogger(this.getClass().getName());
	
	private List<Float> wd; //温度监测值
	private List<Float> sd; //湿度监测值
	private List<Float> yq; //氧气监测值
	private String[] zcList; //温湿度监测的资产列表，从配置文件中获取
	
	public ReadWSYQValueCommandResponse() {
		wd = new ArrayList<Float>();
		sd = new ArrayList<Float>();
		yq = new ArrayList<Float>();
	}

	public List<Float> getWd() {
		return wd;
	}

	public void setWd(List<Float> wd) {
		this.wd = wd;
	}

	public List<Float> getSd() {
		return sd;
	}

	public void setSd(List<Float> sd) {
		this.sd = sd;
	}

	public List<Float> getYq() {
		return yq;
	}

	public void setYq(List<Float> yq) {
		this.yq = yq;
	}

	public String[] getZcList() {
		return zcList;
	}

	public void setZcList(String[] zcList) {
		this.zcList = zcList;
	}

	@Override
	public void afterAction() {
		// 1将温湿度监测值数据存入数据库
		PgWsDao wsDao = new PgWsDaoImpl();
		PgO2Dao yqDao = new PgO2DaoImpl();
		PgDeviceDao deviceDao = new PgDeviceDaoImpl();
		PgAlarmRuleDao ruleDao = new PgAlarmRuleDaoImpl();
		PgAlarmDao alarmDao = new PgAlarmDaoImpl();
		
		if (null != zcList && zcList.length > 0) {
			// 遍历温湿度设备列表，将温湿度浓度监测值存入数据库
			for (int i = 0; i < zcList.length; i++) {
				String zcbh = zcList[i];
				
				int deviceId = deviceDao.findDeviceIdByCode(zcbh);
				if (deviceId > 0) {
					// 温湿度监测仪的后续操作
					if (zcbh.indexOf("WS") >= 0) {
						if (wd.get(i) != null && sd.get(i) != null) {
							float wdValue = wd.get(i);
							float sdValue = sd.get(i);
							
							try {
								wsDao.addWsdzRecord(wdValue, sdValue, TimeFormat.formatTimestamp(this.getTime().getTime()), deviceId);
							} catch (Exception ex) {
								logger.error("添加温湿度监测记录异常");
							}
							
							// (一)如果有报警则立即推送
							// 判断是否超过报警阈值
							PgAlarmRule rule = ruleDao.findRuleByDevice(deviceId);
							if (null != rule) {
								double wdHigh = 0.0;
								double sdHigh = 0.0;
								try {
									if (null != rule) {
										String highStr = rule.getHighvalue();
										if (null != highStr && highStr.isEmpty() == false && highStr.indexOf(";") > 0) {
											wdHigh = NumberFormat.parseDouble(highStr.split(";")[0], "0.00");
											sdHigh = NumberFormat.parseDouble(highStr.split(";")[1], "0.00");
										}
									}
								} catch (Exception ex) {
									logger.error(ex);
									ex.printStackTrace();
								}
								
								// 温度超过高限阈值
								if (wdHigh > 0.0001 && wdValue > wdHigh) {
									PgAlarm wdAlarm = new PgAlarm();
									wdAlarm.setActive(1);
									wdAlarm.setAlarm_date(this.getTime().getTime());
									wdAlarm.setAlarm_value(NumberFormat.format(wdValue, "0.00"));
									wdAlarm.setAlarmdevid(deviceId);
									wdAlarm.setAlarmtypeid(PgAlarm.ALARM_TYPE_PGRUN);
									wdAlarm.setDescription("温度超过高限阈值");
									wdAlarm.setUserid(null);
									
									alarmDao.insertAlarmRecord(wdAlarm);
									deviceDao.updateDeviceStatus(deviceId, "温度超高");
									
									// 将报警日志推送至市级平台
									String date = TimeFormat.formatDate(getTime().getTime());
									int count = alarmDao.findAlarmCountByDate(date);
									String bjbh = "THXC." + date + "." + NumberFormat.format(count+1, "0000");
									String bjms = wdAlarm.getDescription() + "，温度值为" + wdValue;
									String bjsj = date.replace("-", "");
									String wdbjResp = DataPushInterface.addTempAlarmData(bjbh, zcbh, bjms, bjsj);
									logger.info("同步温度报警记录日志结果：" + wdbjResp);
									
									// 将报警值推送至市级平台
									String wdResp = DataPushInterface.addTempData(zcbh, NumberFormat.format(wdValue, "0.00"), TimeFormat.format(this.getTime().getTime(), "yyyyMMddHHmmss"));
									logger.info("同步温度值结果：" + wdResp);
									
									// 自动打开当前舱段的排风机，手动关闭风机
									// 首先找到当前舱段的排风机资产编号
									if (Boolean.valueOf(Configure.getProperty("sys", "WD_ON_FJ", "false")) == true) {
										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");
											for (PgDevice fj : fjs) {
												String fjzcbh = fj.getAssetcode();

												// 调用远程接口启动风机
												HttpRequest.sendGet(baseURL + "remote/turnOnFj.action", "zcbh=" + fjzcbh);
											}
										}
									}
								}
							
							
								// 湿度超过高限阈值
								if (sdHigh > 0.0001 && sdValue > sdHigh) {
									PgAlarm sdAlarm = new PgAlarm();
									sdAlarm.setActive(1);
									sdAlarm.setAlarm_date(this.getTime().getTime());
									sdAlarm.setAlarm_value(NumberFormat.format(sdValue, "0.00"));
									sdAlarm.setAlarmdevid(deviceId);
									sdAlarm.setAlarmtypeid(PgAlarm.ALARM_TYPE_PGRUN);
									sdAlarm.setDescription("湿度超过高限阈值");
									sdAlarm.setUserid(null);
									
									alarmDao.insertAlarmRecord(sdAlarm);
									deviceDao.updateDeviceStatus(deviceId, "湿度超高");
									
									// 将报警日志推送至市级平台
									String date = TimeFormat.formatDate(getTime().getTime());
									int count = alarmDao.findAlarmCountByDate(date);
									String bjbh = "THXC." + date + "." + NumberFormat.format(count+1, "0000");
									String bjms = sdAlarm.getDescription() + "，湿度值为" + sdValue;
									String bjsj = date.replace("-", "");
									String sdbjResp = DataPushInterface.addHumAlarmData(bjbh, zcbh, bjms, bjsj);
									logger.info("同步湿度报警记录日志结果：" + sdbjResp);
									
									// 将报警值推送至市级平台
									String sdResp = DataPushInterface.addHumData(zcbh, NumberFormat.format(sdValue, "0.00"), TimeFormat.format(this.getTime().getTime(), "yyyyMMddHHmmss"));
									logger.info("同步湿度值结果：" + sdResp);
									
									// 湿度不需要联动打开风机
								}
							}
							
							// (二)如果监测值有变化则推送
							// 判断温度值是否有变化
							double lastTemp = wsDao.findLastTempByDevice(deviceId);
							if (Math.abs(wdValue - lastTemp) > 0.01) {
								// 将监测值推送至市级平台
								String wdResp = DataPushInterface.addTempData(zcbh, NumberFormat.format(wdValue, "0.00"), TimeFormat.format(this.getTime().getTime(), "yyyyMMddHHmmss"));
								logger.info("同步温度值结果：" + wdResp);
							}
							
							// 判断湿度值是否有变化
							double lastHum = wsDao.findLastHumByDevice(deviceId);
							if (Math.abs(sdValue - lastHum) > 0.01) {
								// 将监测值推送至市级平台
								String sdResp = DataPushInterface.addHumData(zcbh, NumberFormat.format(sdValue, "0.00"), TimeFormat.format(this.getTime().getTime(), "yyyyMMddHHmmss"));
								logger.info("同步湿度值结果：" + sdResp);
							}
							
							// (三)如果监测值有变化则推送
							// 每天小时各推送一个数据
							int minute = Calendar.getInstance().get(Calendar.MINUTE);
							if (minute < 10) {
								// 将监测值推送至市级平台
								String wdResp = DataPushInterface.addTempData(zcbh, NumberFormat.format(wdValue, "0.00"), TimeFormat.format(this.getTime().getTime(), "yyyyMMddHHmmss"));
								logger.info("同步温度值结果：" + wdResp);
								
								String sdResp = DataPushInterface.addHumData(zcbh, NumberFormat.format(sdValue, "0.00"), TimeFormat.format(this.getTime().getTime(), "yyyyMMddHHmmss"));
								logger.info("同步湿度值结果：" + sdResp);
							}
						}
					} else if (zcbh.indexOf("YQ") >= 0) {
						if (null != yq.get(i)) {
							float yqValue = yq.get(i);
							
							try {
								yqDao.addPblzRecord(yqValue, TimeFormat.formatTimestamp(this.getTime().getTime()), deviceId);
							} catch (Exception ex) {
								logger.error("添加氧气监测记录异常");
							}
							
							// (一)如果有报警则立即推送
							// 判断是否超过报警阈值
							PgAlarmRule rule = ruleDao.findRuleByDevice(deviceId);
							if (null != rule) {
								double low = 0.0;
								try {
									low = NumberFormat.parseDouble(rule.getLowvalue(), "0.00");
								} catch (Exception ex) {
									logger.error(ex);
									ex.printStackTrace();
								}
								
								// 氧气浓度低于低限阈值
								if (low > 0.0001 && yqValue < low) {
									PgAlarm alarm = new PgAlarm();
									alarm.setActive(1);
									alarm.setAlarm_date(this.getTime().getTime());
									alarm.setAlarm_value(NumberFormat.format(yqValue, "0.00"));
									alarm.setAlarmdevid(deviceId);
									alarm.setAlarmtypeid(PgAlarm.ALARM_TYPE_PGRUN);
									alarm.setDescription("氧气浓度低于低限阈值");
									alarm.setUserid(null);
									
									alarmDao.insertAlarmRecord(alarm);
									deviceDao.updateDeviceStatus(deviceId, "氧气浓度过低");
									
									// 将报警日志推送至市级平台
									String date = TimeFormat.formatDate(getTime().getTime());
									int count = alarmDao.findAlarmCountByDate(date);
									String bjbh = "THXC." + date + "." + NumberFormat.format(count+1, "0000");
									String bjms = alarm.getDescription() + "，氧气浓度值为" + yqValue;
									String bjsj = date.replace("-", "");
									String jwbjResp = DataPushInterface.addO2AlarmData(bjbh, zcbh, bjms, bjsj);
									logger.info("同步氧气报警记录日志结果：" + jwbjResp);
									
									// 将报警值推送至市级平台
									String jwResp = DataPushInterface.addO2Data(zcbh, NumberFormat.format(yqValue, "0.00"), TimeFormat.format(this.getTime().getTime(), "yyyyMMddHHmmss"));
									logger.info("同步氧气浓度值结果：" + jwResp);
									
									// 自动打开当前舱段的排风机，手动关闭风机
									// 首先找到当前舱段的排风机资产编号
									if (Boolean.valueOf(Configure.getProperty("sys", "O2_ON_FJ", "false")) == true) {
										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");
											for (PgDevice fj : fjs) {
												String fjzcbh = fj.getAssetcode();

												// 调用远程接口启动风机
												HttpRequest.sendGet(baseURL + "remote/turnOnFj.action", "zcbh=" + fjzcbh);
											}
										}
									}
								}
							}
							
							// (二)如果监测值有变化则推送
							// 判断氧气浓度值是否有变化
							double lastValue = yqDao.findLastValueByDevice(deviceId);
							if (Math.abs(yqValue - lastValue) > 0.01) {
								// 将监测值推送至市级平台
								String o2Resp = DataPushInterface.addO2Data(zcbh, NumberFormat.format(yqValue, "0.00"), TimeFormat.format(this.getTime().getTime(), "yyyyMMddHHmmss"));
								logger.info("同步氧气浓度值结果：" + o2Resp);
							}
							
							// (三)如果监测值有变化则推送
							// 每天小时各推送一个数据
							int minute = Calendar.getInstance().get(Calendar.MINUTE);
							if (minute < 10) {
								// 将监测值推送至市级平台
								String o2Resp = DataPushInterface.addO2Data(zcbh, NumberFormat.format(yqValue, "0.00"), TimeFormat.format(this.getTime().getTime(), "yyyyMMddHHmmss"));
								logger.info("同步氧气浓度值结果：" + o2Resp);
							}
						}
					}
				} else {
					logger.warn("未找到资产[" + zcbh + "]");
				}
			}
		}
	}

	@Override
	public void parseData() {
		// 获取目标ACU的代码
		String acucode = this.getAcucode();
		byte[] messageData = this.getResponseData();
		
		logger.info("开始解析[读取温湿度及氧气值][" + acucode + "]指令响应");
		
		// 判断数据的长度是否满足要求
		if (messageData.length != Integer.parseInt(Configure.getProperty("acubl", acucode + ".WSYQ.WORDCOUNT")) * 2) {
			logger.error("返回的数据长度与读取的不一致！");
			this.setValid(false);
			return;
		}
				
		// 获取目标ACU温湿度监测值内存区域的起始字地址
		int start = Integer.parseInt(Configure.getProperty("acubl", acucode + ".WSYQ.START"));
		
		// 获取目标ACU温湿度相关的资产列表，即温湿度设备列表
		String zcListStr = Configure.getProperty("acubl", acucode + ".WSYQ.ZC.LIST");
		if (StringUtils.isEmpty(zcListStr) == true) {
			this.setValid(false);
			return;
		}
		zcList = zcListStr.split(";");
		
		// 解析温湿度监测值以及温湿度报警阈值
		for (int i = 0; i < zcList.length; i++) {
			String zcbh = zcList[i];
			
			if (zcbh.indexOf("WS") >= 0) {
				// 1解析温度监测值
				float valueTem = getValueFromDataSecond(zcbh, start, messageData, zcbh + ".TemValue");
				
				// 2解析湿度监测值
				float valueWet = getValueFromDataSecond(zcbh, start, messageData, zcbh + ".WetValue");
				
				getWd().add(valueTem);
				getSd().add(valueWet);
				getYq().add(null); // 温湿度监测仪没有氧气值
				logger.info("[" + zcbh + "][温度值" + valueTem + "][湿度值" + valueWet + "]");
			} else if (zcbh.indexOf("YQ") >= 0) {
				// 3解析氧气监测值
				float valueYq = getValueFromDataSecond(zcbh, start, messageData, zcbh + ".Value");
				
				getYq().add(valueYq);
				getWd().add(null); // 氧气监测仪没有温湿度值
				getSd().add(null); // 氧气监测仪没有温湿度值
				logger.info("[" + zcbh + "][氧气值" + valueYq + "]");
			}
		}
		
		logger.info("解析[读取温湿度及氧气值]响应指令结束");
	}
 
}
