730 lines
37 KiB
Java
730 lines
37 KiB
Java
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<Project> projects = projectMapper.selectList(new LambdaQueryWrapper<Project>()
|
||
.isNotNull(Project::getXiwonAppId)
|
||
.isNotNull(Project::getXiwonAppSecret)
|
||
);
|
||
for (Project project : projects) {
|
||
// 获取设备列表
|
||
List<Tower> devList = towerMapper.selectList(new LambdaQueryWrapper<Tower>()
|
||
.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<TowerCurrentData>().eq(TowerCurrentData::getDevSn, devSn).orderByDesc(TowerCurrentData::getXiewenId).last("limit 1"));
|
||
// 请求参数
|
||
Map<String, Object> 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<TowerWorkCycle>().eq(TowerWorkCycle::getDevSn, devSn).orderByDesc(TowerWorkCycle::getEndTime).last("limit 1"));
|
||
// 请求参数
|
||
Map<String, Object> 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<Project> projects = projectMapper.selectList(new LambdaQueryWrapper<Project>()
|
||
.eq(Project::getEnableXiaosa, 1)
|
||
);
|
||
for (Project project : projects) {
|
||
// 获取设备列表
|
||
List<Tower> devList = towerMapper.selectList(new LambdaQueryWrapper<Tower>()
|
||
.eq(Tower::getProjectSn, project.getProjectSn()));
|
||
Map<String, Tower> 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<String, String> 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<String, Tower> devMap, Map<String, String> 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<TowerWorkCycle> 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<TowerWorkCycle>()
|
||
.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<String, Tower> devMap, Map<String, String> 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<TowerCurrentData> 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);
|
||
}
|
||
}
|
||
}
|