pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_83_Up.java
@@ -133,9 +133,11 @@ String ymd = "20" + yy + "-" + mm + "-" + dd ; cdData.rtuDt = ymd + " " + hh ; cdData.rtuDt = ymd + " " + hh + ":00:00" ; cdData.dataDt = DateTime.lastXDay_yyyy_MM_dd(ymd, 1) ; cdData.dataDt += " 23:59:59" ; } } pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/upVos/DataCd83Vo.java
@@ -18,7 +18,7 @@ public Double waterUserTotalAmountDay ;// 当日用户用水量 public Double lossTotalAmountDay ;// 漏损水量 public Double batteryVolt ;//后备电池电压 public String dataDt ;//数据时间(yyyy-mm-dd) public String dataDt ;//数据时间(yyyy-mm-dd HH:00:00) public String rtuDt ;//RTU时钟(上报时刻)(yyyy-mm-dd HH:00:00) public String comName ;//命令名称 pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoRm/RmLossDay.java
@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableName; import com.dy.common.mw.protocol.p206V1.DataV1; import com.dy.common.mw.protocol.p206V2.DataV2; import com.dy.common.mw.protocol.p206V202404.DataV202404; import com.dy.common.po.BaseEntity; import com.dy.common.util.DateTime; import com.fasterxml.jackson.annotation.JsonFormat; @@ -104,4 +105,11 @@ this.dtRtu = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt); this.lossAmount = cdData.lossAmount ;// 损失流量(从0时到当前的漏损累计流量,24时一个周期,0时归0)单位为m3。 } public void valueFrom(DataV202404 dV202404, com.dy.common.mw.protocol.p206V202404.upVos.DataCd83Vo cdData) throws Exception{ this.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.dataDt); this.dtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dV202404.dt); this.dtRtu = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.dataDt); this.lossAmount = cdData.lossTotalAmountDay ;// 损失流量(从0时到当前的漏损累计流量,24时一个周期,0时归0)单位为m3。 } } pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoRm/RmLossDayLast.java
@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableName; import com.dy.common.mw.protocol.p206V1.DataV1; import com.dy.common.mw.protocol.p206V2.DataV2; import com.dy.common.mw.protocol.p206V202404.DataV202404; import com.dy.common.po.BaseEntity; import com.dy.common.util.DateTime; import com.fasterxml.jackson.annotation.JsonFormat; @@ -108,5 +109,11 @@ this.dtRtu = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt); this.lossAmount = cdData.lossAmount ;// 损失流量(从0时到当前的漏损累计流量,24时一个周期,0时归0)单位为m3。 } public void valueFrom(DataV202404 dV202404, com.dy.common.mw.protocol.p206V202404.upVos.DataCd83Vo cdData) throws Exception{ this.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.dataDt); this.dtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dV202404.dt); this.dtRtu = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.dataDt); this.lossAmount = cdData.lossTotalAmountDay ;// 损失流量(从0时到当前的漏损累计流量,24时一个周期,0时归0)单位为m3。 } } pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1/TkDealIntakeAmountDay.java
@@ -42,7 +42,7 @@ * 原来实现本任务功能,数据从84,83,C0功能码数据中获得统计数据,但后来数据中增加了金额与开关阀次数, * 从而使得从三种数据中统计数据相当困难与自相矛盾,所以修改实现方式,只从83数据中统计本数据,并且从几 * 个月来运行数据看,只要设备能上线,基本上各种上报数据都能上报上来,所以没有必须从84及C0数据中统计数据了 * 至此,本实现方式主永久实现方式,不再修改回去了,实践证明,以前的实现方式数据是统计不准确的。 * 至此,本实现方式定为永久实现方式,不再修改回去了,实践证明,以前的实现方式数据是统计不准确的。 */ if (cdObj != null && ( pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V202404/TkDealClientAmountDayV202404.java
New file @@ -0,0 +1,344 @@ package com.dy.rtuMw.server.rtuData.p206V202404; import com.dy.common.mw.protocol.Data; import com.dy.common.mw.protocol.p206V202404.DataV202404; import com.dy.common.mw.protocol.p206V202404.upVos.DataCd85Vo; import com.dy.common.util.DateTime; import com.dy.pipIrrGlobal.pojoPr.PrController; import com.dy.pipIrrGlobal.pojoRm.RmClientAmountDay; import com.dy.pipIrrGlobal.pojoRm.RmClientAmountDayLast; import com.dy.pipIrrGlobal.pojoSe.SeClient; import com.dy.rtuMw.server.rtuData.TaskSurpport; import com.dy.rtuMw.server.rtuData.dbSv.DbSv; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.util.Date; /** * @Author: liurunyu * @Date: 2025/5/14 10:30 * @Description */ public class TkDealClientAmountDayV202404 extends TaskSurpport { private static final Logger log = LogManager.getLogger(TkDealClientAmountDayV202404.class.getName()); //类ID,一定与Tree.xml配置文件中配置一致 public static final String taskId = "TkDealClientAmountDayV202404"; /** * 执行节点任务: 取水口日用水量和漏损量 * * @param data 需要处理的数据 */ @Override public void execute(Object data) { Data d = (Data) data; DataV202404 dV202404 = (DataV202404) d.getSubData();//前面任务已经判断不为null Object cdObj = dV202404.subData; if (cdObj != null && cdObj instanceof DataCd85Vo) { /* 只能采用DataCd85Vo来计算农户日用水量的原因: 1、如果采用DataCd84Vo(开阀工作报)来计算农户日用水量,必须采用本次累计流量减上次累流量的差值作为阶段农户用水量, 然后各个阶段相加,得到本次农户用水量,这个用水量还没加到农户日用水量中,因为只有收不到DataCd85Vo(关阀报) 上报数据时才能加到农户用水量中,否则就会重复计算,但什么时候及能否收到DataCd85Vo不可预知。 2、如果农户有多张IC卡,同时在多个取水口取水,将会是更复杂的计算,许多情形更不可预测,且时间复杂度 必然很高,这样程序运行时间更长,将会造成上行数据堵塞现象。 3、所以只采用上报数据DataCd85Vo作为计算农户用水量的数据来源,这时必然会有漏报缺失情况发生,采用补报机制可以弥补一些。 */ /* 补报DataCd85Vo处理方法: 采用DataCd85Vo数据中的关阀时间closeDt计算出农户用水日期,不能用数据接收日期时间作为农户用水日期, 但这种计算方法可能会有重复上报情况发生,即重复计算了,如果要判断重复,必然要增加一个关阀时间数据库表,增加时间 复杂度,计算用时将会长,本系统假设只要RTU上报上来数据了,说明当前网络较好,必然能收到下行应答,不会发生重复补报。 */ Object[] objs = this.getTaskResults(TkPreGenObjsV202404.taskId); DbSv sv = (DbSv) objs[0]; PrController controller = (PrController) objs[1]; SeClient clientVo = (SeClient)objs[3] ;//这个值对象中只有id和name会有值 if(clientVo != null && clientVo.getId() != null) try { this.doDeal(sv, clientVo, controller, d.getRtuAddr(), dV202404, (DataCd85Vo) cdObj); } catch (Exception e) { log.error("保存取水口日用水量和漏损量数据时发生异常", e); } } } /** * 业务处理 * * @param sv 服务 * @param clientVo 农户对象 * @param controller 控制器对象 * @param rtuAddr 控制器地址 * @param dV202404 上报数据 * @param cdData 上报关阀数据对象 */ private void doDeal(DbSv sv, SeClient clientVo, PrController controller, String rtuAddr, DataV202404 dV202404, DataCd85Vo cdData) throws Exception { RmClientAmountDayLast poLast = sv.getRmClientAmountLast(clientVo.getId()); if (poLast == null) { //数据库中不存在该农户的日取水量数据 //首先生成最新数据及历史数据,并先保存 poLast = this.newRmClientAmountLast(clientVo, dV202404, cdData); this.newAndSaveHistoryDataDeal(sv, clientVo, dV202404, cdData, poLast); sv.saveRmClientAmountLast(poLast); } else { if(DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.endDt).equals(poLast.rtuDtLast)){ //RTU时钟等于本地最新数据中的RTU时钟,重复上报数据,不进行任何处理 }else if(DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.endDt).after(poLast.rtuDtLast)){ //RTU时钟晚于本地最新数据中的RTU时钟,是新上报数据 Date upYmd = DateTime.dateFrom_yyyy_MM_dd1(cdData.endDt);//采用关阀日期作为统计日期 if(upYmd.equals(poLast.dt)){ //同一天数据 poLast = this.updateRmClientAmountLastBySameDateNewData(clientVo, dV202404, cdData, poLast); RmClientAmountDay poHistory = null ; if(poLast.lastHistoryId != null){ poHistory = sv.getRmClientAmountDay(poLast.lastHistoryId) ; } if(poHistory == null){ this.newAndSaveHistoryDataDeal(sv, clientVo, dV202404, cdData, poLast); }else{ poHistory = this.updateRmClientAmountBySameDateNewData(clientVo, poHistory, poLast, dV202404, cdData); sv.updateRmClientAmountDay(poHistory); } }else if(upYmd.after(poLast.dt)){ //新的日期 poLast = this.updateRmClientAmountLastByNewDateNewData(clientVo, dV202404, cdData, poLast); this.newAndSaveHistoryDataDeal(sv, clientVo, dV202404, cdData, poLast); }else{ //这种情况不存在 } sv.updateRmClientAmountLast(poLast); }else{ //RTU时钟早于本地最新数据中的RTU时钟,是补报数据 Date upYmd = DateTime.dateFrom_yyyy_MM_dd1(cdData.endDt);//采用关阀日期作为统计日期 RmClientAmountDay poHistory = sv.getRmClientAmountByClientAndDate(clientVo.getId(), upYmd) ; if(poHistory == null){ //无历史数据 this.newAndSaveHistoryDataDeal(sv, clientVo, dV202404, cdData, null); }else{ poHistory = this.updateOldRmClientAmountBySupplyData(clientVo, poHistory, dV202404, cdData); sv.updateRmClientAmountDay(poHistory); } } } } /** * 生成新的控制器漏损日统计最新记录 * @param clientVo * @param dV202404 * @param cdData * @return * @throws Exception */ private RmClientAmountDayLast newRmClientAmountLast(SeClient clientVo, DataV202404 dV202404, DataCd85Vo cdData)throws Exception { RmClientAmountDayLast po = new RmClientAmountDayLast() ; po.clientId = clientVo.getId(); po.amount = cdData.thisWater ; po.money = cdData.thisMoney ; po.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.endDt);//采用关阀日期作为统计日期 po.openDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.startDt); po.closeDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.endDt); po.thisAmountLast = cdData.thisWater ; po.thisMoneyLast = cdData.thisMoney ; po.thisTimeLast = cdData.thisDuration ; po.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.endDt);//采用结束时间作为控制器时钟 return po ; } /** * 生成新的控制器漏损日统计历史记录 * @param clientVo * @param dV202404 * @param cdData * @param lastPo * @return * @throws Exception */ private RmClientAmountDay newRmClientAmountDay(SeClient clientVo, DataV202404 dV202404, DataCd85Vo cdData, RmClientAmountDayLast lastPo)throws Exception { RmClientAmountDay poHistory = new RmClientAmountDay() ; poHistory.clientId = clientVo.getId(); if(lastPo != null){ if(poHistory.amount != null){ poHistory.amount += lastPo.amount ; }else{ poHistory.amount = lastPo.amount ; } if(poHistory.money != null){ poHistory.money += lastPo.money ; }else{ poHistory.money = lastPo.money ; } poHistory.times = 1 ; poHistory.dt = lastPo.dt ; poHistory.openDtLast = lastPo.openDtLast ; poHistory.closeDtLast = lastPo.closeDtLast ; poHistory.thisAmountLast = lastPo.thisAmountLast ; poHistory.thisMoneyLast = lastPo.thisMoneyLast ; poHistory.thisTimeLast = lastPo.thisTimeLast ; poHistory.rtuDtLast = lastPo.rtuDtLast ; }else{ poHistory.amount = cdData.thisWater ; poHistory.money = cdData.thisMoney ; poHistory.times = 1 ; poHistory.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.endDt);//采用关阀日期作为统计日期 poHistory.openDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.startDt); poHistory.closeDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.endDt); poHistory.thisAmountLast = cdData.thisWater ; poHistory.thisMoneyLast = cdData.thisMoney ; poHistory.thisTimeLast = cdData.thisDuration ; poHistory.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.endDt); } return poHistory ; } /** * 保存新的历史数据记录,并把ID赋值给最新记录的 lastHistoryId * @param sv * @param clientVo * @param dV202404 * @param cdData * @param lastPo * @throws Exception * @return RmIntakeAmountDay */ private RmClientAmountDay newAndSaveHistoryDataDeal(DbSv sv, SeClient clientVo, DataV202404 dV202404, DataCd85Vo cdData, RmClientAmountDayLast lastPo)throws Exception { RmClientAmountDay poHistory = this.newRmClientAmountDay(clientVo, dV202404, cdData, lastPo) ; sv.saveRmClientAmountDay(poHistory); //由最新数据持有历史数据中的最新记录ID,以方便快速查询 lastPo.lastHistoryId = poHistory == null ? null: poHistory.id ; return poHistory ; } /** * 更新最新数据 * @param clientVo * @param dV202404 * @param cdData * @param lastPo * @return * @throws Exception */ private RmClientAmountDayLast updateRmClientAmountLastBySameDateNewData(SeClient clientVo, DataV202404 dV202404, DataCd85Vo cdData, RmClientAmountDayLast lastPo)throws Exception { lastPo.clientId = clientVo.getId(); if(lastPo.amount != null){ lastPo.amount += cdData.thisWater ; }else{ lastPo.amount = cdData.thisWater ; } if(lastPo.money != null){ lastPo.money += cdData.thisMoney ; }else{ lastPo.money = cdData.thisMoney ; } lastPo.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.endDt);//采用关阀日期作为统计日期 lastPo.openDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.startDt); lastPo.closeDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.endDt); lastPo.thisAmountLast = cdData.thisWater ; lastPo.thisMoneyLast = cdData.thisMoney ; lastPo.thisTimeLast = cdData.thisDuration ; lastPo.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.endDt); return lastPo ; } /** * 更新最新数据 * @param clientVo * @param dV202404 * @param cdData * @param lastPo * @return * @throws Exception */ private RmClientAmountDayLast updateRmClientAmountLastByNewDateNewData(SeClient clientVo, DataV202404 dV202404, DataCd85Vo cdData, RmClientAmountDayLast lastPo)throws Exception { lastPo.clientId = clientVo.getId(); lastPo.amount = cdData.thisWater ; lastPo.money = cdData.thisMoney ; lastPo.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.endDt);//采用关阀日期作为统计日期 lastPo.openDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.startDt); lastPo.closeDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.endDt); lastPo.thisAmountLast = cdData.thisWater ; lastPo.thisMoneyLast = cdData.thisMoney ; lastPo.thisTimeLast = cdData.thisDuration ; lastPo.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.endDt); return lastPo ; } /** * 更新最新数据 * @param clientVo * @param poHistory * @param dV202404 * @param cdData * @param lastPo * @return * @throws Exception */ private RmClientAmountDay updateRmClientAmountBySameDateNewData(SeClient clientVo, RmClientAmountDay poHistory, RmClientAmountDayLast lastPo, DataV202404 dV202404, DataCd85Vo cdData)throws Exception { poHistory.clientId = clientVo.getId(); if(poHistory.amount != null){ poHistory.amount += cdData.thisWater ; }else{ poHistory.amount = cdData.thisWater ; } if(poHistory.money != null){ poHistory.money += cdData.thisMoney ; }else{ poHistory.money = cdData.thisMoney ; } if(poHistory.times != null){ poHistory.times += 1 ; }else{ poHistory.times = 1 ; } poHistory.dt = lastPo.dt ; poHistory.openDtLast = lastPo.openDtLast ; poHistory.closeDtLast = lastPo.closeDtLast ; poHistory.thisAmountLast = lastPo.thisAmountLast ; poHistory.thisMoneyLast = lastPo.thisMoneyLast ; poHistory.thisTimeLast = lastPo.thisTimeLast ; poHistory.rtuDtLast = lastPo.rtuDtLast ; return poHistory ; } /** * 更新最新数据 * @param clientVo * @param poHistory * @param dV202404 * @param cdData * @return * @throws Exception */ private RmClientAmountDay updateOldRmClientAmountBySupplyData(SeClient clientVo, RmClientAmountDay poHistory, DataV202404 dV202404, DataCd85Vo cdData)throws Exception { poHistory.clientId = clientVo.getId(); if(poHistory.amount != null){ poHistory.amount += cdData.thisWater ; }else{ poHistory.amount = cdData.thisWater ; } if(poHistory.money != null){ poHistory.money += cdData.thisMoney ; }else{ poHistory.money = cdData.thisMoney ; } if(poHistory.times != null){ poHistory.times += 1 ; }else{ poHistory.times = 1 ; } poHistory.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.endDt);//采用关阀日期作为统计日期 poHistory.openDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.startDt) ; poHistory.closeDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.endDt) ; poHistory.thisAmountLast = cdData.thisWater ; poHistory.thisMoneyLast = cdData.thisMoney ; poHistory.thisTimeLast = cdData.thisDuration ; poHistory.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.endDt) ; return poHistory ; } } pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V202404/TkDealIcRemainMoneyV202404.java
New file @@ -0,0 +1,164 @@ package com.dy.rtuMw.server.rtuData.p206V202404; import com.dy.common.mw.protocol.Data; import com.dy.common.mw.protocol.p206V202404.DataV202404; import com.dy.common.mw.protocol.p206V202404.upVos.DataCd85Vo; import com.dy.common.mw.protocol.p206V202404.upVos.DataCd84Vo; import com.dy.pipIrrGlobal.voSe.VoCardInfo1; import com.dy.rtuMw.server.rtuData.TaskSurpport; import com.dy.rtuMw.server.rtuData.dbSv.DbSv; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * @Author: liurunyu * @Date: 2025/5/14 10:30 * @Description 处理IC卡剩余金额 */ public class TkDealIcRemainMoneyV202404 extends TaskSurpport { private static final Logger log = LogManager.getLogger(TkDealIcRemainMoneyV202404.class.getName()); //类ID,一定与Tree.xml配置文件中配置一致 public static final String taskId = "TkDealIcRemainMoneyV202404"; /** * 执行节点任务: 取水口日用水量和漏损量 * * @param data 需要处理的数据 */ @Override public void execute(Object data) { Data d = (Data) data; DataV202404 dV1 = (DataV202404) d.getSubData();//前面任务已经判断不为null Object cdObj = dV1.subData; if (cdObj != null && (cdObj instanceof DataCd84Vo || cdObj instanceof DataCd85Vo)){ Object[] objs = this.getTaskResults(TkPreGenObjsV202404.taskId) ; DbSv sv = (DbSv)objs[0] ; try{ TkDealIcRemainMoneyV202404.UpDataVo vo = new TkDealIcRemainMoneyV202404.UpDataVo() ; if(cdObj instanceof DataCd84Vo){ vo.valueFrom( (DataCd84Vo)cdObj, null); }else if(cdObj instanceof DataCd85Vo){ vo.valueFrom(null, (DataCd85Vo)cdObj); } this.doDeal(sv, dV1, vo); }catch (Exception e){ log.error("保存取水口日用水量和漏损量数据时发生异常", e); } } } /** * 业务处理 * @param sv 服务 * @param dV1 上报数据 * @param dataVo 上报数据对象 */ private void doDeal(DbSv sv, DataV202404 dV1, TkDealIcRemainMoneyV202404.UpDataVo dataVo) throws Exception { if(dataVo.icCardNo != null){ if(!dataVo.isVirIcCard){ //实体卡 if(dataVo.remainMoney != null){ VoCardInfo1 vo = sv.getIcCard(dataVo.icCardAddr, dataVo.icCardNo) ; if(vo != null && vo.id != null){ if(vo.money != null){ if(vo.money > dataVo.remainMoney){ //本地的剩余金额 大于 RTU上报的剩余金额 this.updateIcCardRemainMoney(sv, vo.id, dataVo.remainMoney); }else{ //本地的剩余金额 小于 RTU上报的剩余金额,说明当前上报可能是补报或其他原因造成的现象 //不做处理 } }else{ //这种情况一般不会存在,除非有什么误操作造成 this.updateIcCardRemainMoney(sv, vo.id, dataVo.remainMoney); } } } }else{ //虚拟卡 if(dataVo.remainMoney != null){ VoCardInfo1 vo = sv.getVirIcCard(dataVo.icCardNo) ; if(vo != null && vo.id != null){ if(vo.money != null){ if(vo.money > dataVo.remainMoney){ //本地的剩余金额 大于 RTU上报的剩余金额 this.updateVirIcCardRemainMoney(sv, vo.id, dataVo.remainMoney); }else{ //本地的剩余金额 小于 RTU上报的剩余金额,说明当前上报可能是补报或其他原因造成的现象 //不做处理 } }else{ //这种情况一般不会存在,除非有什么误操作造成 this.updateVirIcCardRemainMoney(sv, vo.id, dataVo.remainMoney); } } } } } } /** * 更新实体卡剩余金额 * @param id * @param remainMoney */ private void updateIcCardRemainMoney(DbSv sv, Long id , Double remainMoney){ sv.updateIcCardRemainMoney(id,remainMoney); } /** * 更新虚拟卡剩余金额 * @param id * @param remainMoney */ private void updateVirIcCardRemainMoney(DbSv sv, Long id , Double remainMoney){ sv.updateVirIcCardRemainMoney(id, remainMoney); } private class UpDataVo{ public Boolean isVirIcCard ;//是否为虚拟卡 public String icCardAddr ;//卡地址 public String icCardNo ;//卡编号 public Double remainMoney ; //剩余金额 public void valueFrom(DataCd84Vo vo84, DataCd85Vo vo85){ if(vo84 != null){ if(this.isAll0(vo84.icCardAddr)){ this.isVirIcCard = true ; }else{ this.isVirIcCard = false ; } this.icCardAddr = vo84.icCardAddr ; this.icCardNo = vo84.icCardNo ; this.remainMoney = vo84.moneyRemainUser ; }else if(vo85 != null){ if(this.isAll0(vo85.icCardAddr)){ this.isVirIcCard = true ; }else{ this.isVirIcCard = false ; } this.icCardAddr = vo85.icCardAddr ; this.icCardNo = vo85.icCardNo ; this.remainMoney = vo85.moneyRemain ; } } private boolean isAll0(String s){ if(s != null && !s.trim().equals("")){ s = s.replaceAll("0", "") ; if(s.equals("")){ return true ; }else{ return false ; } } return false ; } } } pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V202404/TkDealIntakeAmountDayV202404.java
New file @@ -0,0 +1,517 @@ package com.dy.rtuMw.server.rtuData.p206V202404; import com.dy.common.mw.protocol.Data; import com.dy.common.mw.protocol.p206V202404.DataV202404; import com.dy.common.mw.protocol.p206V202404.upVos.DataCd84Vo; import com.dy.common.mw.protocol.p206V202404.upVos.DataCd85Vo; import com.dy.common.util.DateTime; import com.dy.pipIrrGlobal.pojoPr.PrController; import com.dy.pipIrrGlobal.pojoRm.RmIntakeAmountDay; import com.dy.pipIrrGlobal.pojoRm.RmIntakeAmountDayLast; import com.dy.rtuMw.server.rtuData.TaskSurpport; import com.dy.rtuMw.server.rtuData.dbSv.DbSv; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * @Author: liurunyu * @Date: 2025/5/14 10:30 * @Description 取水口日用水量和漏损量 */ public class TkDealIntakeAmountDayV202404 extends TaskSurpport { private static final Logger log = LogManager.getLogger(TkDealIntakeAmountDayV202404.class.getName()); //类ID,一定与Tree.xml配置文件中配置一致 public static final String taskId = "TkDealIntakeAmountDayV202404"; /** * 执行节点任务: 取水口日用水量和漏损量 * * @param data 需要处理的数据 */ @Override public void execute(Object data) { Data d = (Data) data; DataV202404 dV202404 = (DataV202404) d.getSubData();//前面任务已经判断不为null Object cdObj = dV202404.subData; /** * 2025-01-11 * 原来实现本任务功能,数据从84,83,C0功能码数据中获得统计数据,但后来数据中增加了金额与开关阀次数, * 从而使得从三种数据中统计数据相当困难与自相矛盾,所以修改实现方式,只从83数据中统计本数据,并且从几 * 个月来运行数据看,只要设备能上线,基本上各种上报数据都能上报上来,所以没有必须从84及C0数据中统计数据了 * 至此,本实现方式定为永久实现方式,不再修改回去了,实践证明,以前的实现方式数据是统计不准确的。 */ if (cdObj != null && ( //cdObj instanceof DataCd84Vo || cdObj instanceof DataCd85Vo )){ Object[] objs = this.getTaskResults(TkPreGenObjsV202404.taskId) ; DbSv sv = (DbSv)objs[0] ; PrController controller = (PrController)objs[1] ; try{ TkDealIntakeAmountDayV202404.UpDataVo vo = new TkDealIntakeAmountDayV202404.UpDataVo() ; /* if(cdObj instanceof DataCd84Vo){ vo.valueFrom(null, (DataCd84Vo)cdObj, null, null); }else */ if(cdObj instanceof DataCd85Vo){ vo.valueFrom(null, (DataCd85Vo)cdObj); } this.doDeal(sv, controller, d.getRtuAddr(), dV202404, vo); }catch (Exception e){ log.error("保存取水口日用水量和漏损量数据时发生异常", e); } } } /** * 业务处理 * @param sv 服务 * @param controller 控制器对象 * @param rtuAddr 控制器地址 * @param dV202404 上报数据 * @param dataVo 上报数据对象 */ private void doDeal(DbSv sv, PrController controller, String rtuAddr, DataV202404 dV202404, TkDealIntakeAmountDayV202404.UpDataVo dataVo) throws Exception { RmIntakeAmountDayLast poLast = sv.getRmIntakeAmountLast(controller.getIntakeId()); if (poLast == null) { //数据库中不存在该取水口的日取水量数据 //首先生成最新数据及历史数据,并先保存 poLast = this.newRmIntakeAmountLast(controller, rtuAddr, dV202404, dataVo); this.newAndSaveRmIntakeAmountHistory(sv, controller, rtuAddr, dV202404, dataVo, poLast); sv.saveRmIntakeAmountLast(poLast); } else { if(DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dataVo.rtuDt).before(poLast.rtuDtLast)){ //RTU时钟早于本地RTU时钟,是补报,不用补报来计算取水口日累计取水量,因为采用的是累计流量相差的计算方法, //其实补报的量值,基于前面上报数据已经计算包含了,只是量值归结的日期不正确罢了。 }else if(DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dataVo.rtuDt).equals(poLast.rtuDtLast)){ //RTU时钟等于本地RTU时钟,重复上报数据,不进行任何处理 }else{ //上行数据中的日期时间符合计算的条件 if(!rtuAddr.equals(poLast.rtuAddrLast)){ //更换了控制器,处理方法:只更换控制器地址,不进行水量计算 //因为上行数据中的日期时间是可进行计算的 if(DateTime.dateFrom_yyyy_MM_dd1(dV202404.dt).equals(poLast.dt)){ //同一天数据 poLast = this.updateRmIntakeAmountLastBySameDateByControllerChange(poLast, controller, rtuAddr, dV202404, dataVo); RmIntakeAmountDay poHistory = null ; if(poLast.lastHistoryId != null){ poHistory = sv.getRmIntakeAmountDay(poLast.lastHistoryId) ; } if(poHistory == null){ this.newAndSaveRmIntakeAmountHistory(sv, controller, rtuAddr, dV202404, dataVo, poLast); }else{ poHistory = this.updateRmIntakeAmountBySameDateByControllerChange(poHistory, poLast, controller, rtuAddr, dV202404, dataVo); sv.updateRmIntakeAmountDay(poHistory); } }else{ //非同一天,所以新生成一个历史记录 poLast = this.updateRmIntakeAmountLastByNewDateByControllerChange(poLast, controller, rtuAddr, dV202404, dataVo); this.newAndSaveRmIntakeAmountHistory(sv, controller, rtuAddr, dV202404, dataVo, poLast); } }else{ //未更换控制器 if(DateTime.dateFrom_yyyy_MM_dd1(dV202404.dt).equals(poLast.dt)){ //同一天数据 poLast = this.updateRmIntakeAmountLastBySameDateNewData(poLast, controller, rtuAddr, dV202404, dataVo); RmIntakeAmountDay poHistory = null ; if(poLast.lastHistoryId != null){ poHistory = sv.getRmIntakeAmountDay(poLast.lastHistoryId) ; } if(poHistory == null){ this.newAndSaveRmIntakeAmountHistory(sv, controller, rtuAddr, dV202404, dataVo, poLast); }else{ poHistory = this.updateRmIntakeAmountBySameDateNewData(poHistory, poLast, controller, rtuAddr, dV202404, dataVo); sv.updateRmIntakeAmountDay(poHistory); } }else if(DateTime.dateFrom_yyyy_MM_dd1(dV202404.dt).after(poLast.dt)){ //新的日期 poLast = this.updateRmIntakeAmountLastByNewDateNewData(poLast, controller, rtuAddr, dV202404, dataVo); this.newAndSaveRmIntakeAmountHistory(sv, controller, rtuAddr, dV202404, dataVo, poLast); }else{ //这种情况不存在 } } } //更新最新数据 sv.updateRmIntakeAmountLast(poLast); } } /** * 生成新的取水口用水统计最新记录 * @param controller * @param rtuAddr * @param dV202404 * @param cdData * @return * @throws Exception */ private RmIntakeAmountDayLast newRmIntakeAmountLast(PrController controller, String rtuAddr, DataV202404 dV202404, TkDealIntakeAmountDayV202404.UpDataVo cdData)throws Exception { RmIntakeAmountDayLast po = new RmIntakeAmountDayLast() ; po.intakeId = controller==null?null:controller.getIntakeId(); po.controllerIdLast = controller==null?null:controller.getId(); po.totalAmountLast = cdData.totalAmount ; po.dt = DateTime.dateFrom_yyyy_MM_dd1(dV202404.dt); po.dtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dV202404.dt); po.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt); po.amount = cdData.amount ; po.money = cdData.money ; po.times = 1 ; /* 2025-01-11 if(cdData.isCloseValve != null && cdData.isCloseValve){ po.amount = cdData.amount ; po.money = cdData.money ; po.times = 1 ; }else{ po.amount = 0.0D ; po.money = 0.0D ; po.times = 0 ; }*/ po.rtuAddrLast = rtuAddr; return po ; } /** * 保存新的历史数据记录,并把ID赋值给最新记录的 lastHistoryId * @param sv * @param controller * @param rtuAddr * @param dV202404 * @param cdData * @param poLast * @throws Exception * @return RmIntakeAmountDay */ private RmIntakeAmountDay newAndSaveRmIntakeAmountHistory(DbSv sv, PrController controller, String rtuAddr, DataV202404 dV202404, TkDealIntakeAmountDayV202404.UpDataVo cdData, RmIntakeAmountDayLast poLast)throws Exception { RmIntakeAmountDay poHistory = new RmIntakeAmountDay() ; poHistory.intakeId = controller==null?null:controller.getIntakeId(); poHistory.controllerIdLast = controller==null?null:controller.getId(); poHistory.rtuAddrLast = rtuAddr; poHistory.dt = DateTime.dateFrom_yyyy_MM_dd1(dV202404.dt); poHistory.dtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dV202404.dt); poHistory.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt); poHistory.totalAmountLast = cdData.totalAmount ; //2025-01-11 if(poLast != null){ poHistory.amount = poLast.amount ; poHistory.money = poLast.money ; poHistory.times = poLast.times ; }else{ poHistory.amount = 0.0D ; poHistory.money = 0.0D ; poHistory.times = 0 ; } sv.saveRmIntakeAmountDay(poHistory); //由最新数据持有历史数据中的最新记录ID,以方便快速查询 poLast.lastHistoryId = poHistory == null ? null: poHistory.id ; return poHistory ; } /** * 取水口更换了控制器,同一天数据,此时只更新部分属性 * @param controller * @param rtuAddr * @param dV202404 * @param cdData * @return * @throws Exception */ private RmIntakeAmountDayLast updateRmIntakeAmountLastBySameDateByControllerChange(RmIntakeAmountDayLast lastPo, PrController controller, String rtuAddr, DataV202404 dV202404, TkDealIntakeAmountDayV202404.UpDataVo cdData)throws Exception { lastPo.intakeId = controller==null?null:controller.getIntakeId(); lastPo.controllerIdLast = controller==null?null:controller.getId(); lastPo.rtuAddrLast = rtuAddr; lastPo.dt = DateTime.dateFrom_yyyy_MM_dd1(dV202404.dt); lastPo.dtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dV202404.dt); lastPo.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt); lastPo.totalAmountLast = cdData.totalAmount ; //阀控器更换了,并且是同一天数据 //只有关阀报数据(2025-01-11) if(lastPo.amount == null){ lastPo.amount = cdData.amount ; }else{ lastPo.amount += cdData.amount ; } if(lastPo.money == null){ lastPo.money = cdData.money ; }else{ lastPo.money += cdData.money ; } if(lastPo.times == null){ lastPo.times = 1 ; }else{ lastPo.times += 1 ; } /* if(cdData.isCloseValve != null && cdData.isCloseValve.booleanValue()){ //是从关阀报中得到的数据 if(lastPo.amount == null){ lastPo.amount = cdData.amount ; }else{ lastPo.amount += cdData.amount ; } if(lastPo.money == null){ lastPo.money = cdData.money ; }else{ lastPo.money += cdData.money ; } if(lastPo.times == null){ lastPo.times = 1 ; }else{ lastPo.times += 1 ; } }else{ //非关阀报数据 //不作为 }*/ return lastPo ; } /** * 取水口更换了控制器在,此时只更新部分属性 * @param controller * @param rtuAddr * @param dV202404 * @param cdData * @return * @throws Exception */ private RmIntakeAmountDay updateRmIntakeAmountBySameDateByControllerChange(RmIntakeAmountDay po, RmIntakeAmountDayLast lastPo, PrController controller, String rtuAddr, DataV202404 dV202404, TkDealIntakeAmountDayV202404.UpDataVo cdData)throws Exception { po.intakeId = controller==null?null:controller.getIntakeId(); po.controllerIdLast = controller==null?null:controller.getId(); po.rtuAddrLast = rtuAddr; po.dt = lastPo.dt ; po.dtLast = lastPo.dtLast; po.rtuDtLast = lastPo.rtuDtLast; po.totalAmountLast = lastPo.totalAmountLast ; //阀控器更换了,并且是同一天数据 //只有关阀报数据(2025-01-11) po.amount = lastPo.amount ; po.money = lastPo.money ; po.times = lastPo.times ; return po ; } /** * 取水口更换了控制器,非同一天数据,此时更新部分属性 * @param controller * @param rtuAddr * @param dV202404 * @param cdData * @return * @throws Exception */ private RmIntakeAmountDayLast updateRmIntakeAmountLastByNewDateByControllerChange(RmIntakeAmountDayLast lastPo, PrController controller, String rtuAddr, DataV202404 dV202404, TkDealIntakeAmountDayV202404.UpDataVo cdData)throws Exception { lastPo.intakeId = controller==null?null:controller.getIntakeId(); lastPo.controllerIdLast = controller==null?null:controller.getId(); lastPo.rtuAddrLast = rtuAddr; lastPo.dt = DateTime.dateFrom_yyyy_MM_dd1(dV202404.dt); lastPo.dtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dV202404.dt); lastPo.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt); lastPo.totalAmountLast = cdData.totalAmount ; //阀控器更换了,并且是新一天数据 2025-01-11 lastPo.amount = cdData.amount ; lastPo.money = cdData.money ; lastPo.times = 1 ; return lastPo ; } /** * 收到同一天的新的数据,进行更新数据 * @param controller * @param rtuAddr * @param dV202404 * @param cdData * @return * @throws Exception */ private RmIntakeAmountDayLast updateRmIntakeAmountLastBySameDateNewData(RmIntakeAmountDayLast lastPo, PrController controller, String rtuAddr, DataV202404 dV202404, TkDealIntakeAmountDayV202404.UpDataVo cdData)throws Exception { lastPo.intakeId = controller==null?null:controller.getIntakeId(); lastPo.controllerIdLast = controller==null?null:controller.getId(); lastPo.rtuAddrLast = rtuAddr; //lastPo.dt = DateTime.dateFrom_yyyy_MM_dd1(dV202404.dt);//日期没变 lastPo.dtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dV202404.dt); lastPo.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt); if(cdData.totalAmount == 0.0F){ //发现阀控器一个bug,经常上报累计流量为0,推测是阀控器未能从水表采集到数据时会上报0值 //这种情况数据不做处理 //如果水表初安装,未进行过任务取水,那么累计流量会是0,这种情况当bug处理也无防 //上面时标作了更新,也正常,相当于本次上报的累计流量与上次上报的累计流量数值相等 //lastPo.totalAmountLast = lastPo.totalAmountLast ; //lastPo.amount = lastPo.amount; //本日的日累计水量保持不变 }else { lastPo.totalAmountLast = cdData.totalAmount; } //是同一天数据 //只有关阀报数据(2025-01-11) if(lastPo.amount == null){ lastPo.amount = cdData.amount ; }else{ lastPo.amount += cdData.amount ; } if(lastPo.money == null){ lastPo.money = cdData.money ; }else{ lastPo.money += cdData.money ; } if(lastPo.times == null){ lastPo.times = 1 ; }else{ lastPo.times += 1 ; } /* 2025-01-11 Double added = cdData.totalAmount - lastPo.totalAmountLast ; if(added > 0){ if(lastPo.amount == null){ lastPo.amount = added ; }else{ lastPo.amount += added ; } }else{ //可能是更换水表了,新表底值比原表底值小。 //本次置量值不变,下次再上报时,就能正常计算了。 //lastPo.amount = lastPo.amount ; //日累计取水量不变 } if(cdData.isCloseValve != null && cdData.isCloseValve.booleanValue()){ //是从关阀报中得到的数据 if(lastPo.money == null){ lastPo.money = cdData.money ; }else{ lastPo.money += cdData.money ; } if(lastPo.times == null){ lastPo.times = 1 ; }else{ lastPo.times += 1 ; } }else{ //非关阀报数据 //不作为 } */ return lastPo ; } /** * 因收到新的一天的新的数据后,进行更新数据 * @param controller * @param rtuAddr * @param dV202404 * @param cdData * @return * @throws Exception */ private RmIntakeAmountDayLast updateRmIntakeAmountLastByNewDateNewData(RmIntakeAmountDayLast lastPo, PrController controller, String rtuAddr, DataV202404 dV202404, TkDealIntakeAmountDayV202404.UpDataVo cdData)throws Exception { lastPo.intakeId = controller==null?null:controller.getIntakeId(); lastPo.controllerIdLast = controller==null?null:controller.getId(); lastPo.rtuAddrLast = rtuAddr; lastPo.dt = DateTime.dateFrom_yyyy_MM_dd1(dV202404.dt);//日期变了 lastPo.dtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dV202404.dt); lastPo.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt); lastPo.totalAmountLast = cdData.totalAmount ; //新的一天数据 2025-01-11 lastPo.amount = cdData.amount ; lastPo.money = cdData.money ; lastPo.times = 1 ; /* if(cdData.totalAmount == 0.0F){ //发现阀控器一个bug,经常上报累计流量为0,推测是阀控器未能从水表采集到数据时会上报0值 //这种情况数据不做处理 //如果水表初安装,未进行过任务取水,那么累计流量会是0,这种情况当bug处理也无防 //上面时标作了更新,也正常,相当于本次上报的累计流量与上次上报的累计流量数值相等 //lastPo.totalAmountLast = lastPo.totalAmountLast ; lastPo.amount = 0.0D; //新的一天的日累计水量置0 }else{ Double added = cdData.totalAmount - lastPo.totalAmountLast ; if(added > 0){ //新的一天的处理方式与同一天的处理方式不一样 lastPo.amount = added; }else{ //可能是更换水表了,新表底值比原表底值小。 //本次置0,下次再上报时,就能正常计算了。 lastPo.amount = 0.0D; //日累计水量归0 } } if(cdData.isCloseValve != null && cdData.isCloseValve.booleanValue()){ //是从关阀报中得到的数据 lastPo.money = cdData.money ; lastPo.times = 1 ; }else{ //非关阀报数据 //不作为 } */ return lastPo ; } /** * 更新历史记录 * @param controller * @param rtuAddr * @param dV202404 * @param cdData * @return * @throws Exception */ private RmIntakeAmountDay updateRmIntakeAmountBySameDateNewData(RmIntakeAmountDay po, RmIntakeAmountDayLast lastPo, PrController controller, String rtuAddr, DataV202404 dV202404, TkDealIntakeAmountDayV202404.UpDataVo cdData)throws Exception { po.intakeId = controller==null?null:controller.getIntakeId(); po.controllerIdLast = controller==null?null:controller.getId(); po.rtuAddrLast = rtuAddr; po.dt = lastPo.dt ; po.dtLast = lastPo.dtLast; po.rtuDtLast = lastPo.rtuDtLast; po.totalAmountLast = lastPo.totalAmountLast ; po.amount = lastPo.amount ;//此时lastPo.amount已经增加上了增量 po.money = lastPo.money ;//此时lastPo.money已经增加上了增量 po.times = lastPo.times ;//此时lastPo.times已经增加上了增量 return po ; } public class UpDataVo{ public Double totalAmount; //累计流量:5字节BCD码,取值范围0~9999999999,单位为m3。 public Double amount; //农户用水量 public Double money ;//农户消费金额 public Boolean isCloseValve ;//是否是关阀上报 public String rtuDt ;//控制器时钟 public void valueFrom(DataCd84Vo vo84, DataCd85Vo vo85){ /* if(vo84 != null){ this.totalAmount = vo84.totalAmount ; this.rtuDt = vo84.rtuDt ; }else if(vo85 != null){ */ this.totalAmount = vo85.waterTotalAmount ; this.amount = vo85.thisWater ; this.money = vo85.thisMoney ; this.isCloseValve = true ; this.rtuDt = vo85.endDt ; /*} */ } } } pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V202404/TkDealLossV202404.java
New file @@ -0,0 +1,170 @@ package com.dy.rtuMw.server.rtuData.p206V202404; import com.dy.common.mw.protocol.Data; import com.dy.common.mw.protocol.p206V202404.DataV202404; import com.dy.common.mw.protocol.p206V202404.upVos.DataCd83Vo; import com.dy.common.util.DateTime; import com.dy.pipIrrGlobal.pojoPr.PrController; import com.dy.pipIrrGlobal.pojoRm.RmLossDay; import com.dy.pipIrrGlobal.pojoRm.RmLossDayLast; import com.dy.rtuMw.server.rtuData.TaskSurpport; import com.dy.rtuMw.server.rtuData.dbSv.DbSv; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.util.Date; /** * @Author: liurunyu * @Date: 2025/5/14 11:12 * @Description 取水口漏损统计 */ public class TkDealLossV202404 extends TaskSurpport { private static final Logger log = LogManager.getLogger(TkDealLossV202404.class.getName()); //类ID,一定与Tree.xml配置文件中配置一致 public static final String taskId = "TkDealLossV202404"; /** * 执行节点任务: 处理控制器漏损统计 * * @param data 需要处理的数据 */ @Override public void execute(Object data) { Data d = (Data) data; DataV202404 dV202404 = (DataV202404) d.getSubData();//前面任务已经判断不为null Object cdObj = dV202404.subData; if (cdObj != null && cdObj instanceof DataCd83Vo){ Object[] objs = this.getTaskResults(TkPreGenObjsV202404.taskId) ; DbSv sv = (DbSv)objs[0] ; PrController controller = (PrController)objs[1] ; try{ this.doDeal(sv, controller, d.getRtuAddr(), dV202404, (DataCd83Vo)cdObj); }catch (Exception e){ log.error("保存取水口漏损统计数据时发生异常", e); } } } /** * 业务处理 * @param sv 服务 * @param controller 控制器对象 * @param rtuAddr 控制器地址 * @param dV202404 上报数据 * @param dataCdC0Vo 开阀上报数据对象 */ private void doDeal(DbSv sv, PrController controller, String rtuAddr, DataV202404 dV202404, DataCd83Vo dataCdC0Vo) throws Exception { Date operateDt = controller.getOperateDt() ;//取水中上绑定此控制器的日期与时间 if(operateDt != null){ String operateDtStr = DateTime.yyyy_MM_dd(operateDt) ; if(operateDtStr.equals(DateTime.yyyy_MM_dd())){ //当天发现(并绑定)控制器,控制器计算的漏损量一定不正确,强制设置成0 dataCdC0Vo.lossTotalAmountDay = 0.0 ; } } RmLossDayLast poLast = sv.getRmLossLast(controller.getIntakeId()); if (poLast == null) { //数据库中不存在该取水口的漏损数据 //首先生成最新数据及历史数据,并先保存 poLast = this.newRmLossLast(controller, rtuAddr, dV202404, dataCdC0Vo); this.newAndSaveHistoryDataDeal(sv, controller, rtuAddr, dV202404, dataCdC0Vo, poLast); sv.saveRmLossLast(poLast); } else { if(DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dataCdC0Vo.dataDt).equals(poLast.dtRtu)){ //时间一致,重复上报数据,不进行任何处理 }else{ RmLossDay poHistory = null ; if(poLast.lastHistoryId != null){ poHistory = sv.getRmLossHistory(poLast.lastHistoryId) ; } if(poHistory == null){ poHistory = this.newAndSaveHistoryDataDeal(sv, controller, rtuAddr, dV202404, dataCdC0Vo, poLast); } if(DateTime.dateFrom_yyyy_MM_dd1(dV202404.dt).equals(poLast.dt)){ //同一天数据 poLast.lossAmount = dataCdC0Vo.lossTotalAmountDay ; poLast.dtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dV202404.dt) ; poLast.dtRtu = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dataCdC0Vo.dataDt) ; sv.updateRmLossLast(poLast); poHistory.lossAmount = dataCdC0Vo.lossTotalAmountDay ; poHistory.dtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dV202404.dt) ; poHistory.dtRtu = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dataCdC0Vo.dataDt) ; sv.updateRmLossHistory(poHistory); }else if(DateTime.dateFrom_yyyy_MM_dd1(dV202404.dt).after(poLast.dt)){ //新的日期 poLast.lossAmount = dataCdC0Vo.lossTotalAmountDay ; poLast.dt = DateTime.dateFrom_yyyy_MM_dd1(dataCdC0Vo.dataDt); poLast.dtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dV202404.dt) ; poLast.dtRtu = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dataCdC0Vo.dataDt) ; this.newAndSaveHistoryDataDeal(sv, controller, rtuAddr, dV202404, dataCdC0Vo, poLast); sv.updateRmLossLast(poLast); }else{ //这种情况不存在(RTU时钟早于本地记录中的RTU时钟(RTU穿越回过去了,可能时钟重置了),此种情况不处理) } } sv.updateRmLossLast(poLast); } } /** * 生成新的控制器漏损日统计最新记录 * @param controller * @param rtuAddr * @param dV202404 * @param cdData * @return * @throws Exception */ private RmLossDayLast newRmLossLast(PrController controller, String rtuAddr, DataV202404 dV202404, DataCd83Vo cdData)throws Exception { RmLossDayLast po = new RmLossDayLast() ; po.controllerId = controller==null?null:controller.getId(); po.intakeId = controller==null?null:controller.getIntakeId(); po.rtuAddr = rtuAddr; po.valueFrom(dV202404, cdData) ; return po ; } /** * 生成新的控制器漏损日统计历史记录 * @param controller * @param rtuAddr * @param dV202404 * @param cdData * @return * @throws Exception */ private RmLossDay newRmLossHistory(PrController controller, String rtuAddr, DataV202404 dV202404, DataCd83Vo cdData)throws Exception { RmLossDay po = new RmLossDay() ; po.controllerId = controller==null?null:controller.getId(); po.intakeId = controller==null?null:controller.getIntakeId(); po.rtuAddr = rtuAddr; po.valueFrom(dV202404, cdData); return po ; } /** * 保存新的开阀上报历史数据记录,并把ID赋值给最新记录的 lastHistoryId * @param sv * @param controller * @param rtuAddr * @param dV202404 * @param dataCdC0Vo * @param poLast * @throws Exception * @return RmLossHistory */ private RmLossDay newAndSaveHistoryDataDeal(DbSv sv, PrController controller, String rtuAddr, DataV202404 dV202404, DataCd83Vo dataCdC0Vo, RmLossDayLast poLast)throws Exception { RmLossDay poHistory = this.newRmLossHistory(controller, rtuAddr, dV202404, dataCdC0Vo) ; sv.saveRmLossHistory(poHistory); //由最新数据持有历史数据中的最新记录ID,以方便快速查询 poLast.lastHistoryId = poHistory == null ? null: poHistory.id ; return poHistory ; } } pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/RtuDataDealTree.xml
@@ -78,6 +78,10 @@ <task id="TkDealWorkingReportV202404" name="控制器工作报(功能码80)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V202404.TkDealWorkingReportV202404" /> <task id="TkDealOpenValveReportV202404" name="控制器开阀上报(功能码84)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V202404.TkDealOpenValveReportV202404" /> <task id="TkDealCloseValveReportV202404" name="控制器关阀上报(功能码85)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V202404.TkDealCloseValveReportV202404" /> <task id="TkDealLossV202404" name="取水口日漏损量(功能码83)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V202404.TkDealLossV202404" /> <task id="TkDealIntakeAmountDayV202404" name="取水口日用水量(功能码84、功能码85)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V202404.TkDealIntakeAmountDayV202404" /> <task id="TkDealClientAmountDayV202404" name="农户日用水量(功能码85)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V202404.TkDealClientAmountDayV202404" /> <task id="TkDealIcRemainMoneyV202404" name="IC卡剩余金额(功能码84、功能码85)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V202404.TkDealIcRemainMoneyV202404" /> </task> <!-- 识别命令响应数据 --> <task id="TkFindComResponseV202404" name="识别响应命令数据" enable="true" class="com.dy.rtuMw.server.rtuData.p206V202404.TkFindComResponseV202404">