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.PgHSDao;
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.PgHSDaoImpl;
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;

public class ReadHSValueCommandResponse extends ReadMemoryCommandResponse {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -3864512113984510244L;

	private final Logger logger = Logger.getLogger(this.getClass().getName());
	
	private List<Float> hsnd; //硫化氢浓度值
	private List<Float> hsldbjz; //硫化氢联动报警值
	private String[] zcList; // 监测设备资产列表，从配置文件中获取
	
	public ReadHSValueCommandResponse() {
		hsnd = new ArrayList<Float>();
		hsldbjz = new ArrayList<Float>();
	}

	public List<Float> getHsnd() {
		return hsnd;
	}

	public void setHsnd(List<Float> hsnd) {
		this.hsnd = hsnd;
	}

	public List<Float> getHsldbjz() {
		return hsldbjz;
	}

	public void setHsldbjz(List<Float> hsldbjz) {
		this.hsldbjz = hsldbjz;
	}
	
	public String[] getZcList() {
		return zcList;
	}

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

	@Override
	public void afterAction() {
		// 1将硫化氢浓度数据存入数据库
		PgHSDao hsDao = new PgHSDaoImpl();
		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];
				
				float value = hsnd.get(i);
				
				int deviceId = deviceDao.findDeviceIdByCode(zcbh);
				if (deviceId > 0) {
					hsDao.addPblzRecord(hsnd.get(i), TimeFormat.formatTimestamp(this.getTime().getTime()), deviceId);
					
					// (一)如果有报警则立即推送
					// 判断是否超过报警阈值
					PgAlarmRule rule = ruleDao.findRuleByDevice(deviceId);
					if (null != rule) {
						double high = 0.0;
						try {
							high = NumberFormat.parseDouble(rule.getHighvalue(), "0.00");
						} catch (Exception ex) {
							logger.error(ex);
							ex.printStackTrace();
						}
						
						// 一氧化碳浓度超过高限阈值
						if (high > 0.0001 && value > high) {
							PgAlarm alarm = new PgAlarm();
							alarm.setActive(1);
							alarm.setAlarm_date(this.getTime().getTime());
							alarm.setAlarm_value(NumberFormat.format(value, "0.00"));
							alarm.setAlarmdevid(deviceId);
							alarm.setAlarmtypeid(PgAlarm.ALARM_TYPE_PGRUN);
							alarm.setDescription("硫化氢浓度超过高限阈值");
							alarm.setUserid(null);
							
							alarmDao.insertAlarmRecord(alarm);
							
							// 将报警日志推送至市级平台
							String date = TimeFormat.formatDate(getTime().getTime());
							int count = alarmDao.findAlarmCountByDate(date);
							String bjbh = "THXC." + date + "." + NumberFormat.format(count+1, "0000");
							String bjms = alarm.getDescription() + "，硫化氢浓度值为" + value;
							String bjsj = date.replace("-", "");
							String jwbjResp = DataPushInterface.addHSAlarmData(bjbh, zcbh, bjms, bjsj);
							logger.info("同步硫化氢报警记录日志结果：" + jwbjResp);
							
							// 将报警值推送至市级平台
							String jwResp = DataPushInterface.addHSData(zcbh, NumberFormat.format(value, "0.00"), TimeFormat.format(this.getTime().getTime(), "yyyyMMddHHmmss"));
							logger.info("同步硫化氢浓度值结果：" + jwResp);
							
							// 自动打开当前舱段的排风机，手动关闭风机
							// 首先找到当前舱段的排风机资产编号
							if (Boolean.valueOf(Configure.getProperty("sys", "HS_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 = hsDao.findLastValueByDevice(deviceId);
					if (Math.abs(value - lastValue) > 0.01) {
						// 将监测值推送至市级平台
						String coResp = DataPushInterface.addHSData(zcbh, NumberFormat.format(value, "0.00"), TimeFormat.format(this.getTime().getTime(), "yyyyMMddHHmmss"));
						logger.info("同步硫化氢浓度值结果：" + coResp);
					}
					
					// (三)如果监测值没有变化
					// 每天小时各推送一个数据
					int minute = Calendar.getInstance().get(Calendar.MINUTE);
					if (minute < 10) {
						// 将监测值推送至市级平台
						String coResp = DataPushInterface.addHSData(zcbh, NumberFormat.format(value, "0.00"), TimeFormat.format(this.getTime().getTime(), "yyyyMMddHHmmss"));
						logger.info("同步硫化氢浓度值结果：" + coResp);
					}
				} 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 + ".HS.WORDCOUNT")) * 2) {
			logger.error("返回的数据长度与读取的不一致！");
			this.setValid(false);
			return;
		}
		
		// 获取目标ACU硫化氢监测值内存区域的起始字地址
		int start = Integer.parseInt(Configure.getProperty("acubl", acucode + ".HS.START"));
		
		// 获取目标ACU硫化氢相关的资产列表，即硫化氢设备列表
		String zcListStr = Configure.getProperty("acubl", acucode + ".HS.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];
			
			// 1解析硫化氢浓度监测值
			float value = getValueFromData(zcbh, start, messageData, zcbh + ".Value");
			
			// 2解析硫化氢浓度报警阈值
			float threshold = getValueFromData(zcbh, start, messageData, zcbh + ".Set");
	
			getHsnd().add(value);
			getHsldbjz().add(threshold);
			
			logger.info("[" + zcbh + "][硫化氢浓度值" + value + "][硫化氢浓度报警阈值" + threshold + "]");
		}
		
		logger.info("解析[读取硫化氢浓度值]响应指令结束");
	}

}
