diff --git a/dntd-model-buildheating/src/main/java/com/dky/calculate/BuildHeatingAdvantage.java b/dntd-model-buildheating/src/main/java/com/dky/calculate/BuildHeatingAdvantage.java index bde0c6a..3ef2531 100644 --- a/dntd-model-buildheating/src/main/java/com/dky/calculate/BuildHeatingAdvantage.java +++ b/dntd-model-buildheating/src/main/java/com/dky/calculate/BuildHeatingAdvantage.java @@ -1,23 +1,42 @@ package com.dky.calculate; + +import java.text.DecimalFormat; + //方案优势 public class BuildHeatingAdvantage { -//安全性 - public static String safety(){ - return "精准控温"; + + DecimalFormat decimalFormat = new DecimalFormat("#.00"); + + /** + * 经济性 + * @param firstInvestFee 初始投资金额 + * @param yearRunFee 年运行费用 + * @param lastYearFee 替代前上年运行费用 + * @return + */ + public String economy(Double firstInvestFee ,Double yearRunFee, Double lastYearFee){ + // 运行收益 = 上年运行费用(即原设备运行费用)- 今年运行费用 + Double hsq = Math.round((lastYearFee - yearRunFee) * 100.0)/100.0; + if (hsq <= 0){ + return "本技术方案中替代技术相对于原生产设备在经济性上优势不大,但从环保效益上具有较高的优势"; + } + // 投资回收期 = 初次投资费用/运行收益 + Double js = Math.round((firstInvestFee / hsq) * 100.0)/100.0; + return "本次改造投资回收期为"+js+"年,本改造方案相比较原技术节省年运行费用成本"+decimalFormat.format(hsq)+"元。"; } - //经济性 - public static String economy(Double firstInvestFee,Double yearTotalFee,Double yearRunFee,Double lastYearFee){ - Double hsq = Math.round(firstInvestFee/yearTotalFee*100.0)/100.0; - double js = Math.round((lastYearFee - yearRunFee)*100.0)/100.0; - return "本次改造投资回收期为"+hsq+"年,本改造方案相比较原技术节省年运行费用成本"+js+"元。"; + + // 智能性 + public String safety(){ + return "精准控温"; } + // 智能性 - public static String intelligence() { + public String intelligence() { return "以电锅炉替代和实现精准控温。"; } // 环保性 - public static String environment(Double yearReduceCarbon) { + public String environment(Double yearReduceCarbon) { return "本次改造方案减排" + yearReduceCarbon + "吨"; } diff --git a/dntd-model-buildheating/src/main/java/com/dky/calculate/BuildHeatingModel.java b/dntd-model-buildheating/src/main/java/com/dky/calculate/BuildHeatingModel.java index 136c580..b472af5 100644 --- a/dntd-model-buildheating/src/main/java/com/dky/calculate/BuildHeatingModel.java +++ b/dntd-model-buildheating/src/main/java/com/dky/calculate/BuildHeatingModel.java @@ -33,7 +33,7 @@ public class BuildHeatingModel { * @param laborCost 电替代设备人工费用成本 * @return */ - public static Double getRunCost(Integer deviceNum, + public Double getRunCost(Integer deviceNum, Double devicePower, Integer days, Integer years, @@ -51,7 +51,7 @@ public class BuildHeatingModel { * @param laborCost 电替代设备人工费用成本 非表中参数 * @return */ - public static Double getYearCost(Integer deviceNum, + public Double getYearCost(Integer deviceNum, Double devicePrice, Integer useYears, Double devicePower, @@ -62,23 +62,41 @@ public class BuildHeatingModel { } /** - * 年减碳 - * @param lastYearFee 上年运行费用 - * @param oldLaborCost 原设备的人工费用 - * @param electricCost 电替代设备年耗电量 + * 计算原设备年排碳量 + * @param lastYearEnergyUse 替代前年能源使用量 + * @param d 相关能源排放系数 * @return */ - public static Double calculateAnnualCarbonReduction(Double lastYearFee, - Double oldLaborCost, - Double electricCost){ - // 计算煤炭减少的碳排放量 - double coalReduction = (lastYearFee - oldLaborCost) / COAL_PRICE_PER_KILOGRAM * STANDARD_COAL_CONVERSION_FACTOR; + public double calLastYearFactor(Double lastYearEnergyUse , Double d) { + return lastYearEnergyUse * d; + } + + /** + * 计算原设备上年运行费用 + * + * @param laborCost 人工成本 + * @param lastYearEnergyUse 替代前年能源使用量 + * @param energyPrice 平均能源单价 + * @return + */ + public double calLastYearFee(Double laborCost, Double lastYearEnergyUse, Double energyPrice) { + // 上年运行费用(即原设备运行费用)= 上年能源使用量 * 平均能源单价 + 上年人工成本 + return energyPrice * lastYearEnergyUse + laborCost; + } - // 计算电替代设备增加的碳排放量 - double electricityIncrease = electricCost * ELECTRICITY_SUBSTITUTION_CONVERSION_FACTOR; + /** + * 计算年减碳量 + * @param previousYearEnergyUsage 替代前原设备碳排放量 + * @param deviceElectric 电替代耗电量 + * @param electricEmission 电替代设备碳排放因子 + * @return 年减碳量 + */ + public double calculateAnnualCarbonReduction(Double previousYearEnergyUsage, Double deviceElectric, Double electricEmission) { + // 计算电替代设备年耗电量对应的标准煤量 + double coalEquivalentFromElectricity = deviceElectric * electricEmission; - // 计算总的年减碳量 - return (coalReduction - electricityIncrease) * CO2_CONVERSION_FACTOR; + // 计算年减碳量 + return previousYearEnergyUsage - coalEquivalentFromElectricity; } @@ -89,7 +107,7 @@ public class BuildHeatingModel { * @param days 年采暖(供冷)时间(天) * @return */ - public static Double getElectric(Integer deviceNum, + public Double getElectric(Integer deviceNum, Double devicePower, Integer days){ return deviceNum * devicePower * days * 24 ; diff --git a/dntd-model-buildheating/src/main/java/com/dky/calculate/CalC.java b/dntd-model-buildheating/src/main/java/com/dky/calculate/CalC.java index 539fb00..c53b37e 100644 --- a/dntd-model-buildheating/src/main/java/com/dky/calculate/CalC.java +++ b/dntd-model-buildheating/src/main/java/com/dky/calculate/CalC.java @@ -35,7 +35,7 @@ public class CalC { return maps; } - public static Double getC1(List> args) { + public Double getC1(List> args) { // 循环遍历各个方案 final Double[] maxPower = {-100.0}; args.parallelStream().forEach(plan -> { diff --git a/dntd-model-buildheating/src/main/java/com/dky/calculate/Scheme.java b/dntd-model-buildheating/src/main/java/com/dky/calculate/Scheme.java index e9ccd4a..9dd42b8 100644 --- a/dntd-model-buildheating/src/main/java/com/dky/calculate/Scheme.java +++ b/dntd-model-buildheating/src/main/java/com/dky/calculate/Scheme.java @@ -17,7 +17,7 @@ public class Scheme { * @param buildArea 建筑面积 * @param sysDeviceHeatSceneList 替代设备列表 */ - public static List> calScheme(Double buildArea, List sysDeviceHeatSceneList) { + public List> calScheme(Double buildArea, List sysDeviceHeatSceneList) { // 根据设备细类筛选出一个以设备细类为键,该细类下设备列表为值的Map Map> groupByDevSubTypeMap = sysDeviceHeatSceneList.stream() .collect(Collectors.groupingBy(SysDeviceHeatScene::getDevSubType)); @@ -46,7 +46,7 @@ public class Scheme { * @param sysDeviceHeatSceneList 不同设备细类-技术类型下的设备列表 * @return 不同功率的设备对应所需要的数量 */ - public static List calSchemeByTechType(Double buildArea, List sysDeviceHeatSceneList) { + public List calSchemeByTechType(Double buildArea, List sysDeviceHeatSceneList) { // 对技术类型下的设备list按照单台设备可参考供暖面积进行排序 sysDeviceHeatSceneList.sort((o1, o2) -> Double.compare(o2.getDevReferenceArea(), o1.getDevReferenceArea())); Double remainArea = buildArea; diff --git a/dntd-model-buildheating/src/main/java/com/dky/calculate/SchemeRating.java b/dntd-model-buildheating/src/main/java/com/dky/calculate/SchemeRating.java index 7ef6e7e..610fe71 100644 --- a/dntd-model-buildheating/src/main/java/com/dky/calculate/SchemeRating.java +++ b/dntd-model-buildheating/src/main/java/com/dky/calculate/SchemeRating.java @@ -14,7 +14,7 @@ public class SchemeRating { * @param list * @return */ - public static Map getOptimalList(List> list,Double costRatio,Double effRatio,Map maxEff,Map minPrice) { + public Map getOptimalList(List> list,Double costRatio,Double effRatio,Map maxEff,Map minPrice) { Map optimalMap = new HashMap<>(); list.forEach(plan->{ @@ -55,7 +55,7 @@ public class SchemeRating { * @param map * @return */ - public static List getOptimalScheme(Map map) { + public List getOptimalScheme(Map map) { final AtomicReference[] rating = new AtomicReference[]{new AtomicReference<>(-100.0)}; final List[] list = new List[]{new ArrayList<>()}; @@ -74,7 +74,7 @@ public class SchemeRating { * @param alternateDeviceList 可替代设备列表 * @return 不同设备细类下的效率最大值map */ - public static Map getMaxEfficiencyGroupByDevSubType(List alternateDeviceList){ + public Map getMaxEfficiencyGroupByDevSubType(List alternateDeviceList){ Map map = new HashMap<>(); alternateDeviceList.forEach(alternateDevice ->{ String devSubType = alternateDevice.getDevSubType(); @@ -95,7 +95,7 @@ public class SchemeRating { * @param alternateDeviceList 可替代设备列表 * @return 不同设备细类下的成本最小值 */ - public static Map getMinPriceGroupByDevSubType(List> alternateDeviceList){ + public Map getMinPriceGroupByDevSubType(List> alternateDeviceList){ Map map = new HashMap<>(); alternateDeviceList.forEach(plan -> { Double thisPlanCost = 0.0; @@ -117,7 +117,7 @@ public class SchemeRating { } - public static List> getIndex(List> list) { + public List> getIndex(List> list) { List> maps = new ArrayList<>(); final Double[] index = {0.0, Double.MAX_VALUE}; Map map = new HashMap<>(); diff --git a/dntd-tool/src/main/java/com/dky/generate/BuildHeatingScene.java b/dntd-model-buildheating/src/main/java/com/dky/generate/BuildHeatingScene.java similarity index 52% rename from dntd-tool/src/main/java/com/dky/generate/BuildHeatingScene.java rename to dntd-model-buildheating/src/main/java/com/dky/generate/BuildHeatingScene.java index c47d763..8a55e4a 100644 --- a/dntd-tool/src/main/java/com/dky/generate/BuildHeatingScene.java +++ b/dntd-model-buildheating/src/main/java/com/dky/generate/BuildHeatingScene.java @@ -4,6 +4,7 @@ package com.dky.generate; import cn.hutool.json.JSONObject; import com.dky.calculate.*; import com.dky.modelI.DntdModelI; +import com.dky.utils.CalculateUtils; import com.dky.utils.GetTargetDeviceList; import com.dky.utils.GetThisEnergyEmissions; import com.dky.utils.entity.SysDeviceHeatScene; @@ -32,26 +33,84 @@ public class BuildHeatingScene implements DntdModelI { List alternateDeviceList = new ArrayList<>(list1); alternateDeviceList.addAll(list2); + Scheme scheme = new Scheme(); + SchemeRating schemeRating = new SchemeRating(); + CalC calC = new CalC(); + BuildHeatingAdvantage advantage = new BuildHeatingAdvantage(); + BuildHeatingModel buildHeatingModel = new BuildHeatingModel(); + JSONObject distInfo = new JSONObject(); JSONObject buildInfo = new JSONObject(); JSONObject originalDevInfo = new JSONObject(); - try{ + Double runCapacity = null; + Double lastYearNeed = null; + Double heatingArea = null; + Integer days = 0; + Integer energyCode = null; + try { distInfo = (JSONObject) jsonObject.get("distInfo"); buildInfo = (JSONObject) jsonObject.get("buildInfo"); originalDevInfo = (JSONObject) jsonObject.get("originalDevInfo"); - } catch (Exception e){ + + } catch (Exception e) { e.printStackTrace(); } - // 运行容量 - Double runCapacity = Double.parseDouble(distInfo.get("runCapacity").toString()); - // 上年最大需量 - Double lastYearNeed = Double.parseDouble(distInfo.get("lastYearNeed").toString()); - // 建筑面积 - Double heatingArea = Double.parseDouble(buildInfo.get("heatingArea").toString()); - // 年采暖时间(天) - Integer days = Integer.parseInt(buildInfo.get("days").toString()); + try { + // 上年最大需量 + lastYearNeed = Double.parseDouble(distInfo.get("lastYearNeed").toString()); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素上年最大需量传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素上年最大需量为非数字,禁止传参空字符串"); + } + + try { + // 运行容量 + runCapacity = Double.parseDouble(distInfo.get("runCapacity").toString()); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素运行容量传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素运行容量为非数字,禁止传参空字符串"); + } + + try { + // 年采暖时间(天) + days = Integer.parseInt(buildInfo.get("days").toString()); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素年采暖天数为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素年采暖天数为非数字,禁止传参空字符串"); + } + + try { + // 建筑面积 + heatingArea = Double.parseDouble(buildInfo.get("heatingArea").toString()); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素建筑面积传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素建筑面积为非数字,禁止传参空字符串"); + } + + try { + // 替代前原能源类型编码 + energyCode = (Integer) buildInfo.get("energyCode"); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素替代前原能源类型编码传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素替代前原能源类型编码为非数字,禁止传参空字符串"); + } /* 实际可承载容量A = 运行(或合同容量)x0.9[将运行容量或合同容量折算成容量]x85% @@ -70,16 +129,16 @@ public class BuildHeatingScene implements DntdModelI { /* 根据建筑面积计算出不同技术类型下所需要不同功率设备数据 */ - List> matchedDeviceGroupList = Scheme.calScheme(heatingArea, alternateDeviceList); + List> matchedDeviceGroupList = scheme.calScheme(heatingArea, alternateDeviceList); /* 替代后设备总功率C1 */ double C1 = 0.0; - if (originalDevInfo != null){ + if (originalDevInfo != null) { //若存在原设备信息,则根据建筑面积计算每个技术类型下需要的不同功率的设备的数量,然后将不同功率及对应的数量进行计算得出总功率C1,取最大 - C1 = CalC.getC1(matchedDeviceGroupList); + C1 = calC.getC1(matchedDeviceGroupList); } else { - C1 = C/2.5; + C1 = C / 2.5; } /* @@ -97,27 +156,15 @@ public class BuildHeatingScene implements DntdModelI { */ double costRatio = 0.2; double effRatio = 0.8; - /* - try{ - double costRatio1 = Double.parseDouble(jsonObject.get("costRatio").toString()); - double effRatio1 = Double.parseDouble(jsonObject.get("effRatio").toString()); - if(costRatio1 < 1 && costRatio1 + costRatio1 == 1){ - costRatio = costRatio1; - effRatio = effRatio1; - } - }catch (Exception e){ - e.printStackTrace(); - } - */ - List matchedDeviceList ; - Map listMap ; + List matchedDeviceList; + Map listMap; /* 根据具体容量与需量判断可使用的技术并计算评分 */ //计算不同细类下成本最小值与效率最大值 - Map maxEffMap = SchemeRating.getMaxEfficiencyGroupByDevSubType(alternateDeviceList); - Map minPrice = SchemeRating.getMinPriceGroupByDevSubType(matchedDeviceGroupList); + Map maxEffMap = schemeRating.getMaxEfficiencyGroupByDevSubType(alternateDeviceList); + Map minPrice = schemeRating.getMinPriceGroupByDevSubType(matchedDeviceGroupList); String remark = ""; if (D1 < A && A < D) { // 判断只能用热泵 @@ -125,24 +172,24 @@ public class BuildHeatingScene implements DntdModelI { matchedDeviceGroupList.forEach((matchedDevices -> { MatchedDevice matchedDevice = matchedDevices.get(0); String s = DeviceSubType.Cooling_Heating_Electric_Boiler.getDesc(); - if (!s.equals(matchedDevice.getDeviceHeatScene().getDevSubType())){ + if (!s.equals(matchedDevice.getDeviceHeatScene().getDevSubType())) { heatPumpDevList.add(matchedDevices); } })); - listMap = SchemeRating.getOptimalList(heatPumpDevList,costRatio,effRatio,maxEffMap,minPrice); - matchedDeviceList = SchemeRating.getOptimalScheme(listMap); + listMap = schemeRating.getOptimalList(heatPumpDevList, costRatio, effRatio, maxEffMap, minPrice); + matchedDeviceList = schemeRating.getOptimalScheme(listMap); } else { // 同时考虑热泵和电锅炉 - if ( A < D1){ + if (A < D1) { remark = "本方案存在扩容投资需求,扩容投资不计入初次投资费用"; } - listMap = SchemeRating.getOptimalList(matchedDeviceGroupList,costRatio,effRatio,maxEffMap,minPrice); - matchedDeviceList = SchemeRating.getOptimalScheme(listMap); + listMap = schemeRating.getOptimalList(matchedDeviceGroupList, costRatio, effRatio, maxEffMap, minPrice); + matchedDeviceList = schemeRating.getOptimalScheme(listMap); } List> maps = new ArrayList<>(); - listMap.forEach((k,v)->{ + listMap.forEach((k, v) -> { Map map = new HashMap<>(); map.put("rating", decimalFormat.format(v.getSchemeRating())); map.put("plan", v.getList()); @@ -155,27 +202,27 @@ public class BuildHeatingScene implements DntdModelI { 封装返回 */ JSONObject returnJsonObject = new JSONObject(); - Double startCost = 0.0; - Double runCost = 0.0; - Double allCost = 0.0; - Double calculateAnnualCarbon = 0.0; - Double laborFee1 = 0.0; - Double electric = 0.0; - List> deviceList = new ArrayList<>(); - for (MatchedDevice matchedDevice : matchedDeviceList){ + Double startCost = 0.0; + Double runCost = 0.0; + Double allCost = 0.0; + Double calculateAnnualCarbon = 0.0; + Double laborFee1 = 0.0; + Double electric = 0.0; + List> deviceList = new ArrayList<>(); + for (MatchedDevice matchedDevice : matchedDeviceList) { HashMap map = new HashMap<>(); - map.put("devSubType",matchedDevice.getDeviceHeatScene().getDevSubType()); - map.put("devTechType",matchedDevice.getDeviceHeatScene().getDevTechType()); - map.put("devCount",matchedDevice.getCount()); - map.put("devPrice",matchedDevice.getDeviceHeatScene().getDevPrice()); + map.put("devSubType", matchedDevice.getDeviceHeatScene().getDevSubType()); + map.put("devTechType", matchedDevice.getDeviceHeatScene().getDevTechType()); + map.put("devCount", matchedDevice.getCount()); + map.put("devPrice", matchedDevice.getDeviceHeatScene().getDevPrice()); deviceList.add(map); startCost = startCost + (matchedDevice.getCount() * matchedDevice.getDeviceHeatScene().getDevPrice()); - runCost = runCost + (BuildHeatingModel.getRunCost(matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPower(), days, matchedDevice.getDeviceHeatScene().getDevServiceLife(), matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost())); + runCost = runCost + (buildHeatingModel.getRunCost(matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPower(), days, matchedDevice.getDeviceHeatScene().getDevServiceLife(), matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost())); - allCost = allCost + (BuildHeatingModel.getYearCost(matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPrice(), matchedDevice.getDeviceHeatScene().getDevServiceLife(), matchedDevice.getDeviceHeatScene().getDevPower(), days, matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost())); + allCost = allCost + (buildHeatingModel.getYearCost(matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPrice(), matchedDevice.getDeviceHeatScene().getDevServiceLife(), matchedDevice.getDeviceHeatScene().getDevPower(), days, matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost())); - electric = electric + (BuildHeatingModel.getElectric(matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPower(), days)); + electric = electric + (buildHeatingModel.getElectric(matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPower(), days)); laborFee1 = laborFee1 + (matchedDevice.getCount() * matchedDevice.getDeviceHeatScene().getLaborCost() / matchedDevice.getDeviceHeatScene().getDevServiceLife()); @@ -186,32 +233,41 @@ public class BuildHeatingScene implements DntdModelI { Double energyPrice = 0.0; try { energyPrice = Double.parseDouble(buildInfo.get("energyPrice").toString()); - } catch (NullPointerException e){ - energyPrice = GetThisEnergyEmissions.getThisEnergyPrice((Integer) buildInfo.get("energyCode")); + } catch (Exception e) { + System.out.println("计算因子采用默认值"); + energyPrice = GetThisEnergyEmissions.getThisEnergyPrice(energyCode); } try { // 上年运行费用(元) lastYearFee = Double.parseDouble(buildInfo.get("lastYearFee").toString()); } catch (NullPointerException e) { - // e.printStackTrace(); - System.out.println("计算因子采用默认值"); previousYearEnergyUsage = Double.parseDouble(buildInfo.get("previousYearEnergyUsage").toString()); - lastYearFee = HeatBoilerModel.calLastYearFee(laborFee1, previousYearEnergyUsage, energyPrice); + lastYearFee = buildHeatingModel.calLastYearFee(laborFee1, previousYearEnergyUsage, energyPrice); + } catch (NumberFormatException nfe){ + nfe.printStackTrace(); + System.err.println("上年运行费用(元)为非数字,禁止传参空字符串"); } try { // 替代前年能源用量 previousYearEnergyUsage = Double.parseDouble(buildInfo.get("previousYearEnergyUsage").toString()); - } catch (NullPointerException e){ - lastYearFee = Double.parseDouble(buildInfo.get("lastYearFee").toString()); - previousYearEnergyUsage = lastYearFee / energyPrice; + } catch (NullPointerException e) { + try { + previousYearEnergyUsage = CalculateUtils.divide(lastYearFee, energyPrice); + } catch (ArithmeticException nfe){ + nfe.printStackTrace(); + System.err.println("数学错误,替代前原使用能源平均单价不可为0"); + } + } catch (NumberFormatException nfe){ + nfe.printStackTrace(); + System.err.println("替代前年能源用量为非数字,禁止传参空字符串"); } // 替代前上年原设备碳排放量 - double energyLastYearFactor = HeatBoilerModel.calLastYearFactor(previousYearEnergyUsage, GetThisEnergyEmissions.getThisEnergyEmission((Integer) buildInfo.get("energyCode"))); + double energyLastYearFactor = buildHeatingModel.calLastYearFactor(previousYearEnergyUsage, GetThisEnergyEmissions.getThisEnergyEmission(energyCode)); // 年减碳量 - calculateAnnualCarbon = HeatBoilerModel.calculateAnnualCarbonReduction(energyLastYearFactor, electric, EnergyEmissions.ELECTRIC.getCo2EmissionFactor()); + calculateAnnualCarbon = buildHeatingModel.calculateAnnualCarbonReduction(energyLastYearFactor, electric, EnergyEmissions.ELECTRIC.getCo2EmissionFactor()); //初次投资费用 returnJsonObject.set("startCost", decimalFormat.format(startCost)); @@ -222,23 +278,24 @@ public class BuildHeatingScene implements DntdModelI { //年总费用 returnJsonObject.set("yearCost", decimalFormat.format(allCost)); //年减碳量 - returnJsonObject.set("calculate", decimalFormat.format(calculateAnnualCarbon/1000)); + returnJsonObject.set("calculate", decimalFormat.format(calculateAnnualCarbon / 1000)); //替代电量 returnJsonObject.set("electric", decimalFormat.format(electric)); //备注 - returnJsonObject.set("remark",remark); + returnJsonObject.set("remark", remark); //封装需配置设备情况 - returnJsonObject.set("deviceList",deviceList); + returnJsonObject.set("deviceList", deviceList); //封装方案优势 - returnJsonObject.set("safety", BuildHeatingAdvantage.safety()); - returnJsonObject.set("economy", Advantage.economy(startCost, runCost, lastYearFee)); - returnJsonObject.set("intelligence", BuildHeatingAdvantage.intelligence()); - returnJsonObject.set("environment", BuildHeatingAdvantage.environment(Double.valueOf(decimalFormat.format(calculateAnnualCarbon/1000)))); + returnJsonObject.set("safety", advantage.safety()); + returnJsonObject.set("economy", advantage.economy(startCost, runCost, lastYearFee)); + returnJsonObject.set("intelligence", advantage.intelligence()); + returnJsonObject.set("environment", advantage.environment(Double.valueOf(decimalFormat.format(calculateAnnualCarbon / 1000)))); // 封装方案评分 // returnJsonObject.set("matchedDeviceList", maps); return returnJsonObject; } + } diff --git a/dntd-model-heatboiler/src/main/java/com/dky/calculate/CalC.java b/dntd-model-heatboiler/src/main/java/com/dky/calculate/CalC.java new file mode 100644 index 0000000..c53b37e --- /dev/null +++ b/dntd-model-heatboiler/src/main/java/com/dky/calculate/CalC.java @@ -0,0 +1,54 @@ +package com.dky.calculate; + + + +import com.dky.utils.result.MatchedDevice; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CalC { + + public static List> getC(List>>> list) { + List> maps = new ArrayList<>(); + list.parallelStream().forEach(stringListMap -> { + // 区分热泵、电锅炉 + stringListMap.forEach((k,v)->{ + // 循环遍历各个方案 + final Double[] maxPower = {0.0}; + v.parallelStream().forEach((plan)->{ + Double power = 0.0; + for (MatchedDevice device : plan){ + power = power + (device.getCount() * device.getDeviceHeatScene().getDevPower()) ; + } + if (power >= maxPower[0]){ + maxPower[0] = power; + } + }); + Map map = new HashMap<>(); + map.put(k, maxPower[0]); + maps.add(map); + }); + }); + return maps; + } + + public Double getC1(List> args) { + // 循环遍历各个方案 + final Double[] maxPower = {-100.0}; + args.parallelStream().forEach(plan -> { + Double power = 0.0; + for (MatchedDevice device : plan){ + power = power + (device.getCount() * device.getDeviceHeatScene().getDevPower()) ; + } + if (power >= maxPower[0]){ + maxPower[0] = power; + } + }); + return maxPower[0]; + } + + +} diff --git a/dntd-model-heatboiler/src/main/java/com/dky/calculate/HeatAdvantage.java b/dntd-model-heatboiler/src/main/java/com/dky/calculate/HeatAdvantage.java new file mode 100644 index 0000000..7124e29 --- /dev/null +++ b/dntd-model-heatboiler/src/main/java/com/dky/calculate/HeatAdvantage.java @@ -0,0 +1,42 @@ +package com.dky.calculate; + +import java.text.DecimalFormat; + +//方案优势 +public class HeatAdvantage { + + DecimalFormat decimalFormat = new DecimalFormat("#.00"); + + /** + * 经济性 + * @param firstInvestFee 初始投资金额 + * @param yearRunFee 年运行费用 + * @param lastYearFee 替代前上年运行费用 + * @return + */ + public String economy(Double firstInvestFee ,Double yearRunFee, Double lastYearFee){ + // 运行收益 = 上年运行费用(即原设备运行费用)- 今年运行费用 + Double hsq = Math.round((lastYearFee - yearRunFee) * 100.0)/100.0; + if (hsq <= 0){ + return "本技术方案中替代技术相对于原生产设备在经济性上优势不大,但从环保效益上具有较高的优势"; + } + // 投资回收期 = 初次投资费用/运行收益 + Double js = Math.round((firstInvestFee / hsq) * 100.0)/100.0; + return "本次改造投资回收期为"+js+"年,本改造方案相比较原技术节省年运行费用成本"+decimalFormat.format(hsq)+"元。"; + } + + // 智能性 + public String safety(){ + return "精准控温"; + } + + // 智能性 + public String intelligence() { + return "以电锅炉替代和实现精准控温。"; + } + + // 环保性 + public String environment(Double yearReduceCarbon) { + return "本次改造方案减排" + yearReduceCarbon + "吨"; + } +} diff --git a/dntd-model-heatboiler/src/main/java/com/dky/calculate/HeatBoilerModel.java b/dntd-model-heatboiler/src/main/java/com/dky/calculate/HeatBoilerModel.java index 4f55dfe..e31be80 100644 --- a/dntd-model-heatboiler/src/main/java/com/dky/calculate/HeatBoilerModel.java +++ b/dntd-model-heatboiler/src/main/java/com/dky/calculate/HeatBoilerModel.java @@ -7,12 +7,6 @@ import com.dky.utils.enums.EnergyPriceType; public class HeatBoilerModel { - // 标准煤转换系数:千克标准煤/千克 - private static final double coalConversionFactor = 0.7143; - // 电能转换到标准煤的系数:千克标准煤/千瓦时 - private static final double electricityConversionFactor = 0.1229; - // 标准煤转换到二氧化碳的系数:千克二氧化碳/千克标准煤 - private static final double carbonConversionFactor = 1.9003; /** * 计算初次投资费用 @@ -22,7 +16,7 @@ public class HeatBoilerModel { * @param d 热效率,后期从设备中获取 TODO * @return 初次投资费用 */ - public static double calculateInitialInvestment(HeatboilerSpec heatboilerSpec, Heatboiler heatboiler , OriginalDevice originalDevice,Double d) { + public double calculateInitialInvestment(HeatboilerSpec heatboilerSpec, Heatboiler heatboiler , OriginalDevice originalDevice,Double d) { // 计算电替代设备台数 = 供热设备功率(蒸吨)/(电替代设备功率*热效率) double substituteElectricityDevices = heatboiler.getHotDevicePower() / (heatboiler.getHotDevicePower() * d); @@ -41,7 +35,7 @@ public class HeatBoilerModel { * @param deviceAnnualOperationTime 电替代设备年运行时间 * @return 年运行费用 */ - public static double calculateAnnualOperatingCost(Double devicePower, Integer deviceCount, Double deviceSubstituteLaborCost, Integer deviceAnnualOperationTime) { + public double calculateAnnualOperatingCost(Double devicePower, Integer deviceCount, Double deviceSubstituteLaborCost, Integer deviceAnnualOperationTime) { // 电替代设备年耗电量=单台电替代设备的功率*电替代设备台数*电设备年运行时间 double annualElectricityConsumption = devicePower * deviceCount * deviceAnnualOperationTime; @@ -60,7 +54,7 @@ public class HeatBoilerModel { * @param deviceServiceLife 设备使用年限 * @return */ - public static double calculateAnnualTotalCost(Double devicePower, Integer deviceCount, Double deviceSubstituteLaborCost, Integer deviceAnnualOperationTime, Double devicePrice, Integer deviceServiceLife) { + public double calculateAnnualTotalCost(Double devicePower, Integer deviceCount, Double deviceSubstituteLaborCost, Integer deviceAnnualOperationTime, Double devicePrice, Integer deviceServiceLife) { //(电替代设备台数*单台电设备价格)/电替代设备的使用年限 double v = ((devicePrice * deviceCount) / deviceServiceLife); // 年总费用=(电替代设备台数*单台电设备价格)/电替代设备的使用年限 + 年运行费用 @@ -74,7 +68,7 @@ public class HeatBoilerModel { * @param electricEmission 电替代设备碳排放因子 * @return 年减碳量 */ - public static double calculateAnnualCarbonReduction(Double previousYearEnergyUsage, Double deviceElectric, Double electricEmission) { + public double calculateAnnualCarbonReduction(Double previousYearEnergyUsage, Double deviceElectric, Double electricEmission) { // 计算电替代设备年耗电量对应的标准煤量 double coalEquivalentFromElectricity = deviceElectric * electricEmission; @@ -89,7 +83,7 @@ public class HeatBoilerModel { * @param deviceAnnualOperationTime 单台电设备年运行时间 * @return */ - public static double calculateSubstituteElectricity(Double devicePower, Integer deviceCount, Integer deviceAnnualOperationTime) { + public double calculateSubstituteElectricity(Double devicePower, Integer deviceCount, Integer deviceAnnualOperationTime) { // 电替代设备年耗电量 = 电替代设备的功率 * 电替代设备台数 * 电设备年运行时间 return devicePower * deviceCount * deviceAnnualOperationTime; @@ -102,7 +96,7 @@ public class HeatBoilerModel { * @param energyPrice 平均能源单价 * @return */ - public static double calLastYearFee(Double laborCost, Double lastYearEnergyUse, Double energyPrice) { + public double calLastYearFee(Double laborCost, Double lastYearEnergyUse, Double energyPrice) { // 上年运行费用(即原设备运行费用)= 上年能源使用量 * 平均能源单价 + 上年人工成本 return energyPrice * lastYearEnergyUse + laborCost; @@ -114,7 +108,7 @@ public class HeatBoilerModel { * @param d 相关能源排放系数 * @return */ - public static double calLastYearFactor(Double lastYearEnergyUse , Double d) { + public double calLastYearFactor(Double lastYearEnergyUse , Double d) { return lastYearEnergyUse * d; } diff --git a/dntd-model-heatboiler/src/main/java/com/dky/calculate/HeatBoilerScheme.java b/dntd-model-heatboiler/src/main/java/com/dky/calculate/HeatBoilerScheme.java index 7e936c1..9af6d7a 100644 --- a/dntd-model-heatboiler/src/main/java/com/dky/calculate/HeatBoilerScheme.java +++ b/dntd-model-heatboiler/src/main/java/com/dky/calculate/HeatBoilerScheme.java @@ -11,7 +11,7 @@ import java.util.stream.Collectors; public class HeatBoilerScheme { - public static List> calScheme(Double heatEfficiency, List sysDeviceHeatSceneList) { + public List> calScheme(Double heatEfficiency, List sysDeviceHeatSceneList) { // 根据设备细类筛选出一个以设备细类为键,该细类下设备列表为值的Map Map> groupByDevSubTypeMap = sysDeviceHeatSceneList.stream() .collect(Collectors.groupingBy(SysDeviceHeatScene::getDevSubType)); @@ -32,7 +32,7 @@ public class HeatBoilerScheme { return planList; } - public static List calSchemeByTechType(Double heatEfficiency, List sysDeviceHeatSceneList) { + public List calSchemeByTechType(Double heatEfficiency, List sysDeviceHeatSceneList) { // 对技术类型下的设备list按照单台设备功率进行排序 sysDeviceHeatSceneList.sort((o1, o2) -> Double.compare(o2.getDevPower(), o1.getDevPower())); Double remainArea = heatEfficiency; diff --git a/dntd-model-heatboiler/src/main/java/com/dky/calculate/HeatSchemeRating.java b/dntd-model-heatboiler/src/main/java/com/dky/calculate/HeatSchemeRating.java new file mode 100644 index 0000000..ac17dcc --- /dev/null +++ b/dntd-model-heatboiler/src/main/java/com/dky/calculate/HeatSchemeRating.java @@ -0,0 +1,153 @@ +package com.dky.calculate; + + +import com.dky.entity.SchemeRatingRes; +import com.dky.utils.entity.SysDeviceHeatScene; +import com.dky.utils.result.MatchedDevice; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; + +public class HeatSchemeRating { + + /** + * 计算每一种方案的效率和成本评分 + * @param list + * @return + */ + public Map getOptimalList(List> list, Double costRatio, Double effRatio, Map maxEff, Map minPrice) { + + Map optimalMap = new HashMap<>(); + list.forEach(plan->{ + String devTechType = plan.get(0).getDeviceHeatScene().getDevTechType(); + AtomicReference rating = new AtomicReference<>(0.0); + String devSubType = plan.get(0).getDeviceHeatScene().getDevSubType(); + Double eff = 0.0; + Double cost = 0.0; + for (MatchedDevice device : plan) { + eff = device.getDeviceHeatScene().getHeatEfficiency(); + } + for (MatchedDevice device : plan) { + cost = cost + ((device.getCount() * device.getDeviceHeatScene().getDevPrice()) + (device.getCount()) * device.getDeviceHeatScene().getDevSubstituteLaborCost() * device.getDeviceHeatScene().getDevServiceLife()); + } + + double v1 = (maxEff.get(devSubType) - eff) / maxEff.get(devSubType); // 热效率占比计算 + double v = (cost - minPrice.get(devSubType)) / minPrice.get(devSubType); // 成本占比计算 + + // 3、(1-(选择对应设备细类的效率最大的效率值(效率最大值)-当前设备的效率值值)/效率最大值)*100*系数 +(1-(当前成本值-对应设备细类的成本最小值)/对应设备细类的成本最小值)*100*0.2。取最高得分。 + rating.set(((1 - v1) * 100 * effRatio) + ((1 - v) * 100 * costRatio)); + + System.out.println("当前方案成本 = " + cost + ",方案详情 = "); + for (MatchedDevice matchedDevice : plan){ + System.out.println(matchedDevice); + } + System.out.println("当前方案评分: " + rating.get() + "\n"); + + // 方案评分结果 + SchemeRatingRes schemeRatingRes = new SchemeRatingRes(plan, rating.get(), devTechType); + optimalMap.put(devTechType, schemeRatingRes); + + }); + return optimalMap; + } + + /** + * 获取最优评分的方案 + * @param map + * @return + */ + public List getOptimalScheme(Map map) { + + final AtomicReference[] rating = new AtomicReference[]{new AtomicReference<>(-100.0)}; + final List[] list = new List[]{new ArrayList<>()}; + map.forEach((k,v)->{ + if (v.getSchemeRating() > rating[0].get()) { + rating[0].set(v.getSchemeRating()); + list[0] = v.getList(); + } + }); + + return list[0]; + } + + /** + * 获取不同设备细类下的效率最大值 + * @param alternateDeviceList 可替代设备列表 + * @return 不同设备细类下的效率最大值map + */ + public Map getMaxEfficiencyGroupByDevSubType(List alternateDeviceList){ + Map map = new HashMap<>(); + alternateDeviceList.forEach(alternateDevice ->{ + String devSubType = alternateDevice.getDevSubType(); + Double v = map.get(devSubType); + if ( v == null){ + map.put(devSubType,alternateDevice.getHeatEfficiency()); + } else { + if( alternateDevice.getHeatEfficiency() > v){ + map.put(devSubType,alternateDevice.getHeatEfficiency()); + } + } + }); + return map; + } + + /** + * 获取不同设备细类下的成本最小值 + * @param alternateDeviceList 可替代设备列表 + * @return 不同设备细类下的成本最小值 + */ + public Map getMinPriceGroupByDevSubType(List> alternateDeviceList){ + Map map = new HashMap<>(); + alternateDeviceList.forEach(plan -> { + Double thisPlanCost = 0.0; + String devSubType = plan.get(0).getDeviceHeatScene().getDevSubType(); + for (MatchedDevice device : plan) { + thisPlanCost = thisPlanCost + ((device.getCount() * device.getDeviceHeatScene().getDevPrice()) + (device.getCount()) * device.getDeviceHeatScene().getDevSubstituteLaborCost() * device.getDeviceHeatScene().getDevServiceLife()); + } + + Double v = map.get(devSubType); + if ( v == null){ + map.put(devSubType, thisPlanCost); + } else { + if(thisPlanCost < v){ + map.put(devSubType, thisPlanCost); + } + } + }); + return map; + } + + + public List> getIndex(List> list) { + List> maps = new ArrayList<>(); + final Double[] index = {0.0, Double.MAX_VALUE}; + Map map = new HashMap<>(); + + list.parallelStream().forEach((plan) -> { + Double eff = 0.0; + Double cost = 0.0; + for (MatchedDevice device : plan) { + eff = device.getDeviceHeatScene().getHeatEfficiency(); + } + for (MatchedDevice device : plan) { + cost = cost + ((device.getCount() * device.getDeviceHeatScene().getDevPrice()) + (device.getCount()) * device.getDeviceHeatScene().getDevSubstituteLaborCost() * device.getDeviceHeatScene().getDevServiceLife()); + } + if (eff >= index[0]) { + index[0] = eff; + } + if (cost <= index[1]) { + index[1] = cost; + } + map.put(plan.get(0).getDeviceHeatScene().getDevSubType(), index); + maps.add(map); + }); + return maps; + } + + + + +} diff --git a/dntd-model-heatboiler/src/main/java/com/dky/entity/SchemeRatingRes.java b/dntd-model-heatboiler/src/main/java/com/dky/entity/SchemeRatingRes.java new file mode 100644 index 0000000..e20e920 --- /dev/null +++ b/dntd-model-heatboiler/src/main/java/com/dky/entity/SchemeRatingRes.java @@ -0,0 +1,47 @@ +package com.dky.entity; + + +import com.dky.utils.result.MatchedDevice; + +import java.util.List; + +public class SchemeRatingRes { + + List list; + + Double schemeRating; + + String planName; + + public SchemeRatingRes() { } + + public SchemeRatingRes(List list, Double schemeRating, String planName) { + this.list = list; + this.schemeRating = schemeRating; + this.planName = planName; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + + public Double getSchemeRating() { + return schemeRating; + } + + public void setSchemeRating(Double schemeRating) { + this.schemeRating = schemeRating; + } + + public String getPlanName() { + return planName; + } + + public void setPlanName(String planName) { + this.planName = planName; + } +} diff --git a/dntd-tool/src/main/java/com/dky/generate/HeatBoilerScene.java b/dntd-model-heatboiler/src/main/java/com/dky/generate/HeatBoilerScene.java similarity index 53% rename from dntd-tool/src/main/java/com/dky/generate/HeatBoilerScene.java rename to dntd-model-heatboiler/src/main/java/com/dky/generate/HeatBoilerScene.java index ca891fa..08d463a 100644 --- a/dntd-tool/src/main/java/com/dky/generate/HeatBoilerScene.java +++ b/dntd-model-heatboiler/src/main/java/com/dky/generate/HeatBoilerScene.java @@ -2,7 +2,9 @@ package com.dky.generate; import cn.hutool.json.JSONObject; import com.dky.calculate.*; +import com.dky.entity.SchemeRatingRes; import com.dky.modelI.DntdModelI; +import com.dky.utils.CalculateUtils; import com.dky.utils.GetTargetDeviceList; import com.dky.utils.GetThisEnergyEmissions; import com.dky.utils.entity.SysDeviceHeatScene; @@ -11,7 +13,10 @@ import com.dky.utils.enums.EnergyEmissions; import com.dky.utils.result.MatchedDevice; import java.text.DecimalFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class HeatBoilerScene implements DntdModelI { @@ -32,30 +37,77 @@ public class HeatBoilerScene implements DntdModelI { JSONObject heatUseNeedInfo = new JSONObject(); JSONObject originalDevInfo = new JSONObject(); + HeatBoilerScheme scheme = new HeatBoilerScheme(); + CalC calC = new CalC(); + HeatSchemeRating schemeRating = new HeatSchemeRating(); + HeatAdvantage advantage = new HeatAdvantage(); + HeatBoilerModel model = new HeatBoilerModel(); + + Double runCapacity = null; + Double lastYearNeed = null; + Double heatingNeedPower = null; + Integer energyCode = null; try { distInfo = (JSONObject) jsonObject.get("distInfo"); heatUseNeedInfo = (JSONObject) jsonObject.get("heatUseNeedInfo"); originalDevInfo = (JSONObject) jsonObject.get("originalDevInfo"); + // 出口温度(摄氏度) + Double thermometerValueOut = Double.parseDouble(heatUseNeedInfo.get("thermometerValueOut").toString()); } catch (Exception e) { e.printStackTrace(); } - // 运行容量 - Double runCapacity = Double.parseDouble(distInfo.get("runCapacity").toString()); - // 上年最大需量 - Double lastYearNeed = Double.parseDouble(distInfo.get("lastYearNeed").toString()); - // 供热需量设备功率(单位: kW)【 1蒸吨等于770KW 】 - Double heatingNeedPower = Double.parseDouble(heatUseNeedInfo.get("heatingNeedPower").toString()) * 770; - // 出口温度(摄氏度) - Double thermometerValueOut = Double.parseDouble(heatUseNeedInfo.get("thermometerValueOut").toString()); + try { + // 上年最大需量 + lastYearNeed = Double.parseDouble(distInfo.get("lastYearNeed").toString()); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素上年最大需量传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素上年最大需量为非数字,禁止传参空字符串"); + } + + try { + // 运行容量 + runCapacity = Double.parseDouble(distInfo.get("runCapacity").toString()); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素运行容量传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素运行容量为非数字,禁止传参空字符串"); + } + + try { + // 供热需量设备功率(单位: kW)【 1蒸吨等于770KW 】 + heatingNeedPower = Double.parseDouble(heatUseNeedInfo.get("heatingNeedPower").toString()) * 770; + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素供热需量设备功率传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素供热需量设备功率为非数字,禁止传参空字符串"); + } + + try { + // 替代前原能源类型编码 + energyCode = (Integer) originalDevInfo.get("energyCode"); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素替代前原能源类型编码传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素替代前原能源类型编码为非数字,禁止传参空字符串"); + } // 根据供热需量设备功率计算出不同技术类型下所需要不同功率设备数据 - List> matchedDeviceGroupList = HeatBoilerScheme.calScheme(heatingNeedPower, alternateDeviceList); + List> matchedDeviceGroupList = scheme.calScheme(heatingNeedPower, alternateDeviceList); // 实际可承载容量A = 运行(或合同容量)x0.9 [将运行容量或合同容量折算成容量] x85% double A = runCapacity * COEFFICIENT_1 * COEFFICIENT_2; // 根据供热需量设备功率计算每个技术类型下需要的不同功率的设备的数量,然后将不同功率及对应的数量进行计算得出总功率C1,取最大 - Double C1 = CalC.getC1(matchedDeviceGroupList); + Double C1 = calC.getC1(matchedDeviceGroupList); // 改造后最大需量 double D1 = lastYearNeed + C1; @@ -80,16 +132,16 @@ public class HeatBoilerScene implements DntdModelI { // 根据具体容量与需量判断可使用的技术并计算评分 // 计算不同细类下成本最小值与效率最大值 - Map maxEffMap = SchemeRating.getMaxEfficiencyGroupByDevSubType(alternateDeviceList); - Map minPrice = SchemeRating.getMinPriceGroupByDevSubType(matchedDeviceGroupList); + Map maxEffMap = schemeRating.getMaxEfficiencyGroupByDevSubType(alternateDeviceList); + Map minPrice = schemeRating.getMinPriceGroupByDevSubType(matchedDeviceGroupList); String remark = ""; // 同时考虑热泵和电锅炉 if (A < D1) { remark = "本方案存在扩容投资需求,扩容投资不计入初次投资费用"; } - listMap = SchemeRating.getOptimalList(matchedDeviceGroupList, costRatio, effRatio, maxEffMap, minPrice); - matchedDeviceList = SchemeRating.getOptimalScheme(listMap); + listMap = schemeRating.getOptimalList(matchedDeviceGroupList, costRatio, effRatio, maxEffMap, minPrice); + matchedDeviceList = schemeRating.getOptimalScheme(listMap); List> maps = new ArrayList<>(); listMap.forEach((k, v) -> { @@ -121,12 +173,12 @@ public class HeatBoilerScene implements DntdModelI { startCost = startCost + (matchedDevice.getCount() * matchedDevice.getDeviceHeatScene().getDevPrice()); - runCost = runCost + (HeatBoilerModel.calculateAnnualOperatingCost(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost(), matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime())); + runCost = runCost + (model.calculateAnnualOperatingCost(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost(), matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime())); - allCost = allCost + (HeatBoilerModel.calculateAnnualTotalCost(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost(), + allCost = allCost + (model.calculateAnnualTotalCost(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost(), matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime(), matchedDevice.getDeviceHeatScene().getDevPrice(), matchedDevice.getDeviceHeatScene().getDevServiceLife())); - electric = electric + (HeatBoilerModel.calculateSubstituteElectricity(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime())); + electric = electric + (model.calculateSubstituteElectricity(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime())); } @@ -147,30 +199,41 @@ public class HeatBoilerScene implements DntdModelI { try { energyPrice = Double.parseDouble(originalDevInfo.get("energyPrice").toString()); } catch (NullPointerException e){ - energyPrice = GetThisEnergyEmissions.getThisEnergyPrice((Integer) originalDevInfo.get("energyCode")); + System.out.println("计算因子采用默认值"); + energyPrice = GetThisEnergyEmissions.getThisEnergyPrice(energyCode); } try { // 替代前年能源用量 previousYearEnergyUsage = Double.parseDouble(originalDevInfo.get("previousYearEnergyUsage").toString()); } catch (NullPointerException e){ - lastYearFee = Double.parseDouble(originalDevInfo.get("lastYearFee").toString()); - previousYearEnergyUsage = lastYearFee / energyPrice; + try { + lastYearFee = Double.parseDouble(originalDevInfo.get("lastYearFee").toString()); + previousYearEnergyUsage = CalculateUtils.divide(lastYearFee, energyPrice); + } catch (ArithmeticException nfe){ + nfe.printStackTrace(); + System.err.println("数学错误,替代前原使用能源平均单价不可为0"); + } catch (NullPointerException npe){ + System.err.println("替代前年能源使用量和上年运行费用都为空"); + } + } catch (NumberFormatException nfe){ + nfe.printStackTrace(); + System.err.println("替代前年能源用量为非数字,禁止传参空字符串"); } try { // 上年运行费用(元) lastYearFee = Double.parseDouble(originalDevInfo.get("lastYearFee").toString()); } catch (NullPointerException e) { - // e.printStackTrace(); - System.out.println("计算因子采用默认值"); - previousYearEnergyUsage = Double.parseDouble(originalDevInfo.get("previousYearEnergyUsage").toString()); - lastYearFee = HeatBoilerModel.calLastYearFee(0.0, previousYearEnergyUsage, energyPrice); + lastYearFee = model.calLastYearFee(0.0, previousYearEnergyUsage, energyPrice); + } catch (NumberFormatException nfe){ + nfe.printStackTrace(); + System.err.println("上年运行费用(元)为非数字,禁止传参空字符串"); } // 替代前上年原设备碳排放量 - double energyLastYearFactor = HeatBoilerModel.calLastYearFactor(previousYearEnergyUsage, GetThisEnergyEmissions.getThisEnergyEmission((Integer) originalDevInfo.get("energyCode"))); + double energyLastYearFactor = model.calLastYearFactor(previousYearEnergyUsage, GetThisEnergyEmissions.getThisEnergyEmission(energyCode)); // 年减碳量 - calculateAnnualCarbon = HeatBoilerModel.calculateAnnualCarbonReduction(energyLastYearFactor, electric, EnergyEmissions.ELECTRIC.getCo2EmissionFactor()); + calculateAnnualCarbon = model.calculateAnnualCarbonReduction(energyLastYearFactor, electric, EnergyEmissions.ELECTRIC.getCo2EmissionFactor()); returnJsonObject.set("calculate", decimalFormat.format(calculateAnnualCarbon / 1000)); @@ -182,10 +245,10 @@ public class HeatBoilerScene implements DntdModelI { returnJsonObject.set("deviceList", deviceList); //封装方案优势 - returnJsonObject.set("safety", BuildHeatingAdvantage.safety()); - returnJsonObject.set("economy", Advantage.economy(startCost, runCost, lastYearFee)); - returnJsonObject.set("intelligence", BuildHeatingAdvantage.intelligence()); - returnJsonObject.set("environment", BuildHeatingAdvantage.environment(Double.valueOf(decimalFormat.format(calculateAnnualCarbon / 1000)))); + returnJsonObject.set("safety", advantage.safety()); + returnJsonObject.set("economy", advantage.economy(startCost, runCost, lastYearFee)); + returnJsonObject.set("intelligence", advantage.intelligence()); + returnJsonObject.set("environment", advantage.environment(Double.valueOf(decimalFormat.format(calculateAnnualCarbon / 1000)))); // 封装方案评分 // returnJsonObject.set("matchedDeviceList", maps); diff --git a/dntd-model-heatboiler/src/main/java/com/dky/calculate/Advantage.java b/dntd-model-kitchencooking/src/main/java/com/dky/calculate/Advantage.java similarity index 77% rename from dntd-model-heatboiler/src/main/java/com/dky/calculate/Advantage.java rename to dntd-model-kitchencooking/src/main/java/com/dky/calculate/Advantage.java index 96a30bf..814502a 100644 --- a/dntd-model-heatboiler/src/main/java/com/dky/calculate/Advantage.java +++ b/dntd-model-kitchencooking/src/main/java/com/dky/calculate/Advantage.java @@ -5,12 +5,7 @@ import java.text.DecimalFormat; //方案优势 public class Advantage { - static DecimalFormat decimalFormat = new DecimalFormat("#.00"); - - //安全性 - public String safety(){ - return "无"; - } + DecimalFormat decimalFormat = new DecimalFormat("#.00"); /** * 经济性 @@ -19,7 +14,7 @@ public class Advantage { * @param lastYearFee 替代前上年运行费用 * @return */ - public static String economy(Double firstInvestFee ,Double yearRunFee, Double lastYearFee){ + public String economy(Double firstInvestFee ,Double yearRunFee, Double lastYearFee){ // 运行收益 = 上年运行费用(即原设备运行费用)- 今年运行费用 Double hsq = Math.round((lastYearFee - yearRunFee) * 100.0)/100.0; if (hsq <= 0){ @@ -29,13 +24,19 @@ public class Advantage { Double js = Math.round((firstInvestFee / hsq) * 100.0)/100.0; return "本次改造投资回收期为"+js+"年,本改造方案相比较原技术节省年运行费用成本"+decimalFormat.format(hsq)+"元。"; } + + // 智能性 + public String safety(){ + return "精准控温"; + } + // 智能性 - public static String intelligence() { + public String intelligence() { return "以电锅炉替代和实现精准控温。"; } // 环保性 - public static String environment(Double yearReduceCarbon) { + public String environment(Double yearReduceCarbon) { return "本次改造方案减排" + yearReduceCarbon + "吨"; } } diff --git a/dntd-model-kitchencooking/src/main/java/com/dky/calculate/KitchenCookModel.java b/dntd-model-kitchencooking/src/main/java/com/dky/calculate/KitchenCookModel.java index 5637505..64fdfd8 100644 --- a/dntd-model-kitchencooking/src/main/java/com/dky/calculate/KitchenCookModel.java +++ b/dntd-model-kitchencooking/src/main/java/com/dky/calculate/KitchenCookModel.java @@ -5,12 +5,6 @@ import com.dky.utils.enums.EnergyPriceType; public class KitchenCookModel { - private static final double ELECTIRC_PRICE_KILOWATT_HOUR = EnergyPriceType.Residential_Electric_Price.getPrice(); // 居民平均电价(0.55元/千瓦时) - private static final double COAL_PRICE_PER_KILOGRAM = 0.9; // 煤炭的平均价格,单位:元/千克 - private static final double STANDARD_COAL_CONVERSION_FACTOR = 0.7143; // 千克标准煤/千克 - private static final double CO2_CONVERSION_FACTOR = 1.9003; // 千克二氧化碳/千克 - private static final double ELECTRICITY_SUBSTITUTION_CONVERSION_FACTOR = 0.1229; // 千克标准煤/千瓦时 - /** * 计算电厨炊年耗电量 * @param powerPerUnit 设备功率 @@ -30,8 +24,8 @@ public class KitchenCookModel { * @param laborCostForReplacement 电替代设备人工费用成本 * @return 电厨炊年耗电量 *平均电价(0.55元/千瓦时) + 电替代设备人工费用成本 */ - public static double calculateAnnualOperatingCost(double powerPerUnit, int numberOfUnits, int annualOperatingHours, double laborCostForReplacement) { - return calculateAnnualElectricityConsumption(powerPerUnit, numberOfUnits, annualOperatingHours) * ELECTIRC_PRICE_KILOWATT_HOUR + laborCostForReplacement; + public double calculateAnnualOperatingCost(double powerPerUnit, int numberOfUnits, int annualOperatingHours, double laborCostForReplacement) { + return calculateAnnualElectricityConsumption(powerPerUnit, numberOfUnits, annualOperatingHours) * EnergyPriceType.Residential_Electric_Price.getPrice() + laborCostForReplacement; } /** @@ -44,27 +38,49 @@ public class KitchenCookModel { * @param laborCostForReplacement 电替代设备人工费用成本 * @return (电厨炊设备台数 *单台电设备价格)/电厨炊的使用年限 + 年运行费用 */ - public static double calculateTotalAnnualCost(int numberOfUnits, double pricePerUnit, int usefulLifeYears, double powerPerUnit, int annualOperatingHours, double laborCostForReplacement) { + public double calculateTotalAnnualCost(int numberOfUnits, double pricePerUnit, int usefulLifeYears, double powerPerUnit, int annualOperatingHours, double laborCostForReplacement) { double initialCost = numberOfUnits * pricePerUnit; double depreciationCost = initialCost / usefulLifeYears; return depreciationCost + calculateAnnualOperatingCost(powerPerUnit, numberOfUnits, annualOperatingHours, laborCostForReplacement); } + /** + * 计算原设备上年运行费用 + * + * @param laborCost 人工成本 + * @param lastYearEnergyUse 替代前年能源使用量 + * @param energyPrice 平均能源单价 + * @return + */ + public double calLastYearFee(Double laborCost, Double lastYearEnergyUse, Double energyPrice) { + // 上年运行费用(即原设备运行费用)= 上年能源使用量 * 平均能源单价 + 上年人工成本 + return energyPrice * lastYearEnergyUse + laborCost; + } + + /** + * 计算原设备年排碳量 + * + * @param lastYearEnergyUse 替代前年能源使用量 + * @param d 相关能源排放系数 + * @return + */ + public double calLastYearFactor(Double lastYearEnergyUse, Double d) { + return lastYearEnergyUse * d; + } + /** * 计算年减碳量 - * @param lastYearFee 上年运行费用 - * @param laborCostForOriginalDevice 原设备人工费用 - * @param annualElectricityConsumption 电替代设备年耗电量 - * @return 年减碳量=[(上年运行费用-原设备的人工费用)/煤炭平均价格(0.9元/千克)*0.7143千克标准煤/千克-电替代设备年耗电量*0.1229千克标准煤/千瓦时]*1.9003千克二氧化碳/千克 + * @param previousYearEnergyUsage 替代前原设备碳排放量 + * @param deviceElectric 电替代耗电量 + * @param electricEmission 电替代设备碳排放因子 + * @return 年减碳量 */ - public static double calculateAnnualCarbonReduction(double lastYearFee, double laborCostForOriginalDevice, double annualElectricityConsumption) { - // (上年运行费用-原设备的人工费用)/煤炭平均价格(0.9元/千克)*0.7143千克标准煤/千克 - double coalEquivalentFromPreviousYear = (lastYearFee - laborCostForOriginalDevice) / COAL_PRICE_PER_KILOGRAM * STANDARD_COAL_CONVERSION_FACTOR; - // 电替代设备年耗电量 * 0.1229千克标准煤 - double electricityEquivalent = annualElectricityConsumption * ELECTRICITY_SUBSTITUTION_CONVERSION_FACTOR; - // (上年运行费用-原设备的人工费用)/煤炭平均价格(0.9元/千克)*0.7143千克标准煤/千克-电替代设备年耗电量*0.1229千克标准煤/千瓦时 - double netReductionInCoalEquivalent = coalEquivalentFromPreviousYear - electricityEquivalent; - return netReductionInCoalEquivalent * CO2_CONVERSION_FACTOR; + public double calculateAnnualCarbonReduction(Double previousYearEnergyUsage, Double deviceElectric, Double electricEmission) { + // 计算电替代设备年耗电量对应的标准煤量 + double coalEquivalentFromElectricity = deviceElectric * electricEmission; + + // 计算年减碳量 + return previousYearEnergyUsage - coalEquivalentFromElectricity; } } diff --git a/dntd-model-kitchencooking/src/main/java/com/dky/calculate/KitchenCookScheme.java b/dntd-model-kitchencooking/src/main/java/com/dky/calculate/KitchenCookScheme.java index a40d41e..4c6b729 100644 --- a/dntd-model-kitchencooking/src/main/java/com/dky/calculate/KitchenCookScheme.java +++ b/dntd-model-kitchencooking/src/main/java/com/dky/calculate/KitchenCookScheme.java @@ -9,7 +9,7 @@ import java.util.stream.Collectors; public class KitchenCookScheme { - public static List getCookDevices(Integer peopleNum, List sysDeviceHeatSceneList) { + public List getCookDevices(Integer peopleNum, List sysDeviceHeatSceneList) { // 根据用餐人数获取烹饪设备类型最少推荐使用人数 Integer cookDeviceType = getCookDeviceType(peopleNum, sysDeviceHeatSceneList); @@ -24,7 +24,7 @@ public class KitchenCookScheme { return list; } - public static Integer getCookDeviceType(Integer peopleNum, List sysDeviceHeatSceneList) { + public Integer getCookDeviceType(Integer peopleNum, List sysDeviceHeatSceneList) { // 使用流对sysDeviceHeatSceneList进行处理,首先收集到一个TreeSet中,TreeSet会根据SysDeviceHeatScene的recomMinPeopleNum属性进行排序, // 然后将TreeSet转换为ArrayList。这样做的目的是为了确保后续处理时集合中的元素是按照recomMinPeopleNum升序排列的。 ArrayList collect = sysDeviceHeatSceneList.stream().collect( diff --git a/dntd-tool/src/main/java/com/dky/generate/KitchenCookScene.java b/dntd-model-kitchencooking/src/main/java/com/dky/generate/KitchenCookScene.java similarity index 55% rename from dntd-tool/src/main/java/com/dky/generate/KitchenCookScene.java rename to dntd-model-kitchencooking/src/main/java/com/dky/generate/KitchenCookScene.java index edd83fc..ec3efbf 100644 --- a/dntd-tool/src/main/java/com/dky/generate/KitchenCookScene.java +++ b/dntd-model-kitchencooking/src/main/java/com/dky/generate/KitchenCookScene.java @@ -1,8 +1,11 @@ package com.dky.generate; import cn.hutool.json.JSONObject; -import com.dky.calculate.*; +import com.dky.calculate.Advantage; +import com.dky.calculate.KitchenCookModel; +import com.dky.calculate.KitchenCookScheme; import com.dky.modelI.DntdModelI; +import com.dky.utils.CalculateUtils; import com.dky.utils.GetTargetDeviceList; import com.dky.utils.GetThisEnergyEmissions; import com.dky.utils.entity.SysDeviceHeatScene; @@ -29,6 +32,14 @@ public class KitchenCookScene implements DntdModelI { JSONObject distInfo = new JSONObject(); JSONObject originalDevInfo = new JSONObject(); + Double runCapacity = null; + Double lastYearNeed = null; + Integer peopleNum = null; + Integer energyCode = null; + + KitchenCookScheme scheme = new KitchenCookScheme(); + KitchenCookModel model = new KitchenCookModel(); + Advantage advantage = new Advantage(); try{ distInfo = (JSONObject) jsonObject.get("distInfo"); @@ -37,12 +48,50 @@ public class KitchenCookScene implements DntdModelI { e.printStackTrace(); } - // 运行容量 - Double runCapacity = Double.parseDouble(distInfo.get("runCapacity").toString()); - // 上年最大需量 - Double lastYearNeed = Double.parseDouble(distInfo.get("lastYearNeed").toString()); - // 人数 - Integer peopleNum = Integer.parseInt(jsonObject.get("peopleNum").toString()); + try { + // 上年最大需量 + lastYearNeed = Double.parseDouble(distInfo.get("lastYearNeed").toString()); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素上年最大需量传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素上年最大需量为非数字,禁止传参空字符串"); + } + + try { + // 运行容量 + runCapacity = Double.parseDouble(distInfo.get("runCapacity").toString()); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素运行容量传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素运行容量为非数字,禁止传参空字符串"); + } + + try { + // 人数 + peopleNum = Integer.parseInt(jsonObject.get("peopleNum").toString()); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素人数为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素人数为非数字,禁止传参空字符串"); + } + + try { + // 替代前原能源类型编码 + energyCode = (Integer) originalDevInfo.get("energyCode"); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素替代前原能源类型编码传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素替代前原能源类型编码为非数字,禁止传参空字符串"); + } + /* 实际可承载容量A = 运行(或合同容量)x0.9[将运行容量或合同容量折算成容量]x85% @@ -52,7 +101,7 @@ public class KitchenCookScene implements DntdModelI { /* 根据人数计算出不同技术类型下所需要不同功率设备数据 */ - List cookDevices = KitchenCookScheme.getCookDevices(peopleNum, alternateDeviceList); + List cookDevices = scheme.getCookDevices(peopleNum, alternateDeviceList); /* 替代后设备总功率C1 */ @@ -94,9 +143,9 @@ public class KitchenCookScene implements DntdModelI { startCost = startCost + (matchedDevice.getCount() * matchedDevice.getDeviceHeatScene().getDevPrice()); - runCost = runCost + (KitchenCookModel.calculateAnnualOperatingCost(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime(), matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost())); + runCost = runCost + (model.calculateAnnualOperatingCost(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime(), matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost())); - allCost = allCost + (KitchenCookModel.calculateTotalAnnualCost(matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPrice(), matchedDevice.getDeviceHeatScene().getDevServiceLife(), + allCost = allCost + (model.calculateTotalAnnualCost(matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPrice(), matchedDevice.getDeviceHeatScene().getDevServiceLife(), matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime(), matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost())); electric = electric + (KitchenCookModel.calculateAnnualElectricityConsumption(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime())); @@ -108,10 +157,10 @@ public class KitchenCookScene implements DntdModelI { Double previousYearEnergyUsage = 1.0; Double lastYearFee = 0.0; Double energyPrice = 0.0; - Integer energyCode = (Integer) originalDevInfo.get("energyCode"); try { energyPrice = Double.parseDouble(originalDevInfo.get("energyPrice").toString()); - } catch (NullPointerException e){ + } catch (Exception e) { + System.out.println("计算因子采用默认值"); energyPrice = GetThisEnergyEmissions.getThisEnergyPrice(energyCode); } @@ -119,23 +168,32 @@ public class KitchenCookScene implements DntdModelI { // 上年运行费用(元) lastYearFee = Double.parseDouble(originalDevInfo.get("lastYearFee").toString()); } catch (NullPointerException e) { - // e.printStackTrace(); - System.out.println("计算因子采用默认值"); previousYearEnergyUsage = Double.parseDouble(originalDevInfo.get("previousYearEnergyUsage").toString()); - lastYearFee = HeatBoilerModel.calLastYearFee(laborCost, previousYearEnergyUsage, energyPrice); + lastYearFee = model.calLastYearFee(laborCost, previousYearEnergyUsage, energyPrice); + } catch (NumberFormatException nfe){ + nfe.printStackTrace(); + System.err.println("上年运行费用(元)为非数字,禁止传参空字符串"); } try { // 替代前年能源用量 previousYearEnergyUsage = Double.parseDouble(originalDevInfo.get("previousYearEnergyUsage").toString()); - } catch (NullPointerException e){ - previousYearEnergyUsage = lastYearFee / energyPrice; + } catch (NullPointerException e) { + try { + previousYearEnergyUsage = CalculateUtils.divide(lastYearFee, energyPrice); + } catch (ArithmeticException nfe){ + nfe.printStackTrace(); + System.err.println("数学错误,替代前原使用能源平均单价不可为0"); + } + } catch (NumberFormatException nfe){ + nfe.printStackTrace(); + System.err.println("替代前年能源用量为非数字,禁止传参空字符串"); } // 替代前上年原设备碳排放量 - double energyLastYearFactor = HeatBoilerModel.calLastYearFactor(previousYearEnergyUsage, GetThisEnergyEmissions.getThisEnergyEmission(energyCode)); + double energyLastYearFactor = model.calLastYearFactor(previousYearEnergyUsage, GetThisEnergyEmissions.getThisEnergyEmission(energyCode)); // 年减碳量 - calculateAnnualCarbon = HeatBoilerModel.calculateAnnualCarbonReduction(energyLastYearFactor, electric, EnergyEmissions.ELECTRIC.getCo2EmissionFactor()); + calculateAnnualCarbon = model.calculateAnnualCarbonReduction(energyLastYearFactor, electric, EnergyEmissions.ELECTRIC.getCo2EmissionFactor()); //初次投资费用 @@ -156,10 +214,10 @@ public class KitchenCookScene implements DntdModelI { returnJsonObject.set("deviceList",deviceList); //封装方案优势 - returnJsonObject.set("safety", BuildHeatingAdvantage.safety()); - returnJsonObject.set("economy", Advantage.economy(startCost, runCost, lastYearFee)); - returnJsonObject.set("intelligence", BuildHeatingAdvantage.intelligence()); - returnJsonObject.set("environment", BuildHeatingAdvantage.environment(Double.valueOf(decimalFormat.format(calculateAnnualCarbon/1000)))); + returnJsonObject.set("safety", advantage.safety()); + returnJsonObject.set("economy", advantage.economy(startCost, runCost, lastYearFee)); + returnJsonObject.set("intelligence", advantage.intelligence()); + returnJsonObject.set("environment", advantage.environment(Double.valueOf(decimalFormat.format(calculateAnnualCarbon/1000)))); return returnJsonObject; diff --git a/dntd-model-materialkiln/src/main/java/com/dky/calculate/MaterialAdvantage.java b/dntd-model-materialkiln/src/main/java/com/dky/calculate/MaterialAdvantage.java new file mode 100644 index 0000000..6f11742 --- /dev/null +++ b/dntd-model-materialkiln/src/main/java/com/dky/calculate/MaterialAdvantage.java @@ -0,0 +1,42 @@ +package com.dky.calculate; + +import java.text.DecimalFormat; + +//方案优势 +public class MaterialAdvantage { + + DecimalFormat decimalFormat = new DecimalFormat("#.00"); + + /** + * 经济性 + * @param firstInvestFee 初始投资金额 + * @param yearRunFee 年运行费用 + * @param lastYearFee 替代前上年运行费用 + * @return + */ + public String economy(Double firstInvestFee ,Double yearRunFee, Double lastYearFee){ + // 运行收益 = 上年运行费用(即原设备运行费用)- 今年运行费用 + Double hsq = Math.round((lastYearFee - yearRunFee) * 100.0)/100.0; + if (hsq <= 0){ + return "本技术方案中替代技术相对于原生产设备在经济性上优势不大,但从环保效益上具有较高的优势"; + } + // 投资回收期 = 初次投资费用/运行收益 + Double js = Math.round((firstInvestFee / hsq) * 100.0)/100.0; + return "本次改造投资回收期为"+js+"年,本改造方案相比较原技术节省年运行费用成本"+decimalFormat.format(hsq)+"元。"; + } + + // 智能性 + public String safety(){ + return "精准控温"; + } + + // 智能性 + public String intelligence() { + return "以电锅炉替代和实现精准控温。"; + } + + // 环保性 + public String environment(Double yearReduceCarbon) { + return "本次改造方案减排" + yearReduceCarbon + "吨"; + } +} diff --git a/dntd-model-materialkiln/src/main/java/com/dky/calculate/MaterialKilnModel.java b/dntd-model-materialkiln/src/main/java/com/dky/calculate/MaterialKilnModel.java index 809a608..5f8d163 100644 --- a/dntd-model-materialkiln/src/main/java/com/dky/calculate/MaterialKilnModel.java +++ b/dntd-model-materialkiln/src/main/java/com/dky/calculate/MaterialKilnModel.java @@ -2,15 +2,18 @@ package com.dky.calculate; import com.dky.utils.enums.EnergyPriceType; +import com.dky.utils.result.MatchedDevice; + +import java.util.List; public class MaterialKilnModel { // 标准煤转换系数:千克标准煤/千克 - private static final double coalConversionFactor = 0.7143; + private final double coalConversionFactor = 0.7143; // 电能转换到标准煤的系数:千克标准煤/千瓦时 - private static final double electricityConversionFactor = 0.1229; + private final double electricityConversionFactor = 0.1229; // 标准煤转换到二氧化碳的系数:千克二氧化碳/千克标准煤 - private static final double carbonConversionFactor = 1.9003; + private final double carbonConversionFactor = 1.9003; /** * 计算初次投资费用 @@ -23,7 +26,7 @@ public class MaterialKilnModel { * @param singleEquipmentPrice 单台电设备价格 * @return 包含计算结果的对象 */ - public static Double calculateProduction( + public Double calculateProduction( Double productDensity, Double furnaceWorkingVolume, Double expectedAnnualOutput, @@ -43,6 +46,34 @@ public class MaterialKilnModel { } + public Double getC1(List> args) { + // 循环遍历各个方案 + final Double[] maxPower = {-100.0}; + args.parallelStream().forEach(plan -> { + Double power = 0.0; + for (MatchedDevice device : plan) { + power = power + (device.getCount() * device.getDeviceHeatScene().getDevPower()); + } + if (power >= maxPower[0]) { + maxPower[0] = power; + } + }); + return maxPower[0]; + } + + /** + * 计算原设备上年运行费用 + * + * @param laborCost 人工成本 + * @param lastYearEnergyUse 替代前年能源使用量 + * @param energyPrice 平均能源单价 + * @return + */ + public double calLastYearFee(Double laborCost, Double lastYearEnergyUse, Double energyPrice) { + // 上年运行费用(即原设备运行费用)= 上年能源使用量 * 平均能源单价 + 上年人工成本 + return energyPrice * lastYearEnergyUse + laborCost; + } + /** * 计算年运行费用 @@ -53,7 +84,7 @@ public class MaterialKilnModel { * @param deviceAnnualOperationTime 电替代设备年运行时间 * @return 年运行费用 */ - public static double calculateAnnualOperatingCost(Double devicePower, Integer deviceCount, Double deviceSubstituteLaborCost, Integer deviceAnnualOperationTime) { + public double calculateAnnualOperatingCost(Double devicePower, Integer deviceCount, Double deviceSubstituteLaborCost, Integer deviceAnnualOperationTime) { // 电替代设备年耗电量=单台电替代设备的功率*电替代设备台数*电设备年运行时间 double annualElectricityConsumption = devicePower * deviceCount * deviceAnnualOperationTime; @@ -73,7 +104,7 @@ public class MaterialKilnModel { * @param deviceServiceLife 设备使用年限 * @return */ - public static double calculateAnnualTotalCost(Double devicePower, Integer deviceCount, Double deviceSubstituteLaborCost, Integer deviceAnnualOperationTime, Double devicePrice, Integer deviceServiceLife) { + public double calculateAnnualTotalCost(Double devicePower, Integer deviceCount, Double deviceSubstituteLaborCost, Integer deviceAnnualOperationTime, Double devicePrice, Integer deviceServiceLife) { //(电替代设备台数*单台电设备价格)/电替代设备的使用年限 double v = ((devicePrice * deviceCount) / deviceServiceLife); // 年总费用 =(电替代设备台数*单台电设备价格)/电替代设备的使用年限 + 年运行费用 @@ -81,30 +112,18 @@ public class MaterialKilnModel { } /** - * 计算年减碳量。 - * - * @param previousYearOperatingCost 上年运行费用 - * @param originalEquipmentLaborCost 原设备的人工费用 - * @param electricitySubstitutionAnnualConsumption 电替代设备年耗电量 + * 计算年减碳量 + * @param previousYearEnergyUsage 替代前原设备碳排放量 + * @param deviceElectric 电替代耗电量 + * @param electricEmission 电替代设备碳排放因子 * @return 年减碳量 */ - public static double calculateAnnualCarbonReduction( - Double previousYearOperatingCost, - Double originalEquipmentLaborCost, - Double electricitySubstitutionAnnualConsumption - ) { - // 计算节约的煤炭量(转换为标准煤)=(上年运行费用-原设备的人工费用)/煤炭平均价格(0.9元/千克)*0.7143千克标准煤/千克 - double savedCoalInStandardCoal = (previousYearOperatingCost - originalEquipmentLaborCost) / - EnergyPriceType.Coal_Price_Per_Kilogram.getPrice() * coalConversionFactor; - - // 计算电替代设备消耗的电量转换为标准煤的量 - double electricityInStandardCoal = electricitySubstitutionAnnualConsumption * electricityConversionFactor; - - // 计算总的节约的标准煤量 - double totalSavedStandardCoal = savedCoalInStandardCoal - electricityInStandardCoal; + public double calculateAnnualCarbonReduction(Double previousYearEnergyUsage, Double deviceElectric, Double electricEmission) { + // 计算电替代设备年耗电量对应的标准煤量 + double coalEquivalentFromElectricity = deviceElectric * electricEmission; // 计算年减碳量 - return totalSavedStandardCoal * carbonConversionFactor; + return previousYearEnergyUsage - coalEquivalentFromElectricity; } /** @@ -115,12 +134,21 @@ public class MaterialKilnModel { * @param deviceAnnualOperationTime 单台电设备年运行时间 * @return */ - public static double calculateSubstituteElectricity(Double devicePower, Integer deviceCount, Integer deviceAnnualOperationTime) { + public double calculateSubstituteElectricity(Double devicePower, Integer deviceCount, Integer deviceAnnualOperationTime) { // 电替代设备年耗电量 = 电替代设备的功率 * 电替代设备台数 * 电设备年运行时间 return devicePower * deviceCount * deviceAnnualOperationTime; } - + /** + * 计算原设备年排碳量 + * + * @param lastYearEnergyUse 替代前年能源使用量 + * @param d 相关能源排放系数 + * @return + */ + public double calLastYearFactor(Double lastYearEnergyUse, Double d) { + return lastYearEnergyUse * d; + } } diff --git a/dntd-model-materialkiln/src/main/java/com/dky/generate/MaterialKilnScene.java b/dntd-model-materialkiln/src/main/java/com/dky/generate/MaterialKilnScene.java new file mode 100644 index 0000000..9a61025 --- /dev/null +++ b/dntd-model-materialkiln/src/main/java/com/dky/generate/MaterialKilnScene.java @@ -0,0 +1,248 @@ +package com.dky.generate; + +import cn.hutool.json.JSONObject; +import com.dky.calculate.MaterialAdvantage; +import com.dky.calculate.MaterialKilnModel; +import com.dky.calculate.MaterialKilnScheme; +import com.dky.modelI.DntdModelI; +import com.dky.utils.CalculateUtils; +import com.dky.utils.GetTargetDeviceList; +import com.dky.utils.GetThisEnergyEmissions; +import com.dky.utils.entity.SysDeviceHeatScene; +import com.dky.utils.enums.DeviceSubType; +import com.dky.utils.enums.EnergyEmissions; +import com.dky.utils.result.MatchedDevice; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +public class MaterialKilnScene implements DntdModelI { + + DecimalFormat decimalFormat = new DecimalFormat("#.00"); + + // 首先A=由运行/合同容量折合成kW(x0.9)x85%, + static final Double COEFFICIENT_1 = 0.9; + static final Double COEFFICIENT_2 = 0.85; + + + @Override + public JSONObject createReport(JSONObject jsonObject, List list) { + List list1 = GetTargetDeviceList.main(DeviceSubType.Material_Kiln.getDesc(), list); + List list2 = GetTargetDeviceList.main(DeviceSubType.Metal_Kiln.getDesc(), list); + List alternateDeviceList = new ArrayList<>(list1); + alternateDeviceList.addAll(list2); + + MaterialKilnModel model = new MaterialKilnModel(); + MaterialAdvantage advantage = new MaterialAdvantage(); + + JSONObject distInfo = new JSONObject(); + JSONObject heatUseNeedInfo = new JSONObject(); + JSONObject originalDevInfo = new JSONObject(); + + try { + distInfo = (JSONObject) jsonObject.get("distInfo"); + heatUseNeedInfo = (JSONObject) jsonObject.get("heatUseNeedInfo"); + originalDevInfo = (JSONObject) jsonObject.get("originalDevInfo"); + // 预计年产量(吨) + Double yearOutPut = Double.parseDouble(heatUseNeedInfo.get("yearOutPut").toString()); + } catch (Exception e) { + e.printStackTrace(); + } + + double lastYearNeed = 0; + double runCapacity = 0; + try { + // 上年最大需量 + lastYearNeed = Double.parseDouble(distInfo.get("lastYearNeed").toString()); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素上年最大需量传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素上年最大需量为非数字,禁止传参空字符串"); + } + + try { + // 运行容量 + runCapacity = Double.parseDouble(distInfo.get("runCapacity").toString()); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素运行容量传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素运行容量为非数字,禁止传参空字符串"); + } + + Double workArea = null; + try { + // 工作容积(单位: m³)【 1 立方米=1000 升 】 + workArea = Double.parseDouble(heatUseNeedInfo.get("workArea").toString()) / 1000; + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素工作容积传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素工作容积为非数字,禁止传参空字符串"); + } + + + Double needTemp = null; + try { + // 温度要求(摄氏度) + needTemp = Double.parseDouble(heatUseNeedInfo.get("needTemp").toString()); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素温度要求(摄氏度)传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素温度要求(摄氏度)为非数字,禁止传参空字符串"); + } + + // 用户所属行业编码 + String userIndustry = null; + try { + userIndustry = jsonObject.get("userIndustry").toString(); + } catch (NullPointerException e) { + System.out.println("用户所属行业编码为空"); + } + + // 替代前原能源类型编码 + Integer energyCode = null; + try { + // 替代前原能源类型编码 + energyCode = (Integer) originalDevInfo.get("energyCode"); + } catch (NullPointerException e1) { + e1.printStackTrace(); + System.err.println("模型计算必须元素替代前原能源类型编码传的为null或者没有传参"); + } catch (NumberFormatException e2) { + e2.printStackTrace(); + System.err.println("模型计算必须元素替代前原能源类型编码为非数字,禁止传参空字符串"); + } + + // 根据供热需量设备功率计算出不同技术类型下所需要不同功率设备数据 + List schemeList = MaterialKilnScheme.getSchemeList(userIndustry, needTemp, alternateDeviceList); + List matchedDeviceGroupList = MaterialKilnScheme.calSchemeByTechType(workArea, schemeList); + + // 实际可承载容量A = 运行(或合同容量)x0.9 [将运行容量或合同容量折算成容量] x85% + double A = runCapacity * COEFFICIENT_1 * COEFFICIENT_2; + // 根据供热需量设备功率计算每个技术类型下需要的不同功率的设备的数量,然后将不同功率及对应的数量进行计算得出总功率C1,取最大 + Double C1 = model.getC1(Collections.singletonList(matchedDeviceGroupList)); + + // 改造后最大需量 + double D1 = lastYearNeed + C1; + + String remark = ""; + + // 同时考虑热泵和电锅炉 + if (A < D1) { + remark = "本方案存在扩容投资需求,扩容投资不计入初次投资费用"; + } + + + /* + 封装返回 + */ + JSONObject returnJsonObject = new JSONObject(); + Double startCost = 0.0; + Double runCost = 0.0; + Double allCost = 0.0; + Double calculateAnnualCarbon = 0.0; + Double laborFee1 = 0.0; + Double electric = 0.0; + List> deviceList = new ArrayList<>(); + for (MatchedDevice matchedDevice : matchedDeviceGroupList) { + HashMap map = new HashMap<>(); + map.put("devSubType", matchedDevice.getDeviceHeatScene().getDevSubType()); + map.put("devTechType", matchedDevice.getDeviceHeatScene().getDevTechType()); + map.put("devCount", matchedDevice.getCount()); + map.put("devPrice", matchedDevice.getDeviceHeatScene().getDevPrice()); + deviceList.add(map); + + startCost = startCost + (matchedDevice.getCount() * matchedDevice.getDeviceHeatScene().getDevPrice()); + + runCost = runCost + (model.calculateAnnualOperatingCost(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost(), matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime())); + + allCost = allCost + (model.calculateAnnualTotalCost(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost(), + matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime(), matchedDevice.getDeviceHeatScene().getDevPrice(), matchedDevice.getDeviceHeatScene().getDevServiceLife())); + + electric = electric + (model.calculateSubstituteElectricity(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime())); + + laborFee1 = laborFee1 + (matchedDevice.getCount() * matchedDevice.getDeviceHeatScene().getLaborCost() / matchedDevice.getDeviceHeatScene().getDevServiceLife()); + + } + + Double previousYearEnergyUsage = 1.0; + Double lastYearFee = 0.0; + Double energyPrice = 0.0; + try { + energyPrice = Double.parseDouble(originalDevInfo.get("energyPrice").toString()); + } catch (NullPointerException e){ + System.out.println("计算因子采用默认值"); + energyPrice = GetThisEnergyEmissions.getThisEnergyPrice(energyCode); + } + + try { + // 替代前年能源用量 + previousYearEnergyUsage = Double.parseDouble(originalDevInfo.get("previousYearEnergyUsage").toString()); + } catch (NullPointerException e){ + try { + lastYearFee = Double.parseDouble(originalDevInfo.get("lastYearFee").toString()); + previousYearEnergyUsage = CalculateUtils.divide(lastYearFee, energyPrice); + } catch (ArithmeticException nfe){ + nfe.printStackTrace(); + System.err.println("数学错误,替代前原使用能源平均单价不可为0"); + } catch (NullPointerException npe){ + System.err.println("替代前年能源使用量和上年运行费用都为空"); + } + } catch (NumberFormatException nfe){ + nfe.printStackTrace(); + System.err.println("替代前年能源用量为非数字,禁止传参空字符串"); + } + + try { + // 上年运行费用(元) + lastYearFee = Double.parseDouble(originalDevInfo.get("lastYearFee").toString()); + } catch (NullPointerException e) { + lastYearFee = model.calLastYearFee(0.0, previousYearEnergyUsage, energyPrice); + } catch (NumberFormatException nfe){ + nfe.printStackTrace(); + System.err.println("上年运行费用(元)为非数字,禁止传参空字符串"); + } + + // 替代前上年原设备碳排放量 + double energyLastYearFactor = model.calLastYearFactor(previousYearEnergyUsage, GetThisEnergyEmissions.getThisEnergyEmission((Integer) originalDevInfo.get("energyCode"))); + // 年减碳量 + calculateAnnualCarbon = model.calculateAnnualCarbonReduction(energyLastYearFactor, electric, EnergyEmissions.ELECTRIC.getCo2EmissionFactor()); + + //初次投资费用 + returnJsonObject.set("startCost", decimalFormat.format(startCost)); + // 设备总价 + returnJsonObject.set("devCost", decimalFormat.format(startCost)); + //年运行费用 + returnJsonObject.set("yearRunCost", decimalFormat.format(runCost)); + //年总费用 + returnJsonObject.set("yearCost", decimalFormat.format(allCost)); + + returnJsonObject.set("calculate", decimalFormat.format(calculateAnnualCarbon / 1000)); + //替代电量 + returnJsonObject.set("electric", decimalFormat.format(electric)); + //备注 + returnJsonObject.set("remark", remark); + //封装需配置设备情况 + returnJsonObject.set("deviceList", deviceList); + + //封装方案优势 + returnJsonObject.set("safety", advantage.safety()); + returnJsonObject.set("economy", advantage.economy(startCost, runCost, lastYearFee)); + returnJsonObject.set("intelligence", advantage.intelligence()); + returnJsonObject.set("environment", advantage.environment(Double.valueOf(decimalFormat.format(calculateAnnualCarbon / 1000)))); + + + return returnJsonObject; + } + + +} diff --git a/dntd-model-metalkiln/src/main/java/calculate/MetalKilnScheme.java b/dntd-model-metalkiln/src/main/java/calculate/MetalKilnScheme.java index 648f9fd..ccec6a0 100644 --- a/dntd-model-metalkiln/src/main/java/calculate/MetalKilnScheme.java +++ b/dntd-model-metalkiln/src/main/java/calculate/MetalKilnScheme.java @@ -7,12 +7,14 @@ import com.dky.utils.enums.DeviceSubType; import com.dky.utils.enums.MetalKinTemps; import com.dky.utils.result.MatchedDevice; +import java.text.DecimalFormat; import java.util.*; import java.util.stream.Collectors; public class MetalKilnScheme { + DecimalFormat df = new DecimalFormat("#.00"); public static List calSchemeByTechType(Double workArea, List sysDeviceHeatSceneList) { // 对技术类型下的设备list按照单台设备工作容积进行排序 diff --git a/dntd-model-metalkiln/src/main/resources/IndustryCode.properties b/dntd-model-metalkiln/src/main/resources/IndustryCode.properties deleted file mode 100644 index f374d6e..0000000 --- a/dntd-model-metalkiln/src/main/resources/IndustryCode.properties +++ /dev/null @@ -1 +0,0 @@ -industry_code=3200 \ No newline at end of file diff --git a/dntd-tool/src/main/java/com/dky/generate/MaterialKilnScene.java b/dntd-tool/src/main/java/com/dky/generate/MaterialKilnScene.java deleted file mode 100644 index f1de21d..0000000 --- a/dntd-tool/src/main/java/com/dky/generate/MaterialKilnScene.java +++ /dev/null @@ -1,169 +0,0 @@ -package com.dky.generate; - -import calculate.MetalKilnScheme; -import cn.hutool.json.JSONObject; -import com.dky.calculate.*; -import com.dky.modelI.DntdModelI; -import com.dky.utils.GetTargetDeviceList; -import com.dky.utils.GetThisEnergyEmissions; -import com.dky.utils.entity.SysDeviceHeatScene; -import com.dky.utils.enums.DeviceSubType; -import com.dky.utils.enums.EnergyEmissions; -import com.dky.utils.result.MatchedDevice; - -import java.text.DecimalFormat; -import java.util.*; - -public class MaterialKilnScene implements DntdModelI { - - DecimalFormat decimalFormat = new DecimalFormat("#.00"); - - // 首先A=由运行/合同容量折合成kW(x0.9)x85%, - static final Double COEFFICIENT_1 = 0.9; - static final Double COEFFICIENT_2 = 0.85; - - - @Override - public JSONObject createReport(JSONObject jsonObject, List list) { - List list1 = GetTargetDeviceList.main(DeviceSubType.Material_Kiln.getDesc(), list); - List list2 = GetTargetDeviceList.main(DeviceSubType.Metal_Kiln.getDesc(), list); - List alternateDeviceList = new ArrayList<>(list1); - alternateDeviceList.addAll(list2); - - JSONObject distInfo = new JSONObject(); - JSONObject heatUseNeedInfo = new JSONObject(); - JSONObject originalDevInfo = new JSONObject(); - - try { - distInfo = (JSONObject) jsonObject.get("distInfo"); - heatUseNeedInfo = (JSONObject) jsonObject.get("heatUseNeedInfo"); - originalDevInfo = (JSONObject) jsonObject.get("originalDevInfo"); - } catch (Exception e) { - e.printStackTrace(); - } - - // 运行容量 - Double runCapacity = Double.parseDouble(distInfo.get("runCapacity").toString()); - // 上年最大需量 - Double lastYearNeed = Double.parseDouble(distInfo.get("lastYearNeed").toString()); - // 工作容积(单位: m³)【 1 立方米=1000 升 】 - Double workArea = Double.parseDouble(heatUseNeedInfo.get("workArea").toString()) / 1000; - // 预计年产量(吨) - Double yearOutPut = Double.parseDouble(heatUseNeedInfo.get("yearOutPut").toString()); - // 温度要求(摄氏度) - Double needTemp = Double.parseDouble(heatUseNeedInfo.get("needTemp").toString()); - // 用户所属行业编码 - String userIndustry = jsonObject.get("userIndustry").toString(); - - // 根据供热需量设备功率计算出不同技术类型下所需要不同功率设备数据 - List schemeList = MaterialKilnScheme.getSchemeList(userIndustry, needTemp, alternateDeviceList); - List matchedDeviceGroupList = MaterialKilnScheme.calSchemeByTechType(workArea, schemeList); - - // 实际可承载容量A = 运行(或合同容量)x0.9 [将运行容量或合同容量折算成容量] x85% - double A = runCapacity * COEFFICIENT_1 * COEFFICIENT_2; - // 根据供热需量设备功率计算每个技术类型下需要的不同功率的设备的数量,然后将不同功率及对应的数量进行计算得出总功率C1,取最大 - Double C1 = CalC.getC1(Collections.singletonList(matchedDeviceGroupList)); - - // 改造后最大需量 - double D1 = lastYearNeed + C1; - - String remark = ""; - - // 同时考虑热泵和电锅炉 - if (A < D1) { - remark = "本方案存在扩容投资需求,扩容投资不计入初次投资费用"; - } - - - /* - 封装返回 - */ - JSONObject returnJsonObject = new JSONObject(); - Double startCost = 0.0; - Double runCost = 0.0; - Double allCost = 0.0; - Double calculateAnnualCarbon = 0.0; - Double laborFee1 = 0.0; - Double electric = 0.0; - List> deviceList = new ArrayList<>(); - for (MatchedDevice matchedDevice : matchedDeviceGroupList) { - HashMap map = new HashMap<>(); - map.put("devSubType", matchedDevice.getDeviceHeatScene().getDevSubType()); - map.put("devTechType", matchedDevice.getDeviceHeatScene().getDevTechType()); - map.put("devCount", matchedDevice.getCount()); - map.put("devPrice", matchedDevice.getDeviceHeatScene().getDevPrice()); - deviceList.add(map); - - startCost = startCost + (matchedDevice.getCount() * matchedDevice.getDeviceHeatScene().getDevPrice()); - - runCost = runCost + (MaterialKilnModel.calculateAnnualOperatingCost(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost(), matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime())); - - allCost = allCost + (MaterialKilnModel.calculateAnnualTotalCost(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost(), - matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime(), matchedDevice.getDeviceHeatScene().getDevPrice(), matchedDevice.getDeviceHeatScene().getDevServiceLife())); - - electric = electric + (MaterialKilnModel.calculateSubstituteElectricity(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime())); - - laborFee1 = laborFee1 + (matchedDevice.getCount() * matchedDevice.getDeviceHeatScene().getLaborCost() / matchedDevice.getDeviceHeatScene().getDevServiceLife()); - - } - - Double previousYearEnergyUsage = 1.0; - Double lastYearFee = 0.0; - Double energyPrice = 0.0; - try { - energyPrice = Double.parseDouble(originalDevInfo.get("energyPrice").toString()); - } catch (NullPointerException e){ - energyPrice = GetThisEnergyEmissions.getThisEnergyPrice((Integer) originalDevInfo.get("energyCode")); - } - - try { - // 替代前年能源用量 - previousYearEnergyUsage = Double.parseDouble(originalDevInfo.get("previousYearEnergyUsage").toString()); - } catch (NullPointerException e){ - lastYearFee = Double.parseDouble(originalDevInfo.get("lastYearFee").toString()); - previousYearEnergyUsage = lastYearFee / energyPrice; - } - - try { - // 上年运行费用(元) - lastYearFee = Double.parseDouble(originalDevInfo.get("lastYearFee").toString()); - } catch (NullPointerException e) { - // e.printStackTrace(); - System.out.println("计算因子采用默认值"); - lastYearFee = HeatBoilerModel.calLastYearFee(laborFee1, previousYearEnergyUsage, energyPrice); - } - // 替代前上年原设备碳排放量 - double energyLastYearFactor = HeatBoilerModel.calLastYearFactor(previousYearEnergyUsage, GetThisEnergyEmissions.getThisEnergyEmission((Integer) originalDevInfo.get("energyCode"))); - // 年减碳量 - calculateAnnualCarbon = HeatBoilerModel.calculateAnnualCarbonReduction(energyLastYearFactor, electric, EnergyEmissions.ELECTRIC.getCo2EmissionFactor()); - - - //初次投资费用 - returnJsonObject.set("startCost", decimalFormat.format(startCost)); - // 设备总价 - returnJsonObject.set("devCost", decimalFormat.format(startCost)); - //年运行费用 - returnJsonObject.set("yearRunCost", decimalFormat.format(runCost)); - //年总费用 - returnJsonObject.set("yearCost", decimalFormat.format(allCost)); - - returnJsonObject.set("calculate", decimalFormat.format(calculateAnnualCarbon / 1000)); - //替代电量 - returnJsonObject.set("electric", decimalFormat.format(electric)); - //备注 - returnJsonObject.set("remark", remark); - //封装需配置设备情况 - returnJsonObject.set("deviceList", deviceList); - - //封装方案优势 - returnJsonObject.set("safety", BuildHeatingAdvantage.safety()); - returnJsonObject.set("economy", Advantage.economy(startCost, runCost, lastYearFee)); - returnJsonObject.set("intelligence", BuildHeatingAdvantage.intelligence()); - returnJsonObject.set("environment", BuildHeatingAdvantage.environment(Double.valueOf(decimalFormat.format(calculateAnnualCarbon / 1000)))); - - - return returnJsonObject; - } - - -} diff --git a/dntd-tool/src/main/java/com/dky/generate/MetalKilnScene.java b/dntd-tool/src/main/java/com/dky/generate/MetalKilnScene.java deleted file mode 100644 index 35d7462..0000000 --- a/dntd-tool/src/main/java/com/dky/generate/MetalKilnScene.java +++ /dev/null @@ -1,169 +0,0 @@ -package com.dky.generate; - -import calculate.MetalKilnScheme; -import cn.hutool.json.JSONObject; -import com.dky.calculate.*; -import com.dky.modelI.DntdModelI; -import com.dky.utils.GetTargetDeviceList; -import com.dky.utils.GetThisEnergyEmissions; -import com.dky.utils.entity.SysDeviceHeatScene; -import com.dky.utils.enums.DeviceSubType; -import com.dky.utils.enums.EnergyEmissions; -import com.dky.utils.result.MatchedDevice; - -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - -public class MetalKilnScene implements DntdModelI { - - DecimalFormat decimalFormat = new DecimalFormat("#.00"); - - // 首先A=由运行/合同容量折合成kW(x0.9)x85%, - static final Double COEFFICIENT_1 = 0.9; - static final Double COEFFICIENT_2 = 0.85; - - - @Override - public JSONObject createReport(JSONObject jsonObject, List list) { - - List alternateDeviceList = GetTargetDeviceList.main(DeviceSubType.Metal_Kiln.getDesc(), list); - - JSONObject distInfo = new JSONObject(); - JSONObject heatUseNeedInfo = new JSONObject(); - JSONObject originalDevInfo = new JSONObject(); - - try { - distInfo = (JSONObject) jsonObject.get("distInfo"); - heatUseNeedInfo = (JSONObject) jsonObject.get("heatUseNeedInfo"); - originalDevInfo = (JSONObject) jsonObject.get("originalDevInfo"); - } catch (Exception e) { - e.printStackTrace(); - } - - // 运行容量 - Double runCapacity = Double.parseDouble(distInfo.get("runCapacity").toString()); - // 上年最大需量 - Double lastYearNeed = Double.parseDouble(distInfo.get("lastYearNeed").toString()); - // 工作容积(单位: m³)【 1 立方米=1000 升 】 - Double workArea = Double.parseDouble(heatUseNeedInfo.get("workArea").toString()) / 1000; - // 预计年产量(吨) - Double yearOutPut = Double.parseDouble(heatUseNeedInfo.get("yearOutPut").toString()); - // 温度要求(摄氏度) - Double needTemp = Double.parseDouble(heatUseNeedInfo.get("needTemp").toString()); - // 用户所属行业编码 - String userIndustry = jsonObject.get("userIndustry").toString(); - - // 根据供热需量设备功率计算出不同技术类型下所需要不同功率设备数据 - List schemeList = MetalKilnScheme.getSchemeList(userIndustry, needTemp, alternateDeviceList); - List matchedDeviceGroupList = MetalKilnScheme.calSchemeByTechType(workArea, schemeList); - - // 实际可承载容量A = 运行(或合同容量)x0.9 [将运行容量或合同容量折算成容量] x85% - double A = runCapacity * COEFFICIENT_1 * COEFFICIENT_2; - // 根据供热需量设备功率计算每个技术类型下需要的不同功率的设备的数量,然后将不同功率及对应的数量进行计算得出总功率C1,取最大 - Double C1 = CalC.getC1(Collections.singletonList(matchedDeviceGroupList)); - - // 改造后最大需量 - double D1 = lastYearNeed + C1; - - String remark = ""; - - // 同时考虑热泵和电锅炉 - if (A < D1) { - remark = "本方案存在扩容投资需求,扩容投资不计入初次投资费用"; - } - - - /* - 封装返回 - */ - JSONObject returnJsonObject = new JSONObject(); - Double startCost = 0.0; - Double runCost = 0.0; - Double allCost = 0.0; - Double calculateAnnualCarbon = 0.0; - Double laborFee1 = 0.0; - Double electric = 0.0; - List> deviceList = new ArrayList<>(); - for (MatchedDevice matchedDevice : matchedDeviceGroupList) { - HashMap map = new HashMap<>(); - map.put("devSubType", matchedDevice.getDeviceHeatScene().getDevSubType()); - map.put("devTechType", matchedDevice.getDeviceHeatScene().getDevTechType()); - map.put("devCount", matchedDevice.getCount()); - map.put("devPrice", matchedDevice.getDeviceHeatScene().getDevPrice()); - deviceList.add(map); - - startCost = startCost + (matchedDevice.getCount() * matchedDevice.getDeviceHeatScene().getDevPrice()); - - runCost = runCost + (MaterialKilnModel.calculateAnnualOperatingCost(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost(), matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime())); - - allCost = allCost + (MaterialKilnModel.calculateAnnualTotalCost(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost(), - matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime(), matchedDevice.getDeviceHeatScene().getDevPrice(), matchedDevice.getDeviceHeatScene().getDevServiceLife())); - - electric = electric + (MaterialKilnModel.calculateSubstituteElectricity(matchedDevice.getDeviceHeatScene().getDevPower(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevAnnualOperationTime())); - - laborFee1 = laborFee1 + (matchedDevice.getCount() * matchedDevice.getDeviceHeatScene().getLaborCost() / matchedDevice.getDeviceHeatScene().getDevServiceLife()); - - } - - Double previousYearEnergyUsage = 1.0; - Double lastYearFee = 0.0; - Double energyPrice = 0.0; - try { - energyPrice = Double.parseDouble(originalDevInfo.get("energyPrice").toString()); - } catch (NullPointerException e){ - energyPrice = GetThisEnergyEmissions.getThisEnergyPrice((Integer) originalDevInfo.get("energyCode")); - } - - try { - // 替代前年能源用量 - previousYearEnergyUsage = Double.parseDouble(originalDevInfo.get("previousYearEnergyUsage").toString()); - } catch (NullPointerException e){ - lastYearFee = Double.parseDouble(originalDevInfo.get("lastYearFee").toString()); - previousYearEnergyUsage = lastYearFee / energyPrice; - } - - try { - // 上年运行费用(元) - lastYearFee = Double.parseDouble(originalDevInfo.get("lastYearFee").toString()); - } catch (NullPointerException e) { - // e.printStackTrace(); - System.out.println("计算因子采用默认值"); - lastYearFee = HeatBoilerModel.calLastYearFee(laborFee1, previousYearEnergyUsage, energyPrice); - } - // 替代前上年原设备碳排放量 - double energyLastYearFactor = HeatBoilerModel.calLastYearFactor(previousYearEnergyUsage, GetThisEnergyEmissions.getThisEnergyEmission((Integer) originalDevInfo.get("energyCode"))); - // 年减碳量 - calculateAnnualCarbon = HeatBoilerModel.calculateAnnualCarbonReduction(energyLastYearFactor, electric, EnergyEmissions.ELECTRIC.getCo2EmissionFactor()); - - //初次投资费用 - returnJsonObject.set("startCost", decimalFormat.format(startCost)); - // 设备总价 - returnJsonObject.set("devCost", decimalFormat.format(startCost)); - //年运行费用 - returnJsonObject.set("yearRunCost", decimalFormat.format(runCost)); - //年总费用 - returnJsonObject.set("yearCost", decimalFormat.format(allCost)); - //年减碳量 - returnJsonObject.set("calculate", decimalFormat.format(calculateAnnualCarbon / 1000)); - //替代电量 - returnJsonObject.set("electric", decimalFormat.format(electric)); - //备注 - returnJsonObject.set("remark", remark); - //封装需配置设备情况 - returnJsonObject.set("deviceList", deviceList); - - //封装方案优势 - returnJsonObject.set("safety", BuildHeatingAdvantage.safety()); - returnJsonObject.set("economy", Advantage.economy(startCost, runCost, lastYearFee)); - returnJsonObject.set("intelligence", BuildHeatingAdvantage.intelligence()); - returnJsonObject.set("environment", BuildHeatingAdvantage.environment(Double.valueOf(decimalFormat.format(calculateAnnualCarbon / 1000)))); - - - return returnJsonObject; - } - - -} diff --git a/dntd-tool/src/main/java/com/dky/security/SM4Utils.java b/dntd-tool/src/main/java/com/dky/security/SM4Utils.java index 82ad3ae..840be0e 100644 --- a/dntd-tool/src/main/java/com/dky/security/SM4Utils.java +++ b/dntd-tool/src/main/java/com/dky/security/SM4Utils.java @@ -7,10 +7,11 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; -import java.io.*; import java.nio.charset.StandardCharsets; import java.security.Security; -import java.util.*; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; public class SM4Utils { static { @@ -30,32 +31,6 @@ public class SM4Utils { return Base64.getEncoder().encodeToString(encrypted); } - public static Map decrypt(String encrypted) throws FileNotFoundException { - - File file = new File("file.txt"); - FileReader fileReader = new FileReader(file); - try (BufferedReader reader = new BufferedReader(fileReader)) { - String line; - while ((line = reader.readLine()) != null) { - try { - Cipher cipher = Cipher.getInstance(ALGORITHM, "BC"); - SecretKeySpec secretKey = new SecretKeySpec(line.getBytes(StandardCharsets.UTF_8), "AES"); - cipher.init(Cipher.DECRYPT_MODE, secretKey); - byte[] decoded = Base64.getDecoder().decode(encrypted); - byte[] decrypted = cipher.doFinal(decoded); - return stringToMap(new String(decrypted, StandardCharsets.UTF_8)); - } catch (Exception e) { - System.out.println("私钥:" + line + ",该私钥未认证"); - e.printStackTrace(); - } - } - } catch ( IOException e){ - System.out.println("文件读取错误,请检查文件内容是否为空"); - throw new RuntimeException(); - } - return null; - } - private static String mapToString(Map map) { StringBuilder sb = new StringBuilder(); @@ -85,8 +60,14 @@ public class SM4Utils { * @return */ public static String sm2DecryptBase64(String encryptStr) { - SM2 sm2 = new SM2(SM4_KEY, null); - return StrUtil.utf8Str(sm2.decrypt(encryptStr, KeyType.PrivateKey)); + try { + SM2 sm2 = new SM2(SM4_KEY, null); + return StrUtil.utf8Str(sm2.decrypt(encryptStr, KeyType.PrivateKey)); + } catch (Exception e) { + e.printStackTrace(); + System.err.println("密钥错误,请检查密钥输入是否正确"); + } + return null; } } \ No newline at end of file diff --git a/dntd-tool/src/main/java/com/dky/tool/ModelTool.java b/dntd-tool/src/main/java/com/dky/tool/ModelTool.java index 0c1dac6..fdc2888 100644 --- a/dntd-tool/src/main/java/com/dky/tool/ModelTool.java +++ b/dntd-tool/src/main/java/com/dky/tool/ModelTool.java @@ -9,6 +9,7 @@ import com.dky.utils.entity.SysDeviceHeatScene; import com.dky.utils.enums.Code; import com.dky.utils.result.ResponseUtil; +import java.io.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.ParseException; @@ -122,10 +123,12 @@ public class ModelTool { if (createTimeDate.before(new Date(startTimeDate.getTime() + 1000 * 60 * 60 * 24 * 10))){ isAuthorization = Boolean.TRUE; } + isAuthorization = Boolean.TRUE; if (isAuthorization) { // 判断模型使用权限 // 根据给定的类名初始化类 加密不需要反实例化new - Class buildHeatingScene = Class.forName("com.dky" + "." + ConfigReader.getProperty(jsonObject.getStr("type"))); + String type = decrypt().get(jsonObject.getStr("type")); + Class buildHeatingScene = Class.forName("com.dky" + "." + type); // 实例化这个类 DntdModelI buildHeatingSceneModel = (DntdModelI) buildHeatingScene.newInstance(); // 调用指定方法 @@ -147,7 +150,7 @@ public class ModelTool { } public static void main(String[] args) throws Exception { - String key = "BLR6nEyco9XOz/AAPNyQiVV9ZAaW8uzIlPCPAelM2/l1G/xHFQPpoU6da86xwtXPym6gHx5TRKVUyUpGOUfIqDTf/acmql7/xM6RZUlNizb93z8o5+f3HL4c5/J/R2+6/V0c0oLkh/j/uks6QnyI5UHN+WFPpRVliv3H+Dd+97/jodlcYCafeKMdknClJlaVpUZBnsjDw+Am2+gl1h43wGkmHqS5jGD9z1wkr/VjsjE7oLyS"; + /*String key = "BLR6nEyco9XOz/AAPNyQiVV9ZAaW8uzIlPCPAelM2/l1G/xHFQPpoU6da86xwtXPym6gHx5TRKVUyUpGOUfIqDTf/acmql7/xM6RZUlNizb93z8o5+f3HL4c5/J/R2+6/V0c0oLkh/j/uks6QnyI5UHN+WFPpRVliv3H+Dd+97/jodlcYCafeKMdknClJlaVpUZBnsjDw+Am2+gl1h43wGkmHqS5jGD9z1wkr/VjsjE7oLyS"; // 根据给定的类名初始化类 加密不需要反实例化new Class sm4UtilsClass = Class.forName("com.dky.security.SM4Utils"); // 实例化类 @@ -155,11 +158,32 @@ public class ModelTool { // 获取方法并调用 Method decryptMethod = sm4UtilsClass.getMethod("sm2DecryptBase64", String.class); String invoke = (String) decryptMethod.invoke(obj, key); - System.out.println(invoke); + System.out.println(invoke);*/ } public static JSONObject getEnergyUseInfos(JSONObject jsonObject) { // 调用指定方法 return StirparModelCalculate.createReport(jsonObject); } + + public Map decrypt() throws FileNotFoundException { + Map map = new HashMap<>(); + File file = new File("file.txt"); + FileReader fileReader = new FileReader(file); + try (BufferedReader reader = new BufferedReader(fileReader)) { + String line; + while ((line = reader.readLine()) != null) { + try { + String[] split = line.split("="); + map.put(split[0], split[1]); + } catch (Exception e) { + e.printStackTrace(); + } + } + } catch ( IOException e){ + System.out.println("文件读取错误,请检查文件内容是否为空"); + throw new RuntimeException(); + } + return map; + } } \ No newline at end of file diff --git a/file.txt b/file.txt new file mode 100644 index 0000000..fe21f94 --- /dev/null +++ b/file.txt @@ -0,0 +1,6 @@ +0101=generate.HeatBoilerScene +0102=generate.MaterialKilnScene +0201=generate.BuildHeatingScene +0501=generate.KitchenCookScene +0805=generate.MetalKilnScene +0806=stirtpar.StirparModelCalculate \ No newline at end of file diff --git a/pom.xml b/pom.xml index cff0767..fb75f3e 100644 --- a/pom.xml +++ b/pom.xml @@ -37,14 +37,14 @@ bcprov-jdk15to18 1.69 - + - + src/main/resources/