package com.zhgd.xmgl.task; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpException; import cn.hutool.http.HttpRequest; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.gexin.fastjson.JSON; import com.zhgd.xmgl.modules.bigdevice.entity.Tower; import com.zhgd.xmgl.modules.bigdevice.entity.TowerCurrentData; import com.zhgd.xmgl.modules.bigdevice.entity.TowerWorkCycle; import com.zhgd.xmgl.modules.bigdevice.mapper.TowerCurrentDataMapper; import com.zhgd.xmgl.modules.bigdevice.mapper.TowerMapper; import com.zhgd.xmgl.modules.bigdevice.mapper.TowerWorkCycleMapper; import com.zhgd.xmgl.modules.bigdevice.service.ITowerCurrentDataService; import com.zhgd.xmgl.modules.bigdevice.service.ITowerWorkCycleService; import com.zhgd.xmgl.modules.project.entity.Project; import com.zhgd.xmgl.modules.project.mapper.ProjectMapper; import com.zhgd.xmgl.task.dto.TowerCycleDataDto; import com.zhgd.xmgl.task.dto.TowerDataDto; import com.zhgd.xmgl.util.AsyncTaskUtil; import com.zhgd.xmgl.util.XiwonUtil; import lombok.extern.slf4j.Slf4j; import net.javacrumbs.shedlock.core.SchedulerLock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @Slf4j @Component @RestController @RequestMapping("/xmgl/task/") public class TowerTask { @Autowired private ProjectMapper projectMapper; @Autowired private TowerMapper towerMapper; @Autowired private TowerCurrentDataMapper towerCurrentDataMapper; @Autowired private TowerWorkCycleMapper towerWorkCycleMapper; @Autowired private ITowerCurrentDataService towerCurrentDataService; @Autowired private ITowerWorkCycleService towerWorkCycleService; @Resource private XiwonUtil xiwonUtil; /** * 获取塔吊数据(携稳) 每5分钟触发任务 */ @SchedulerLock(name = "getTowerData", lockAtMostFor = 1000 * 60 * 5, lockAtLeastFor = 1000 * 60 * 3) @Scheduled(cron = "0 0/5 * * * ?") @RequestMapping("tower") public void getEnvironmentDustData() { log.info("获取塔吊数据(携稳)开始任务"); List projects = projectMapper.selectList(new LambdaQueryWrapper() .isNotNull(Project::getXiwonAppId) .isNotNull(Project::getXiwonAppSecret) ); for (Project project : projects) { // 获取设备列表 List devList = towerMapper.selectList(new LambdaQueryWrapper() .eq(Tower::getProjectSn, project.getProjectSn())); devList.forEach(dev -> AsyncTaskUtil.runAsync(() -> { doGetTowerData(dev, project); doGetTowerCycleData(dev, project); }) ); } } private void doGetTowerData(Tower dev, Project project) { // 设备sn String devSn = dev.getDevSn(); log.info("doGetTowerData设备sn:{}", devSn); TowerCurrentData newestData = towerCurrentDataMapper.selectOne(new LambdaQueryWrapper().eq(TowerCurrentData::getDevSn, devSn).orderByDesc(TowerCurrentData::getXiewenId).last("limit 1")); // 请求参数 Map map = new HashMap<>(4); map.put("pageSize", "10"); map.put("pageNum", "1"); JSONObject realTimeData = xiwonUtil.postForm("/tower/realTimeData", project.getXiwonAppId(), project.getXiwonAppSecret(), map, JSONObject.class, (() -> { map.put("deviceSn", devSn); if (newestData != null && newestData.getXiewenId() != null) { map.put("dataId", newestData.getXiewenId()); } return map; })); log.info("携稳接口响应数据(塔吊):devSn:{},rs:{}", devSn, JSON.toJSONString(realTimeData)); Integer code = realTimeData.getInteger("code"); // code校验是否成功请求 if (code == HttpStatus.OK.value()) { JSONArray dataArray = realTimeData.getJSONArray("data"); if (CollUtil.isNotEmpty(dataArray)) { // 解析请求到的参数,保存到我们的数据库 for (Object o : dataArray) { TowerDataDto dto = BeanUtil.toBean(o, TowerDataDto.class); TowerCurrentData data = new TowerCurrentData(); data.setDevSn(devSn); data.setDevName(dev.getDevName()); data.setProjectSn(dev.getProjectSn()); data.setReciveTime(DateUtil.parse(dto.getCraneTime())); data.setStartTime(DateUtil.parse(dto.getCraneTime())); data.setLoading(Convert.toStr(dto.getCraneElevatingCapacity())); data.setLoadRatio(Convert.toStr(dto.getCraneWeightPercentage())); data.setTorque(null); data.setTorqueRatio(Convert.toStr(dto.getCraneTorquePercentage())); if (dto.getCraneTiltAngle() != null) { data.setAngle(Convert.toStr(dto.getCraneTiltAngle() / 10)); } if (dto.getCraneRange() != null) { data.setRanger(Convert.toStr(dto.getCraneRange() / 10)); } if (dto.getCraneHeight() != null) { data.setHeight(Convert.toStr(dto.getCraneHeight() / 10)); } if (dto.getCraneWindSpeed() != null) { data.setWindspeed(Convert.toStr(dto.getCraneWindSpeed() / 10)); } if (dto.getCraneTiltAngle() != null) { data.setObliguity(Convert.toStr(dto.getCraneTiltAngle() / 10)); } data.setRate(null); data.setDriverName(null); data.setDriverIdCard(null); data.setObliguityX(null); data.setObliguityY(null); data.setRealFlag("0"); Integer craneAlarmReason = dto.getCraneAlarmReason(); if (craneAlarmReason != null) { switch (craneAlarmReason) { /* 0 正常 111 112 113 114碰撞报警 12 13 14 15 重量 力矩 倾斜 风速报警 211 212 213 214碰撞预警 22 23 24 25 重量 力矩 倾斜 风速预警 201幅度限位预警 202高度限位预警 203回转限位预警 101幅度限位报警 102高度限位报警 103回转限位报警 118酒精报警 218酒精预警 119重量违章报警 219重量违章预警 */ //data.setNoError(); //data.setWeightError(); //data.setWindSpeedError(); //data.setRangeError(); //data.setHeightError(); //data.setAngleError(); //data.setObliguityError(); //data.setGpsError(); //data.setIdError(); case 111: data.setMultiAlarmAll(1); break; case 112: data.setMultiAlarmAll(1); break; case 113: data.setMultiAlarmAll(1); break; case 114: data.setMultiAlarmAll(1); break; case 13: data.setMomentAlarm(1); break; case 14: data.setObliguityAlarm(1); break; case 15: data.setWindSpeedAlarm(1); break; case 211: data.setMultiAlarmAll(1); break; case 212: data.setMultiAlarmAll(1); break; case 213: data.setMultiAlarmAll(1); break; case 214: data.setMultiAlarmAll(1); break; case 23: data.setMomentAlarm(2); break; case 24: data.setObliguityAlarm(2); break; case 25: data.setWindSpeedAlarm(2); break; case 201: data.setMinRangeAlarm(2); data.setMaxRangeAlarm(2); break; case 202: data.setHeightAlarm(2); data.setHeightLowerAlarm(2); break; case 203: data.setPosAngleAlarm(2); data.setNegAngleAlarm(2); break; case 101: data.setMinRangeAlarm(1); data.setMaxRangeAlarm(1); break; case 102: data.setHeightAlarm(1); data.setHeightLowerAlarm(1); break; case 103: data.setPosAngleAlarm(1); data.setNegAngleAlarm(1); break; default: } if (Objects.equals(craneAlarmReason, 0)) { data.setNoAlarm(1); } else { data.setNoAlarm(0); } } data.setXiewenId(dto.getId()); towerCurrentDataService.saveTowerCurrentData(data); } } else { log.info("塔吊设备sn:{},当前无数据!", devSn); } } else { log.error("塔吊设备sn:{},请求失败!当前code:{},msg:{}", devSn, code, realTimeData.getString("msg")); } } private void doGetTowerCycleData(Tower dev, Project project) { // 设备sn String devSn = dev.getDevSn(); log.info("doGetTowerCycleData设备sn:{}", devSn); TowerWorkCycle newestData = towerWorkCycleMapper.selectOne(new LambdaQueryWrapper().eq(TowerWorkCycle::getDevSn, devSn).orderByDesc(TowerWorkCycle::getEndTime).last("limit 1")); // 请求参数 Map map = new HashMap<>(4); map.put("pageSize", "10"); map.put("pageNum", "1"); JSONObject realTimeData = xiwonUtil.postForm("/tower/workCycle", project.getXiwonAppId(), project.getXiwonAppSecret(), map, JSONObject.class, (() -> { map.put("deviceSn", devSn); if (newestData != null && newestData.getEndTime() != null) { map.put("startTime", DateUtil.formatDateTime(DateUtil.offsetSecond(newestData.getEndTime(), 1))); } map.put("endTime", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); return map; })); log.info("携稳接口响应数据(塔吊循环):devSn:{},rs:{}", devSn, JSON.toJSONString(realTimeData)); Integer code = realTimeData.getInteger("code"); // code校验是否成功请求 if (code == HttpStatus.OK.value()) { JSONArray dataArray = realTimeData.getJSONArray("data"); if (CollUtil.isNotEmpty(dataArray)) { // 解析请求到的参数,保存到我们的数据库 for (Object o : dataArray) { TowerCycleDataDto dto = BeanUtil.toBean(o, TowerCycleDataDto.class); TowerWorkCycle data = new TowerWorkCycle(); data.setDevSn(dev.getDevSn()); data.setDevName(dev.getDevName()); data.setProjectSn(dev.getProjectSn()); data.setStartTime(DateUtil.parse(dto.getStartTime())); data.setEndTime(DateUtil.parse(dto.getEndTime())); data.setAddTime(DateUtil.parse(dto.getSystemTime())); data.setWorkTime(String.valueOf(DateUtil.between(data.getStartTime(), data.getEndTime(), DateUnit.SECOND))); data.setLoading(Convert.toStr(dto.getCycleMaximumWeight())); data.setWorkMaxForce(Convert.toStr(dto.getCycleMaximumTorque())); Long maximumHeight = dto.getMaximumHeight(); if (maximumHeight != null) { data.setMaxHeight(Convert.toStr(maximumHeight / 10)); } Long minimumHeight = dto.getMinimumHeight(); if (minimumHeight != null) { data.setMinHeight(Convert.toStr(minimumHeight / 10)); } Long maximumRange = dto.getMaximumRange(); if (maximumRange != null) { data.setMaxRange(Convert.toStr(maximumRange / 10)); } Long minimumRange = dto.getMinimumRange(); if (minimumRange != null) { data.setMinRange(Convert.toStr(minimumRange / 10)); } Long liftingPointAngle = dto.getLiftingPointAngle(); if (liftingPointAngle != null) { data.setSlingStartRotation(Convert.toStr(liftingPointAngle / 10)); } Long unloadingPointAngle = dto.getUnloadingPointAngle(); if (unloadingPointAngle != null) { data.setSlingEndRotation(Convert.toStr(unloadingPointAngle / 10)); } Long liftingPointRange = dto.getLiftingPointRange(); if (liftingPointRange != null) { data.setSlingStartRange(Convert.toStr(liftingPointRange / 10)); } Long unloadingPointRange = dto.getUnloadingPointRange(); if (unloadingPointRange != null) { data.setSlingEndRange(Convert.toStr(unloadingPointRange / 10)); } Long liftingPointHeight = dto.getLiftingPointHeight(); if (liftingPointHeight != null) { data.setSlingStartHeight(Convert.toStr(liftingPointHeight / 10)); } Long unloadingPointHeight = dto.getUnloadingPointRange(); if (unloadingPointHeight != null) { data.setSlingEndHeight(Convert.toStr(unloadingPointHeight / 10)); } towerWorkCycleService.addTowerWorkCycle(data); } } else { log.info("塔吊循环设备sn:{},当前无数据!", devSn); } } else { log.error("塔吊循环设备sn:{},请求失败!当前code:{},msg:{}", devSn, code, realTimeData.getString("msg")); } } /** * 获取塔吊数据(小萨) 每5分钟触发任务 */ @SchedulerLock(name = "getXiaosaTowerData", lockAtMostFor = 1000 * 60 * 5, lockAtLeastFor = 1000 * 60 * 3) @Scheduled(cron = "0 0/5 * * * ?") @RequestMapping("getXiaosaTowerData") public void getXiaosaTowerData() { try { log.info("获取塔吊数据(小萨)开始任务"); List projects = projectMapper.selectList(new LambdaQueryWrapper() .eq(Project::getEnableXiaosa, 1) ); for (Project project : projects) { // 获取设备列表 List devList = towerMapper.selectList(new LambdaQueryWrapper() .eq(Tower::getProjectSn, project.getProjectSn())); Map devMap = devList.stream().collect(Collectors.toMap(Tower::getDevSn, Function.identity(), (o1, o2) -> o1)); if (CollUtil.isEmpty(devList)) { continue; } JSONObject body = new JSONObject(); body.put("appKey", project.getXiaosaAppKey()); body.put("appSecret", project.getXiaosaAppSecret()); String url = "https://api.open.ixiaosa.com/auth/app_access_token"; log.info("获取塔吊数据(小萨)的token的url:{},body:{}", url, JSON.toJSONString(body)); String result = HttpRequest.post(url) .body(JSON.toJSONString(body)) .timeout(2000) .execute() .body(); log.info("获取塔吊数据(小萨)的token的result:{}", result); if (StrUtil.isBlank(result)) { continue; } com.gexin.fastjson.JSONObject rootJo = JSON.parseObject(result); if (!Objects.equals(rootJo.getBoolean("success"), true)) { continue; } String tokenHeader = "Bearer " + rootJo.getJSONObject("data").getString("appAccessToken"); String xiaosaProjectId = project.getXiaosaProjectId(); url = "https://api.device.open.ixiaosa.com/data/list_crane_param_data/" + xiaosaProjectId; log.info("萨达 查询项目下塔机参数数据url:{}", url); result = HttpRequest.get(url) .header("Authorization", tokenHeader) .execute().body(); log.info("萨达 查询项目下塔机参数数据result:{}", result); Map projectCraneId2DevSnMap = new HashMap<>(); rootJo = JSON.parseObject(result); if (!Objects.equals(rootJo.getBoolean("success"), true)) { continue; } com.gexin.fastjson.JSONArray jsonArray = rootJo.getJSONArray("data"); for (int i = 0; i < jsonArray.size(); i++) { com.gexin.fastjson.JSONObject jsonObject = jsonArray.getJSONObject(i); Tower tower = devMap.get(jsonObject.getString("deviceSn")); if (tower == null) { continue; } projectCraneId2DevSnMap.put(jsonObject.getString("projectCraneId"), tower.getDevSn()); //修改塔吊设备信息 //projectId 项目 ID String //projectCraneId 项目塔机 ID String //projectCraneNum 塔机名称/编号 String //craneType 塔机类型 String FlatArm:平臂,SwingArm:动臂,Tower:塔头 //jibArmLength 起重臂长 Float m //balanceArmLength 平衡臂长 Float m //craneHeight 塔机高度 Float m //craneCapHeight 塔机塔帽高 Float m //longitude 经度 Double ° //latitude 纬度 Double ° // x 相对坐标 X Float // y 相对坐标 Y Float //standardArmLength 标准臂长 Float m //maxRadiusLoad 最大幅度起重量 Float t //ratedLoad 额定吊重 Float t tower.setForearmLength(jsonObject.getDouble("jibArmLength")); tower.setPosteriorArmLength(jsonObject.getDouble("balanceArmLength")); tower.setLongtitude(jsonObject.getString("longitude")); tower.setLatitude(jsonObject.getString("latitude")); tower.setRelatedX(jsonObject.getString("x")); tower.setRelatedY(jsonObject.getString("y")); towerMapper.updateById(tower); } if (CollUtil.isEmpty(projectCraneId2DevSnMap)) { continue; } //保存塔吊实时数据 saveTowerCurrentDataForXiaoSa(tokenHeader, xiaosaProjectId, devMap, projectCraneId2DevSnMap); //保存塔吊循环数据 saveTowerWorkCycleForXiaoSa(tokenHeader, xiaosaProjectId, project.getProjectSn(),devMap, projectCraneId2DevSnMap); } } catch (HttpException e) { log.error("获取塔吊数据(小萨)开始任务err"+e); } } /** * 保存塔吊循环数据(小萨) * * @param tokenHeader * @param xiaosaProjectId * @param projectSn * @param projectCraneId2DevSnMap */ private void saveTowerWorkCycleForXiaoSa(String tokenHeader, String xiaosaProjectId, String projectSn, Map devMap, Map projectCraneId2DevSnMap) { String url = "https://api.device.open.ixiaosa.com/data/list_crane_work_data/" + xiaosaProjectId; log.info("萨达 查询项目下塔机实时吊装循环数据url:{}", url); String result = HttpRequest.get(url) .header("Authorization", tokenHeader) .execute().body(); log.info("萨达 查询项目下塔机实时吊装循环数据result:{}", result); com.gexin.fastjson.JSONObject rootJo = JSON.parseObject(result); if (!Objects.equals(rootJo.getBoolean("success"), true)) { return; } com.gexin.fastjson.JSONArray jsonArray1 = rootJo.getJSONArray("data"); List datas = new ArrayList<>(); if (CollUtil.isNotEmpty(jsonArray1)) { for (int i = 0; i < jsonArray1.size(); i++) { com.gexin.fastjson.JSONObject json = jsonArray1.getJSONObject(i); String xiansaId = json.getString("id"); int count = towerWorkCycleService.count(new LambdaQueryWrapper() .eq(TowerWorkCycle::getXiaoSaId, xiansaId)); if (count > 0) { continue; } TowerWorkCycle data = new TowerWorkCycle(); // 1. projectCraneId → devSn(设备识别码) data.setDevSn(projectCraneId2DevSnMap.get(json.getString("projectCraneId"))); Tower tower = devMap.get(data.getDevSn()); data.setDevName(tower.getDevName()); // 2. projectCraneNum(项目塔机编号/名称,无直接对应字段,可存储到额外字段或忽略) // 如果 towerWorkCycle 有类似 craneName 的字段,可以设置: // t.setCraneName(json.getString("projectCraneNum")); // 3. workLoadingType(吊装类型,2:有吊重,无直接对应字段,可用于判断是否设置吊重) // int workLoadingType = json.getInt("workLoadingType"); // if (workLoadingType == 2) { // 有吊重时,设置相关参数 // } data.setLoading(String.valueOf(Double.parseDouble(json.getString("maxLoadWeight")) * 1000)); // t → kg // 4. upTime → startTime(起吊时间) data.setStartTime(DateUtil.parseDateTime(json.getString("upTime"))); // 5. upAngle → slingStartRotation(起吊回转角度) data.setSlingStartRotation(json.getString("upAngle")); // 6. upRadius → slingStartRange(起吊幅度) data.setSlingStartRange(json.getString("upRadius")); // 7. upHookHeight → slingStartHeight(起吊吊钩高度) data.setSlingStartHeight(json.getString("upHookHeight")); // 8. upLoadWeight(起吊吊重,无直接对应字段,可结合 maxLoadWeight 使用) // 9. upSafeLoad(起吊安全吊重,无直接对应字段) // 10. upTorquePercent(起吊力矩百分比,无直接对应字段) // 11. upFalls → workMultiple(起吊吊绳倍率) data.setWorkMultiple(json.getInteger("upFalls")); // 12. upElevationAngle(起吊俯仰角度,无直接对应字段) // 13. upWindSpeed(起吊风速,用于 maxWindSpeed 计算) double upWindSpeed = json.containsKey("upWindSpeed") ? json.getDouble("upWindSpeed") : 0; // 14. maxTime(力矩最大点记录时间,无直接对应字段) // 15. maxAngle(用于计算 maxAngle/minAngle) double maxAngle = json.getDouble("maxAngle"); // 16. maxRadius(用于计算 maxRange/minRange) double maxRadius = json.getDouble("maxRadius"); // 17. maxHookHeight(用于计算 maxHeight/minHeight) double maxHookHeight = json.getDouble("maxHookHeight"); // 19. maxSafeLoad(最大安全吊重,无直接对应字段) // 20. maxTorquePercent → peakLoad(最大力矩百分比) data.setPeakLoad(json.getString("maxTorquePercent")); // 21. maxFalls(最大吊绳倍率,无直接对应字段) // 22. maxElevationAngle(最大俯仰角度,无直接对应字段) // 23. maxWindSpeed(用于计算 maxWindSpeed) double maxWindSpeed = json.containsKey("maxWindSpeed") ? json.getDouble("maxWindSpeed") : 0; // 24. downTime → endTime(落吊时间) data.setEndTime(DateUtil.parseDateTime(json.getString("downTime"))); // 25. downAngle → slingEndRotation(落吊回转角度) data.setSlingEndRotation(json.getString("downAngle")); // 26. downRadius → slingEndRange(落吊幅度) data.setSlingEndRange(json.getString("downRadius")); // 27. downHookHeight → slingEndHeight(落吊吊钩高度) data.setSlingEndHeight(json.getString("downHookHeight")); // 28. downLoadWeight(落吊吊重,无直接对应字段) // 29. downSafeLoad(落吊安全吊重,无直接对应字段) // 30. downTorquePercent(落吊力矩百分比,无直接对应字段) // 31. downFalls(落吊吊绳倍率,无直接对应字段) // 32. downElevationAngle(落吊俯仰角度,无直接对应字段) // 33. downWindSpeed(用于计算 maxWindSpeed) double downWindSpeed = json.containsKey("downWindSpeed") ? json.getDouble("downWindSpeed") : 0; // 34. loadTime → workTime(起吊时长,单位 s) data.setWorkTime(String.valueOf(DateUtil.between(data.getStartTime(), data.getEndTime(), DateUnit.SECOND))); // 35. realLoadWeight(实际吊重,无直接对应字段) // 计算最大/最小角度、幅度、高度 double upAngle = json.getDouble("upAngle"); double downAngle = json.getDouble("downAngle"); data.setMaxAngle(String.valueOf(Math.max(upAngle, Math.max(maxAngle, downAngle)))); data.setMinAngle(String.valueOf(Math.min(upAngle, Math.min(maxAngle, downAngle)))); double upRadius = json.getDouble("upRadius"); double downRadius = json.getDouble("downRadius"); data.setMaxRange(String.valueOf(Math.max(upRadius, Math.max(maxRadius, downRadius)))); data.setMinRange(String.valueOf(Math.min(upRadius, Math.min(maxRadius, downRadius)))); double upHookHeight = json.getDouble("upHookHeight"); double downHookHeight = json.getDouble("downHookHeight"); data.setMaxHeight(String.valueOf(Math.max(upHookHeight, Math.max(maxHookHeight, downHookHeight)))); data.setMinHeight(String.valueOf(Math.min(upHookHeight, Math.min(maxHookHeight, downHookHeight)))); // 计算最大风速 data.setMaxWindSpeed(String.valueOf(Math.max(upWindSpeed, Math.max(maxWindSpeed, downWindSpeed)))); data.setProjectSn(projectSn); data.setAddTime(new Date()); data.setXiaoSaId(xiansaId); datas.add(data); } } if (CollUtil.isNotEmpty(datas)) { towerWorkCycleService.saveBatch(datas); } } /** * 保存塔吊实时数据(小萨) * * @param tokenHeader * @param xiaosaProjectId * @param devMap * @param projectCraneId2DevSnMap */ private void saveTowerCurrentDataForXiaoSa(String tokenHeader, String xiaosaProjectId, Map devMap, Map projectCraneId2DevSnMap) { String url = "https://api.device.open.ixiaosa.com/data/list_crane_real_time_data/" + xiaosaProjectId; log.info("萨达 查询项目下塔机实时数据url:{}", url); String result = HttpRequest.get(url) .header("Authorization", tokenHeader) .execute().body(); log.info("萨达 查询项目下塔机实时数据result:{}", result); com.gexin.fastjson.JSONObject rootJo = JSON.parseObject(result); if (!Objects.equals(rootJo.getBoolean("success"), true)) { return; } com.gexin.fastjson.JSONArray jsonArray1 = rootJo.getJSONArray("data"); List datas = new ArrayList<>(); if (CollUtil.isNotEmpty(jsonArray1)) { for (int i = 0; i < jsonArray1.size(); i++) { //实时数据 // "time": "2025-06-27 17:56:52", // "projectCraneId": "1928738212753227778", // "currentCraneHeight": 0.0, // "radius": 23.94, // "hookHeight": 37.64, // "angle": 307.46, // "loadWeight": 0.67, // "safeLoad": 6.0, // "torque": 16.0398, // "torquePercent": 11.24, // "falls": 2, // "elevationAngle": 0.0, // "windSpeed": 0.0, // "infractionTypeList": "", // "craneDriverName": "", // "craneDriverIdCard": "", // "projectCraneNum": "1#" com.gexin.fastjson.JSONObject json = jsonArray1.getJSONObject(i); TowerCurrentData data = new TowerCurrentData(); data.setReciveTime(DateUtil.parseDateTime(json.getString("time"))); data.setStartTime(data.getReciveTime()); data.setDevSn(projectCraneId2DevSnMap.get(json.getString("projectCraneId"))); Tower tower = devMap.get(data.getDevSn()); data.setDevName(tower.getDevName()); data.setHeight(json.getString("hookHeight")); data.setRanger(json.getString("radius")); data.setAngle(json.getString("angle")); data.setLoading(Optional.ofNullable(json.getDouble("loadWeight")).map(m -> m * 1000 + "").orElse(null)); if (json.getDouble("loadWeight") != null && json.getDouble("safeLoad") != null && json.getDouble("safeLoad").compareTo(0D) != 0) { data.setLoadRatio(NumberUtil.roundStr(json.getDouble("loadWeight") / json.getDouble("safeLoad"), 4)); } data.setTorque(json.getString("torque")); data.setTorqueRatio(json.getString("torquePercent")); data.setRate(json.getString("falls")); data.setObliguity(json.getString("elevationAngle")); data.setWindspeed(json.getString("windSpeed")); data.setDriverName(json.getString("craneDriverName")); data.setDriverIdCard(json.getString("craneDriverIdCard")); data.setRealFlag("1"); data.setNoError(1); String infractionTypeList = json.getString("infractionTypeList"); Integer noAlarm = 1; if (StrUtil.isNotBlank(infractionTypeList)) { for (String alarmKey : StrUtil.split(infractionTypeList, ",")) { switch (alarmKey) { case "Collision_LeftRotationAlert": data.setMultiNegAlarm(1); break; case "Collision_RightRotationAlert": data.setMultiPosAlarm(1); break; case "Collision_RadiusForthAlert": data.setMultiOutAlarm(1); break; case "Collision_RadiusBackAlert": data.setMultiBackAlarm(1); break; case "RestrictedArea_LeftRotationAlert": data.setForbidEntryNegAlarm(1); break; case "RestrictedArea_RightRotationAlert": data.setForbidEntryPosAlarm(1); break; case "RestrictedArea_RadiusForthAlert": data.setForbidSuspend4OutAlarm(1); break; case "RestrictedArea_RadiusBackAlert": data.setForbidSuspend4BackAlarm(1); break; case "AngleRestrictedArea_LeftRotationAlert": data.setForbidSuspend2NegAlarm(1); break; case "AngleRestrictedArea_RightRotationAlert": data.setForbidSuspend2PosAlarm(1); break; case "Limit_LeftRotationAlert": data.setNegAngleAlarm(1); break; case "Limit_RightRotationAlert": data.setPosAngleAlarm(1); break; case "Limit_RadiusForthAlert": data.setMaxRangeAlarm(1); break; case "Limit_RadiusBackAlert": data.setMinRangeAlarm(1); break; case "Limit_OfHeightTopAlert": data.setHeightAlarm(1); break; case "Limit_HeightBottomAlert": data.setHeightLowerAlarm(1); break; case "Limit_LoadAlert": data.setMomentAlarm(1); break; case "Limit_TorqueAlert": data.setMomentAlarm(1); break; case "Limit_WindSpeedAlert": data.setWindSpeedAlarm(1); break; } } noAlarm = 0; } data.setNoAlarm(noAlarm); data.setProjectSn(tower.getProjectSn()); datas.add(data); } } if (CollUtil.isNotEmpty(datas)) { towerCurrentDataService.saveBatch(datas); } } }