package com.zhgd.xmgl.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zhgd.redis.lock.RedisRepository; import com.zhgd.xmgl.modules.project.entity.Project; import com.zhgd.xmgl.modules.project.mapper.ProjectMapper; import com.zhgd.xmgl.modules.environment.entity.RainAlarm; import com.zhgd.xmgl.modules.environment.entity.RainDev; import com.zhgd.xmgl.modules.environment.entity.RainRecord; import com.zhgd.xmgl.modules.environment.service.IRainAlarmService; import com.zhgd.xmgl.modules.environment.service.IRainDevService; import com.zhgd.xmgl.modules.environment.service.IRainRecordService; import com.zhgd.xmgl.util.RenZhiUtil; import lombok.extern.slf4j.Slf4j; import net.javacrumbs.shedlock.core.SchedulerLock; import org.jetbrains.annotations.Nullable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.scheduling.annotation.Scheduled; 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 @RestController @RequestMapping("xmgl/task") public class RainTask { public static final String REDIS_RAIN_ALARM_TASK_START_TIME = "getRainAlarmTaskStartTime"; @Resource @Lazy private IRainRecordService rainRecordService; @Resource @Lazy private IRainAlarmService rainAlarmService; @Resource @Lazy private IRainDevService rainDevService; @Lazy @Autowired private ProjectMapper projectMapper; @Lazy @Autowired private RedisRepository redisRepository; /** * 获取实时数据 */ @Scheduled(cron = "0 */2 * * * ?") @SchedulerLock(name = "getRainRecordTask", lockAtMostFor = 1000 * 60, lockAtLeastFor = 1000 * 60) @RequestMapping("getRainRecordTask") public void getRainRecordTask() { List projectList = projectMapper.selectList(new LambdaQueryWrapper() .ne(Project::getJnrzckAccount, "") .ne(Project::getJnrzckPw, "") ); for (Project project : projectList) { try { saveAllRecord(project); } catch (Exception e) { log.error("", e); } } } private void saveAllRecord(Project project) { List devs = rainDevService.list(new LambdaQueryWrapper().eq(RainDev::getProjectSn, project.getProjectSn())); if (CollUtil.isEmpty(devs)) { return; } Map devSnMap = devs.stream().collect(Collectors.toMap(RainDev::getDevSn, Function.identity())); JSONArray datas = RenZhiUtil.getRealTimeDataByDeviceAddr(StrUtil.join(",", devs.stream().map(RainDev::getDevSn).collect(Collectors.toList())), project.getJnrzckAccount(), project.getJnrzckPw()); if (CollUtil.isEmpty(datas)) { log.info("获取实时数据为空,项目名称:{}", project.getProjectName()); return; } List records = new ArrayList<>(); for (int i = 0; i < datas.size(); i++) { JSONObject dataJo = datas.getJSONObject(i); JSONArray dataItemJa = dataJo.getJSONArray("dataItem"); String deviceAddr = dataJo.getString("deviceAddr"); RainRecord record = new RainRecord(); for (int j = 0; j < dataItemJa.size(); j++) { JSONObject itemJo = dataItemJa.getJSONObject(j); Integer nodeId = itemJo.getInteger("nodeId"); JSONArray registerItemJa = itemJo.getJSONArray("registerItem"); if (nodeId == 1) { //风力、风速 record.setWindForce(getDouble(registerItemJa, 0)); record.setWindSpeed(getDouble(registerItemJa, 1)); } else if (nodeId == 2) { record.setWindDirection(getString(registerItemJa, 0)); } else if (nodeId == 20) { record.setAccumulatedRainfall(getDouble(registerItemJa, 0)); } else if (nodeId == 21) { record.setInstantaneousRainfall(getDouble(registerItemJa, 0)); record.setCurrentRainfall(getDouble(registerItemJa, 1)); } else if (nodeId == 22) { record.setDailyRainfall(getDouble(registerItemJa, 0)); } else if (nodeId == 11) { record.setAirTemperature(getDouble(registerItemJa, 0)); record.setAirHumidity(getDouble(registerItemJa, 1)); } else if (nodeId == 14) { record.setAtmosphericPressure(getDouble(registerItemJa, 0)); } } record.setRecordTime(new Date(dataJo.getLong("timeStamp"))); record.setDevSn(deviceAddr); record.setProjectSn(devSnMap.get(deviceAddr).getProjectSn()); records.add(record); } rainRecordService.saveBatch(records); } private String getString(JSONArray registerItemJa, int index) { return Optional.ofNullable(registerItemJa.getJSONObject(index)).map(o -> o.getString("data")).orElse(null); } @Nullable private Double getDouble(JSONArray registerItemJa, int index) { return Optional.ofNullable(registerItemJa.getJSONObject(index)).map(o -> o.getDouble("data")).orElse(null); } /** * 获取报警数据 */ @Scheduled(cron = "0 */6 * * * ?") @SchedulerLock(name = "getRainAlarmTask", lockAtMostFor = 1000 * 60 * 5, lockAtLeastFor = 1000 * 60 * 3) @RequestMapping("getRainAlarmTask") public void getRainAlarmTask() { List projectList = projectMapper.selectList(new LambdaQueryWrapper() .ne(Project::getJnrzckAccount, "") .ne(Project::getJnrzckPw, "") ); String start; Object o = redisRepository.get(REDIS_RAIN_ALARM_TASK_START_TIME); if (o != null) { start = o.toString(); } else { start = DateUtil.format(DateUtil.offsetMinute(new Date(), -5), "yyyy-MM-dd HH:mm"); } String end = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm"); redisRepository.set(REDIS_RAIN_ALARM_TASK_START_TIME, end); for (Project project : projectList) { try { saveAllAlarm(project, start, end); } catch (Exception e) { log.error("", e); } } } private void saveAllAlarm(Project project, String start, String end) { List devs = rainDevService.list(new LambdaQueryWrapper().eq(RainDev::getProjectSn, project.getProjectSn())); if (CollUtil.isEmpty(devs)) { return; } Map devSnMap = devs.stream().collect(Collectors.toMap(RainDev::getDevSn, Function.identity())); ArrayList alarms = new ArrayList<>(); String token = RenZhiUtil.getToken(project.getJnrzckAccount(), project.getJnrzckPw()); for (RainDev dev : devs) { for (Integer nodeId : Arrays.asList(1, 2, 20, 21, 22, 11, 14)) { JSONArray dataJa = RenZhiUtil.getAlarmRecordList(dev.getDevSn(), token, nodeId, start, end); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } if (CollUtil.isEmpty(dataJa)) { continue; } for (int j = 0; j < dataJa.size(); j++) { JSONObject jo = dataJa.getJSONObject(j); RainAlarm alarm = new RainAlarm(); alarm.setAlarmContent(getAlarmContent(jo)); alarm.setAlarmVal(jo.getDouble("dataValue")); alarm.setProjectSn(dev.getProjectSn()); alarm.setAlarmTime(new Date(jo.getLong("recordTime"))); alarms.add(alarm); } } } rainAlarmService.saveBatch(alarms); } private String getAlarmContent(JSONObject jo) { /* alarmLevel int 报警级别: 25 1: 报警(超报警上限) 2: 预警(超预警上限) 3: 预警(超预警下限) 4:报警(超报警下限) -1: 离线报警 -2:遥调(开关量)报警 dataValue Double 报警值 alarmRange String 报警限值 */ String factorName = jo.getString("factorName"); Integer alarmLevel = jo.getInteger("alarmLevel"); if (Objects.equals(alarmLevel, 1) || Objects.equals(alarmLevel, 2) || Objects.equals(alarmLevel, 3) || Objects.equals(alarmLevel, 4)) { return StrUtil.format("{} {},报警值:{},报警限值:{}", factorName, getAlarmLevelStr(alarmLevel), jo.getDouble("dataValue"), jo.getString("alarmRange")); } else { return StrUtil.format("{} {},报警值:{}", factorName, getAlarmLevelStr(alarmLevel), jo.getString("dataValue")); } } private String getAlarmLevelStr(Integer alarmLevel) { String s = ""; switch (alarmLevel) { case 1: s = "报警(超报警上限)"; case 2: s = "预警(超预警上限)"; case 3: s = "预警(超预警下限)"; case 4: s = "报警(超报警下限)"; case -1: s = "离线报警"; case -2: s = "遥调(开关量)报警"; } return s; } }