730 lines
37 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}