diff --git a/zc-business/src/main/java/com/zc/business/controller/DcDeviceController.java b/zc-business/src/main/java/com/zc/business/controller/DcDeviceController.java index 0e76ad10..4746e7fe 100644 --- a/zc-business/src/main/java/com/zc/business/controller/DcDeviceController.java +++ b/zc-business/src/main/java/com/zc/business/controller/DcDeviceController.java @@ -6,6 +6,7 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.*; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; @@ -27,6 +28,8 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import io.swagger.v3.oas.annotations.Parameter; +import okhttp3.OkHttpClient; +import okhttp3.Request; import okhttp3.Response; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; @@ -37,6 +40,8 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.IOException; +import java.math.RoundingMode; +import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; @@ -328,7 +333,247 @@ public class DcDeviceController extends BaseController { .get(); // 请求方法 return JSON.parseObject(response.body().string(), AjaxResult.class); } + @ApiOperation("获取太阳能设备属性数据") + @GetMapping("/properties/solarEnergy") + public AjaxResult getDeviceLatestSolarEnergy() throws HttpException, IOException { + Map parameter =new HashMap<>(); + String[] endStakeMark={"208","979"}; + String[] startStakeMark={"054","378"}; + parameter.put("deviceType","15"); + parameter.put("endStakeMark",endStakeMark); + parameter.put("startStakeMark",startStakeMark); + parameter.put("deviceState","1"); + + // StakeMarkUtils.stakeMarkToInt() + //facilitiesType + List dcDevices = dcDeviceService.devicePileNumberQueryDevice(parameter); + List> dcDeviceList = new ArrayList<>(); + OkHttp okHttp = new OkHttp(); + for (DcDevice dcDevice : dcDevices) { + String iotDeviceId = dcDevice.getIotDeviceId(); + Response response // 请求响应 + = okHttp + .url(iotAddress + UniversalEnum.OBTAIN_THE_LATEST_DEVICE_PROPERTY_DATA.getValue() + iotDeviceId) // 请求地址 + .get(); // 请求方法 + // 解析JSON字符串 + JsonElement jsonElement = JsonParser.parseString(response.body().string()); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + + if (jsonObject.has("data") && jsonObject.get("data").isJsonArray()) { + JsonArray dataArray = jsonObject.getAsJsonArray("data"); + // 构建Map + Map attributeMap = new HashMap<>(); + for (JsonElement element : dataArray) { + if (element.isJsonObject()) { + JsonObject item = element.getAsJsonObject(); + if (item.has("property") && item.has("formatValue")) { + String property = item.get("property").getAsString(); + String formatValue = item.get("formatValue").getAsString(); + attributeMap.put(property, formatValue); + } + } + } + dcDevice.setAttributeData(attributeMap); + } + + } + + return AjaxResult.success(dcDevices); + } + @ApiOperation("太阳能状况统计") + @GetMapping("/properties/history/oneDay/{propertyId}") + public AjaxResult queryDevicePropertiesDay( + @PathVariable @Parameter(description = "属性ID") String propertyId) throws HttpException, IOException, ParseException { + HashMap props = new HashMap<>(); + // 设置查询条件的键为“timestamp$BTW”,表示时间戳在一定范围内 + props.put("terms[0].column", "timestamp$BTW"); + ArrayList dateList = new ArrayList<>(); + // 添加当前日期的开始和结束时间到列表,用于设定时间范围 + dateList.add(DateUtil.beginOfDay(new Date()).toString()); + dateList.add(DateUtil.endOfDay(new Date()).toString()); + // 将日期列表以逗号分隔并设置为查询条件的值 + props.put("terms[0].value", String.join(UniversalEnum.COMMA.getValue(), dateList)); + props.put("paging", false); + props.put("sorts[0].order", "asc"); + props.put("sorts[0].name", "timestamp"); + Map parameter =new HashMap<>(); + String[] endStakeMark={"208","979"}; + String[] startStakeMark={"054","378"}; + parameter.put("deviceType","15"); + parameter.put("endStakeMark",endStakeMark); + parameter.put("startStakeMark",startStakeMark); + parameter.put("deviceState","1"); + // 创建一个映射来存储按小时汇总的数据 + Map allDevicesHourlyAggregates = new TreeMap<>(); + + List dcDevices = dcDeviceService.devicePileNumberQueryDevice(parameter); + for (DcDevice dcDevice : dcDevices) { + AjaxResult ajaxResult = queryDeviceProperties(dcDevice.getIotDeviceId(), propertyId, props); + if (!ajaxResult.get("code").equals(UniversalEnum.TWO_HUNDRED.getNumber())) { + return ajaxResult; + } + // 定义时间格式 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + Object data = JSON.parseObject(queryDeviceProperties(dcDevice.getIotDeviceId(), propertyId, props).get("data").toString()).get("data"); + JSONArray dataArray = JSON.parseArray(data.toString()); + // 创建一个映射来存储单个设备按小时汇总的数据 + Map deviceHourlyAggregates = new TreeMap<>(); + + List> list = new ArrayList<>(); + + // 处理每个数据点 + for (Object o : dataArray) { + JSONObject jsonObject = JSON.parseObject(o.toString()); + String formatValueStr = jsonObject.getString("formatValue"); + String timestampStr = jsonObject.getString("timestamp"); + + // 将 Unix 时间戳转换为 Date 对象 + long timestamp = Long.parseLong(timestampStr); + Date date = new Date(timestamp); + + // 将 Date 对象格式化为字符串 + String formattedTimestamp = sdf.format(date); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + // 提取小时部分 + int hour = calendar.get(Calendar.HOUR_OF_DAY); + String key = String.format("%d-%02d-%02d %02d:00:00", + calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, + calendar.get(Calendar.DAY_OF_MONTH), hour); +//转换为 double 类型,去除单位 + String valueWithoutUnit = formatValueStr.replaceAll("[^\\d.]", ""); + double formatValue = Double.parseDouble(valueWithoutUnit); + + // 汇总每个小时的数据 + deviceHourlyAggregates.merge(key, formatValue, Double::sum); + } +// 将设备的数据合并到所有设备的汇总数据中 + for (String key : deviceHourlyAggregates.keySet()) { + allDevicesHourlyAggregates.merge(key, deviceHourlyAggregates.get(key), Double::sum); + } + + } + + return AjaxResult.success(allDevicesHourlyAggregates); + } + + @ApiOperation("太阳能重点数据") + @GetMapping("/properties/latestOne") + public AjaxResult getDeviceLatest() throws HttpException, IOException { + Map parameters = new HashMap<>(); + String[] endStakeMark = {"208", "979"}; + String[] startStakeMark = {"054", "378"}; + parameters.put("deviceType", "15"); + parameters.put("endStakeMark", endStakeMark); + parameters.put("startStakeMark", startStakeMark); + parameters.put("deviceState", "1"); + + // List propertyIds = Arrays.asList("visibility", "wetSlipperyCoefficient", "waterFilmIceSnowValue"); + + List propertyIds = Arrays.asList( +"cumulativeElectricityConsumptionInTheYear", //当年累计用电量 + "cumulativeElectricityConsumptionOnTheDay",//当日累计用电量 + "theAccumulatedChargeOfTheYear",//当年累计充电量 + "dailyAccumulatedCharge"//当日累计充电量 + ); + List dcDevices = dcDeviceService.devicePileNumberQueryDevice(parameters); + Map attributeMap = new HashMap<>(); + + for (DcDevice dcDevice : dcDevices) { + String deviceId = dcDevice.getIotDeviceId(); + for (String propertyId : propertyIds) { + try (Response response = new OkHttpClient().newCall(new Request.Builder() + .url(iotAddress + UniversalEnum.GETS_THE_LATEST_DATA_ABOUT_THE_SPECIFIED_ATTRIBUTES_OF_A_DEVICE.getValue() + deviceId + UniversalEnum.SLASH.getValue() + propertyId) + .build()).execute()) { + String responseBody = response.body().string(); + JsonObject data = JsonParser.parseString(responseBody).getAsJsonObject().getAsJsonObject("data"); + String property = data.get("property").getAsString(); + String formatValueStr = data.get("formatValue").getAsString(); + String valueWithoutUnit = formatValueStr.replaceAll("[^\\d.]", ""); + double value = Double.parseDouble(valueWithoutUnit); + attributeMap.merge(property, value, (oldVal, newVal) -> oldVal + newVal); + } + } + } + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + decimalFormat.setRoundingMode(RoundingMode.HALF_UP); + + // 计算碳减排 碳减排(kg)=光伏发电量(kWh)*0.7119 + double carbonEmissionReduction = attributeMap.getOrDefault("theAccumulatedChargeOfTheYear", 0.0) * 0.7119; + double carbonEmissionReductionCoal = Double.parseDouble(decimalFormat.format(carbonEmissionReduction)); + + attributeMap.put("carbonEmissionReduction", carbonEmissionReductionCoal); +//等效植树(棵)=碳减排(kg)/5.023 + double equivalentTree = attributeMap.getOrDefault("carbonEmissionReduction", 0.0) / 5.023; + double equivalentTreeCoal = Double.parseDouble(decimalFormat.format(equivalentTree)); + + attributeMap.put("equivalentTree", equivalentTreeCoal); + //标准煤(kg)=碳减排(kg)/2.493 + double standardCoal = attributeMap.getOrDefault("carbonEmissionReduction", 0.0) / 2.493; + double formattedStandardCoal = Double.parseDouble(decimalFormat.format(standardCoal)); + + attributeMap.put("standardCoal", formattedStandardCoal); + attributeMap.forEach((key, value) -> System.out.println(String.format("属性:%s,格式值:%s", key, value))); + System.out.println(carbonEmissionReduction); + + return AjaxResult.success(attributeMap); + } +/** + * 太阳能设备统计 + */ + @ApiOperation("太阳能设备统计") + @GetMapping("/properties/solarDeviceStatistics") + public AjaxResult solarDeviceStatistics() throws HttpException, IOException { + Map parameters = new HashMap<>(); + String[] endStakeMark = {"208", "979"}; + String[] startStakeMark = {"054", "378"}; + parameters.put("deviceType", "15"); + parameters.put("endStakeMark", endStakeMark); + parameters.put("startStakeMark", startStakeMark); + int i=0; + Map attributeMap = new HashMap<>(); + // parameters.put("deviceState", "1"); + List dcDevices = dcDeviceService.devicePileNumberQueryDevice(parameters); + OkHttp okHttp = new OkHttp(); + + for (DcDevice dcDevice : dcDevices) { + if (dcDevice.getDeviceState().equals("1")){ + String iotDeviceId = dcDevice.getIotDeviceId(); + Response response // 请求响应 + = okHttp + .url(iotAddress + UniversalEnum.OBTAIN_THE_LATEST_DEVICE_PROPERTY_DATA.getValue() + iotDeviceId) // 请求地址 + .get(); // 请求方法 + // 解析JSON字符串 + JsonElement jsonElement = JsonParser.parseString(response.body().string()); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + + if (jsonObject.has("data") && jsonObject.get("data").isJsonArray()) { + JsonArray dataArray = jsonObject.getAsJsonArray("data"); + // 构建Map + for (JsonElement element : dataArray) { + if (element.isJsonObject()) { + JsonObject item = element.getAsJsonObject(); + if (item.has("property") && item.has("formatValue")) { + if (item.get("property").getAsString().equals("visibility")){//dischargeEquipmentStatus + if (item.get("formatValue").getAsString().equals("故障")){ + i++; + } + } + } + } + } + } + }else{ + i++; + } + attributeMap.put("count",i); + attributeMap.put("size",dcDevices.size()); + } + return AjaxResult.success(attributeMap); + } /** * 查询当天设备指定属性列表 * diff --git a/zc-business/src/main/java/com/zc/business/domain/DcDevice.java b/zc-business/src/main/java/com/zc/business/domain/DcDevice.java index c34c031e..d8f0d82e 100644 --- a/zc-business/src/main/java/com/zc/business/domain/DcDevice.java +++ b/zc-business/src/main/java/com/zc/business/domain/DcDevice.java @@ -12,6 +12,7 @@ import org.springframework.util.ObjectUtils; import com.ruoyi.common.annotation.Excel.ColumnType; import java.util.Date; +import java.util.Map; @Data @ApiModel(value = "DcDevice", description = "设备实体") @@ -116,7 +117,9 @@ public class DcDevice { //设备厂商 @TableField(exist = false) private String manufacturer; + @TableField(exist = false) + private Map attributeData; public Integer stakeMarkToInt() { return StakeMarkUtils.stakeMarkToInt(stakeMark); diff --git a/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java b/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java index a898cdd1..e0a40fc9 100644 --- a/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java +++ b/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java @@ -1245,8 +1245,8 @@ public class DcTrafficStatisticsServiceImpl implements IDcTrafficStatisticsServi .filter(device -> device.getFacilitiesType() .equals("1")) .filter(device -> { int deviceStakeMarkMeters = StakeMarkUtils.stakeMarkToInt(device.getStakeMark()); - return deviceStakeMarkMeters >= StakeMarkUtils.stakeMarkToInt("K111+107") && deviceStakeMarkMeters <= StakeMarkUtils.stakeMarkToInt("K132+577") ; - // return deviceStakeMarkMeters >= StakeMarkUtils.stakeMarkToInt(stakeMark) && deviceStakeMarkMeters <= StakeMarkUtils.stakeMarkToInt(jsonObject.get("endMark").toString()) ; + // return deviceStakeMarkMeters >= StakeMarkUtils.stakeMarkToInt("K111+107") && deviceStakeMarkMeters <= StakeMarkUtils.stakeMarkToInt("K132+577") ; + return deviceStakeMarkMeters >= StakeMarkUtils.stakeMarkToInt(stakeMarkKilometre(stakeMark)) && deviceStakeMarkMeters <= StakeMarkUtils.stakeMarkToInt(stakeMarkKilometre(jsonObject.get("endMark").toString())) ; }) .sorted(Comparator.comparingInt(device -> StakeMarkUtils.stakeMarkToInt(device.getStakeMark()))) .collect(Collectors.toList()); @@ -1264,6 +1264,18 @@ public class DcTrafficStatisticsServiceImpl implements IDcTrafficStatisticsServi } } + private String stakeMarkKilometre(String stakeMark) { + // 使用正则表达式匹配+号前的数字 + String numberBeforePlus = stakeMark.split("\\+")[0].replaceAll("[^0-9]", ""); + // 将匹配到的字符串转换为整数 + int number = Integer.parseInt(numberBeforePlus); + // 对数字加一 + int incrementedNumber = number + 1; + + // 将修改后的数字放回原字符串中 + return stakeMark.replaceFirst(numberBeforePlus, String.valueOf(incrementedNumber)); + } + /** * 各收费站日累计车流辆 *