Newer
Older
pgdsc / src / com / szpg / plc / message / response / read / ReadWSValueCommandResponse.java
package com.szpg.plc.message.response.read;

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

import com.szpg.db.data.PgTemphum;
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.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.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 TAN YUE
 */
public class ReadWSValueCommandResponse 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> wdbjz;

	/**
	 * 湿度报警阈值
	 */
	private List<Float> sdbjz;

	/**
	 * 温湿度监测的资产列表,从配置文件中获取
	 */
	private String[] zcList;

	private boolean WD_ON_FJ;
	private long CLASS_YELLOW_ALARM_INTERVAL;
	
	public ReadWSValueCommandResponse() {
		wd = new ArrayList<Float>();
		sd = new ArrayList<Float>();
		wdbjz = new ArrayList<Float>();
		sdbjz = new ArrayList<Float>();

		WD_ON_FJ = Boolean.valueOf(Configure.getProperty("sys", "WD_ON_FJ", "false"));
		CLASS_YELLOW_ALARM_INTERVAL = Integer.parseInt(Configure.getProperty("sys", "CLASS_YELLOW_ALARM_INTERVAL", "60")) * 60 * 1000L;
	}

	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> getWdbjz() {
		return wdbjz;
	}

	public void setWdbjz(List<Float> wdbjz) {
		this.wdbjz = wdbjz;
	}

	public List<Float> getSdbjz() {
		return sdbjz;
	}

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

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

	@Override
	public void afterAction() {
		// 1将温湿度监测值数据存入数据库
		PgWsDao wsDao = new PgWsDaoImpl();
		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 wdValue = wd.get(i);
				float sdValue = sd.get(i);

				int deviceId = deviceDao.findDeviceIdByCode(zcbh);
				if (deviceId > 0) {
					// 1 取出报警规则
					PgAlarmRule rule = ruleDao.findRuleByDevice(deviceId);

					// 默认的报警阈值
					double wdHigh = 0.0;
					double sdHigh = 0.0;
					if (null != rule) {
						try {
							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();
						}
					}

					// 1 判断温湿度是否报警
					if (wdHigh > 0.0001 && wdValue > wdHigh) {
						// 2 温度需要报警,处理报警记录和监测值
						// 2.1 取出上一个温度报警记录
						PgAlarm lastTempAlarm = alarmDao.findLatestAlarmByDeviceAndType(deviceId, "温度");

						boolean insertAlarmFlag = true;
						if (null != lastTempAlarm) {
							// 2.2 计算与上一个报警记录的操作时间间隔
							long tempAlarmTimeInterval = this.getTime().getTimeInMillis() - lastTempAlarm.getLog_time().getTime();

							// 2.3 上一个温度报警值
							double lastTempAlarmValue = 0.0;
							try {
								lastTempAlarmValue = NumberFormat.parseDouble(lastTempAlarm.getAlarm_value(), "0.00");
							} catch (Exception ex) {
								logger.error(ex);
								ex.printStackTrace();
							}

							if (Math.abs(wdValue - lastTempAlarmValue) < 0.01 && tempAlarmTimeInterval < CLASS_YELLOW_ALARM_INTERVAL) {
								insertAlarmFlag = false;
							}
						}

						// 2.4 如果与前值不同 或者 时间在设定的阈值范围之外 则处理报警
						if (insertAlarmFlag == true) {
							// 2.5 插入监测数值
							wsDao.addWsdzRecord(wdValue, sdValue, TimeFormat.formatTimestamp(this.getTime().getTime()), deviceId);

							// 2.6 推送给市管廊公司平台
							String wdResp = DataPushInterface.addTempData(zcbh, NumberFormat.format(wdValue, "0.00"), TimeFormat.format(this.getTime().getTime(), "yyyyMMddHHmmss"));
							logger.info("同步温度值结果:" + wdResp);

							// 2.7 生成报警记录
							PgAlarm wdAlarm = new PgAlarm().getTempAlarmInstance();

							wdAlarm.setAlarm_date(this.getTime().getTime());
							wdAlarm.setAlarm_value(NumberFormat.format(wdValue, "0.00"));
							wdAlarm.setAlarmdevid(deviceId);
							wdAlarm.setLog_time(this.getTime().getTime());

							// 2.8 将上一条报警记录消警
							alarmDao.insertAlarmRecord(wdAlarm);
							deviceDao.updateDeviceStatus(deviceId, "温度超高");

							// 2.9 向市级平台推送报警日志
							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);

							// 2.10 联动打开风机
							// 自动打开当前舱段的排风机,手动关闭风机
							// 首先找到当前舱段的排风机资产编号
							if (WD_ON_FJ == true) {
								String baseURL = Configure.getProperty("sys", "PGDSC_API_URL");
								HttpRequest.sendGet(baseURL + "remote/turnOnFjReactAlarm.action", "zcbh=" + zcbh);
							}
						}
					} else if (sdHigh > 0.0001 && sdValue > sdHigh) {
						// 3 湿度需要报警,处理报警记录和监测值
						// 3.1 取出上一个报警记录
						PgAlarm lastHumAlarm = alarmDao.findLatestAlarmByDeviceAndType(deviceId, "湿度");

						boolean insertAlarmFlag = true;
						if (null != lastHumAlarm) {
							// 3.2 计算与上一个报警记录的操作时间间隔
							long humAlarmTimeInterval = this.getTime().getTimeInMillis() - lastHumAlarm.getLog_time().getTime();

							// 3.3 上一个湿度报警值
							double lastHumAlarmValue = 0.0;
							try {
								lastHumAlarmValue = NumberFormat.parseDouble(lastHumAlarm.getAlarm_value(), "0.00");
							} catch (Exception ex) {
								logger.error(ex);
								ex.printStackTrace();
							}

							if (Math.abs(sdValue - lastHumAlarmValue) < 0.01 && humAlarmTimeInterval < CLASS_YELLOW_ALARM_INTERVAL) {
								insertAlarmFlag = false;
							}
						}

						// 3.4 如果与前值不同 或者 时间在设定的阈值范围外 则处理报警
						if (insertAlarmFlag == true) {
							// 3.5 插入监测数值
							wsDao.addWsdzRecord(wdValue, sdValue, TimeFormat.formatTimestamp(this.getTime().getTime()), deviceId);

							// 3.6 推送给市管廊公司平台
							String sdResp = DataPushInterface.addHumData(zcbh, NumberFormat.format(sdValue, "0.00"), TimeFormat.format(this.getTime().getTime(), "yyyyMMddHHmmss"));
							logger.info("同步湿度值结果:" + sdResp);

							// 3.7 生成报警记录
							PgAlarm sdAlarm = new PgAlarm().getHumAlarmInstance();

							sdAlarm.setAlarm_date(this.getTime().getTime());
							sdAlarm.setAlarm_value(NumberFormat.format(sdValue, "0.00"));
							sdAlarm.setAlarmdevid(deviceId);
							sdAlarm.setLog_time(this.getTime().getTime());

							// 3.8 将上一条报警记录消警
							alarmDao.insertAlarmRecord(sdAlarm);
							deviceDao.updateDeviceStatus(deviceId, "湿度超高");

							// 3.9 向市级平台推送报警日志
							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);

							// 3.10 湿度不需要联动打开风机
						}
					} else {
						// 4 不需要报警,只处理监测值
						// 4.1 取出上一个监测值
						PgTemphum lastRec = wsDao.findLastRecordByDevice(deviceId);

						// 4.2 计算数值的时间间隔
						long valueTimeInterval = this.getTime().getTimeInMillis() - lastRec.getUptime().getTime();

						// 4.3 判断条件:是否与原值(温度与湿度)相同且相距在六小时以内
						if (Math.abs(wdValue - lastRec.getTemp()) > 0.01 ||
							Math.abs(sdValue - lastRec.getHum()) > 0.01 ||
							valueTimeInterval > CLASS_YELLOW_ALARM_INTERVAL) {
							// 4.4 将数据存入数据库
							wsDao.addWsdzRecord(wdValue, sdValue, TimeFormat.formatTimestamp(this.getTime().getTime()), deviceId);

							// 4.5 推送给市管廊公司平台
							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 {
					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 + ".WS.WORDCOUNT")) * 2) {
			logger.error("返回的数据长度与读取的不一致!");
			this.setValid(false);
			return;
		}
				
		// 获取目标ACU温湿度监测值内存区域的起始字地址
		int start = Integer.parseInt(Configure.getProperty("acubl", acucode + ".WS.START"));
		
		// 获取目标ACU温湿度相关的资产列表,即温湿度设备列表
		String zcListStr = Configure.getProperty("acubl", acucode + ".WS.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 valueTem = getValueFromData(zcbh, start, messageData, zcbh + ".TemValue");
			
			// 2解析湿度监测值
			float valueWet = getValueFromData(zcbh, start, messageData, zcbh + ".WetValue");
			
			// 3解析温度报警阈值
			float threshTem = getValueFromData(zcbh, start, messageData, zcbh + ".TemSet");
			
			// 4解析湿度报警阈值
			float threshWet = getValueFromData(zcbh, start, messageData, zcbh + ".WetSet");
			
			getWd().add(valueTem);
			getSd().add(valueWet);
			getWdbjz().add(threshTem);
			getSdbjz().add(threshWet);
			
			logger.info("[" + zcbh + "][温度值" + valueTem + "][湿度值" + valueWet + "][温度报警阈值" + threshTem + "][湿度报警阈值" + threshWet + "]");
		}
		
		logger.info("解析[读取温湿度值]响应指令结束");
	}
 
}