自动化任务

master
lld 2026-03-06 03:17:31 +08:00
parent 955adba5cb
commit 2b140bd180
26 changed files with 2842 additions and 225 deletions

View File

@ -0,0 +1,32 @@
package com.agri.common.enums;
/**
* @ClassName TempCommandStatus
* @Description TODO
* @Author lld
* @Date 2026/3/6 2:46
* @Version 1.0
*/
public enum TempCommandStatus {
OPEN(1, "下发开指令"),
CLOSE(2, "下发关指令"),
NO_OPERATE(0, "不操作");
private final int code;
private final String desc;
TempCommandStatus(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
// 使用status.getCode() → 1/2/0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,55 @@
package com.agri.common.utils;
/**
* @ClassName dd
* @Description TODO
* @Author lld
* @Date 2026/3/6 1:44
* @Version 1.0
*/
import org.springframework.beans.factory.annotation.Value;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* +
*/
public class RollerTimeCalculator {
// 基础常量:固化到工具类,统一维护
@Value("${agri.per-lap.len}")
private static BigDecimal perLapLen;
@Value("${agri.per-lap.sec}")
private static BigDecimal perLapSec;
// 私有化构造器,禁止实例化
private RollerTimeCalculator() {}
/**
*
* @param targetLen cm
* @return
*/
public static int calculateRunTime(BigDecimal targetLen) {
// 边界处理长度≤0时返回0
if (targetLen == null || targetLen.compareTo(BigDecimal.ZERO)<=0) {
return 0;
}
// 核心公式:时间 = (长度 / 每圈长度) × 每圈时间
BigDecimal cycleCount = targetLen.divide(perLapLen,2, RoundingMode.HALF_UP);
return cycleCount.multiply(perLapSec).setScale(2, RoundingMode.HALF_UP).intValue(); // 四舍五入取整
}
/**
*
* /perLapLenperLapSec
*/
/* public static long calculateRunTimeWithConfig(double targetLen, String imei) {
// 从配置表/缓存读取该设备的单圈长度、单圈时间(适配不同设备参数差异)
Double deviceCmPerCycle = ConfigCache.getVal(imei + "_perLapLen", perLapLen);
Long deviceSecPerCycle = ConfigCache.getVal(imei + "_sec_per_cycle", perLapSec);
return Math.round(targetLen / deviceCmPerCycle * deviceSecPerCycle);
}*/
}

View File

@ -0,0 +1,42 @@
package com.agri.common.utils;
import com.agri.common.enums.TempCommandStatus;
import java.math.BigDecimal;
/**
*
*/
public class TempJudgeUtil {
// 条件参考温度允许的上下误差(抽成常量,后续可配置化)
public static final BigDecimal TEMP_ERROR_RANGE = java.math.BigDecimal.ONE;
/**
*
*
* @param currentTemp DTU
* @param refTemp sys_auto_termtemp
* @return OPEN()/CLOSE()/NO_OPERATE()
*/
public static TempCommandStatus judgeTempCommand(BigDecimal currentTemp, BigDecimal refTemp) {
// 1. 空值校验企业级必备避免NPE
if (currentTemp == null || refTemp == null) {
return TempCommandStatus.NO_OPERATE;
}
// 2. 计算当前温度与参考温度的差值(当前温度 - 参考温度)
BigDecimal tempDiff = currentTemp.subtract(refTemp);
// 3. 按规则判断状态
if (tempDiff.compareTo(TEMP_ERROR_RANGE) > 0) {
// 当前温度 > 参考温度 + 误差 → 下发开指令
return TempCommandStatus.OPEN;
} else if (tempDiff.compareTo(TEMP_ERROR_RANGE.negate()) < 0) {
// 当前温度 < 参考温度 - 误差 → 下发关指令
return TempCommandStatus.CLOSE;
} else {
// 差值在[-误差, +误差]范围内 → 不操作
return TempCommandStatus.NO_OPERATE;
}
}
}

View File

@ -0,0 +1,41 @@
package com.agri.common.utils;
/**
* @ClassName TimeConvertUtil
* @Description TODO
* @Author lld
* @Date 2026/3/6 2:16
* @Version 1.0
*/
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class TimeConvertUtil {
// 定义常用时间格式(企业级:固化为常量,避免重复创建)
public static final DateTimeFormatter DEFAULT_DATETIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* LocalDateTimeyyyy-MM-dd HH:mm:ss
*/
public static LocalDateTime strToLocalDateTime(String timeStr) {
// 空值/空白校验(企业级必备)
if (timeStr == null || timeStr.trim().isEmpty()) {
return null;
}
// 标准格式直接解析
return LocalDateTime.parse(timeStr.trim(), DEFAULT_DATETIME_FORMAT);
}
/**
*
*/
public static LocalDateTime strToLocalDateTimeSafe(String timeStr) {
try {
return strToLocalDateTime(timeStr);
} catch (Exception e) {
// 日志记录转换失败原因(企业级:必加)
System.err.println("时间字符串转换失败str=" + timeStr + ",错误:" + e.getMessage());
return null;
}
}
}

View File

@ -0,0 +1,46 @@
package com.agri.common.utils;
/**
* @ClassName TimeRangeUtil
* @Description TODO
* @Author lld
* @Date 2026/3/6 2:09
* @Version 1.0
*/
import java.time.LocalDateTime;
import java.time.LocalTime;
public class TimeRangeUtil {
/**
* dtuauto_term
*/
public static boolean isTimeInRange(LocalDateTime dtuTime, LocalDateTime startTime, LocalDateTime endTime) {
if (dtuTime == null || startTime == null || endTime == null) {
return false;
}
LocalTime currentTime = dtuTime.toLocalTime();
LocalTime beforeTime = startTime.toLocalTime();
LocalTime afterTime = endTime.toLocalTime();
if (startTime.isBefore(endTime)) {
// 正常时段08:00:00 - 18:00:00
return !currentTime.isBefore(beforeTime) && !currentTime.isAfter(afterTime);
} else {
// 跨天时段22:00:00 - 06:00:00
return currentTime.isAfter(beforeTime) || currentTime.isBefore(afterTime);
}
}
/**
* ts
*/
public static boolean isTsInRange(long ts, LocalDateTime startTime, LocalDateTime endTime) {
LocalDateTime dtuTime = LocalDateTime.ofInstant(
java.time.Instant.ofEpochMilli(ts),
java.time.ZoneId.systemDefault()
);
return isTimeInRange(dtuTime, startTime, endTime);
}
}

View File

@ -4,14 +4,8 @@ import com.agri.common.utils.wechat.WxUtil;
import com.agri.framework.config.MqttConfig;
import com.agri.framework.manager.MqttAutoOffManager;
import com.agri.framework.manager.MqttSubscriptionManager;
import com.agri.system.domain.SysAgriLimit;
import com.agri.system.domain.SysDevOperLog;
import com.agri.system.service.ISysAgriLimitService;
import com.agri.system.service.ISysDevOperLogService;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.lang3.ObjectUtils;
import org.checkerframework.checker.units.qual.A;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -19,17 +13,13 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
/**
*

View File

@ -38,6 +38,10 @@
<groupId>com.agri</groupId>
<artifactId>agri-system</artifactId>
</dependency>
<dependency>
<groupId>com.agri</groupId>
<artifactId>agri-framework</artifactId>
</dependency>
</dependencies>

View File

@ -1,7 +1,25 @@
package com.agri.quartz.task;
import com.agri.common.enums.TempCommandStatus;
import com.agri.common.utils.TempJudgeUtil;
import com.agri.common.utils.TimeConvertUtil;
import com.agri.common.utils.TimeRangeUtil;
import com.agri.system.domain.SysAgriInfo;
import com.agri.system.domain.vo.RollerTermVO;
import com.agri.system.service.ISysAgriInfoService;
import com.agri.system.service.ISysDtuDataService;
import com.agri.system.service.ISysRollerParamService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
*
*
@ -14,4 +32,98 @@ import org.springframework.stereotype.Component;
@Component("rollerAutoTask")
public class RollerAutoTask {
@Autowired
private ISysAgriInfoService agriInfoService;
@Autowired
private ISysDtuDataService dtuDataService;
@Autowired
private ISysRollerParamService rollerParamService;
@Resource
private MqttConfig.MqttMessageSender mqttMessageSender;
public void checkAutoTerm() {
// 查询自动模式的大棚
List<SysAgriInfo> agriInfos = agriInfoService.lambdaQuery()
.select(SysAgriInfo::getImei)
.eq(SysAgriInfo::getWorkMode, 1)
.eq(SysAgriInfo::getIsDeleted, 0)
.list();
if (CollectionUtils.isEmpty(agriInfos)) return;
// 取imei集合
List<String> imeiList = agriInfos.stream().map(SysAgriInfo::getImei).collect(Collectors.toList());
if (CollectionUtils.isEmpty(imeiList)) return;
// 根据imei 查询dtu_data最后一条温度数据
List<Map<String, Object>> dtuDataList = dtuDataService.getLastDtuDataByImeiList(imeiList);
if (CollectionUtils.isEmpty(dtuDataList)) return;
// 根据温湿度imei分组
Map<String, List<Map<String, Object>>> dtuDataByImeiMap = dtuDataList.stream().collect(Collectors.groupingBy(map -> (String) map.get("imei")));
// 获取所有开启自动化模式的大棚列表的卷膜参数和条件设置
List<RollerTermVO> rollerTermList = rollerParamService.getRollerTerms(imeiList);
if (CollectionUtils.isEmpty(rollerTermList)) {
// todo 无参数设置和条件列表直接返回
return;
}
// 按imei分组 → 再按roller分组一步到位
Map<String, Map<String, List<RollerTermVO>>> rollerTermMap = rollerTermList.stream()
.collect(Collectors.groupingBy(
RollerTermVO::getImei,
Collectors.groupingBy(RollerTermVO::getRoller)
));
// 循环所有开启自动化的大棚
for (String imei : imeiList) {
// 获取温湿度指定imei的数据
List<Map<String, Object>> dtuDataInfo = dtuDataByImeiMap.get(imei);
// 该大棚温湿度不存在
if (CollectionUtils.isEmpty(dtuDataInfo)) {
// todo 该大棚下1分钟内无最新温湿度怀疑离线
break;
}
// 最后一条对应imei对应温度
Map<String, Object> dtuData = dtuDataInfo.get(0);
// 获取当前imei下的所有参数设置以及卷膜自动化条件设置
Map<String, List<RollerTermVO>> configTermByRollerMap = rollerTermMap.get(imei);
configTermByRollerMap.forEach((config, terms) ->{
// 每个卷膜分组只会有一个卷膜参数设置,所有取第一个即可
RollerTermVO rollerConfig = terms.get(0);
BigDecimal ventTotalLen = rollerConfig.getVentTotalLen(); // 风口总长
String roller = rollerConfig.getRoller(); // 卷膜
String refTempCode = rollerConfig.getRefTempCode();
BigDecimal reservedLen = rollerConfig.getReservedLen(); // 预留封口
terms.forEach(term -> {
LocalDateTime dtuTime = TimeConvertUtil.strToLocalDateTimeSafe((String) dtuData.get("time"));
if (dtuTime == null) {
return; // 跳过该设备
}
// 判断该温度上报时间是否在该条件设置的时间范围内
boolean inRange = TimeRangeUtil.isTimeInRange(dtuTime, term.getStartTime(), term.getEndTime());
// 在范围内
if (inRange) {
//判断温度是否在
String redTempCode = dtuData.get(refTempCode).toString();
BigDecimal currentTemp = new BigDecimal(dtuData.get(redTempCode).toString());
TempCommandStatus tempCommandStatus = TempJudgeUtil.judgeTempCommand(currentTemp, term.getTemp());
if (tempCommandStatus==TempCommandStatus.OPEN) {
// 开指令
} else if (tempCommandStatus==TempCommandStatus.CLOSE) {
// 关指令
}
}
// 不在掠过
});
});
}
}
}

View File

@ -9,13 +9,14 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.math.BigDecimal;
import java.util.Date;
import java.time.LocalDateTime;
/**
* DTU湿 sys_dtu_data
*
* @author agri
* @date 2025-12-23
* @LocalDateTime 2025-12-23
*/
public class SysDtuData extends BaseEntity
{
@ -36,7 +37,7 @@ public class SysDtuData extends BaseEntity
/** ts转换后的正常时间(由服务端转换入库) */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
@Excel(name = "ts转换后的正常时间(由服务端转换入库)", width = 30, dateFormat = "yyyy-MM-dd")
private Date time;
private LocalDateTime time;
/** 温度1(℃) */
@Excel(name = "温度1(℃)")
@ -104,12 +105,12 @@ public class SysDtuData extends BaseEntity
return ts;
}
public void setTime(Date time)
public void setTime(LocalDateTime time)
{
this.time = time;
}
public Date getTime()
public LocalDateTime getTime()
{
return time;
}

View File

@ -1,20 +1,19 @@
package com.agri.system.domain;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.*;
import com.agri.common.annotation.Excel;
import com.agri.common.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.Getter;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.baomidou.mybatisplus.annotation.TableName;
import com.agri.common.annotation.Excel;
import com.agri.common.core.domain.BaseEntity;
import java.time.LocalDateTime;
/**
* sys_roller_air

View File

@ -1,13 +1,16 @@
package com.agri.system.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.baomidou.mybatisplus.annotation.TableName;
import com.agri.common.annotation.Excel;
import com.agri.common.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.math.BigDecimal;
@ -17,6 +20,7 @@ import java.math.BigDecimal;
* @author lld
* @date 2026-02-27
*/
@Data
@TableName("sys_roller_param")
public class SysRollerParam extends BaseEntity
{
@ -59,92 +63,6 @@ public class SysRollerParam extends BaseEntity
@Excel(name = "最终风口总长")
private BigDecimal ventTotalLen;
public void setId(String id)
{
this.id = id;
}
public String getId()
{
return id;
}
public void setImei(String imei)
{
this.imei = imei;
}
public String getImei()
{
return imei;
}
public void setRoller(String roller)
{
this.roller = roller;
}
public String getRoller()
{
return roller;
}
public void setRefTempCode(String refTempCode)
{
this.refTempCode = refTempCode;
}
public String getRefTempCode()
{
return refTempCode;
}
public void setReservedLen(BigDecimal reservedLen)
{
this.reservedLen = reservedLen;
}
public BigDecimal getReservedLen()
{
return reservedLen;
}
public void setManualTotalLen(BigDecimal manualTotalLen)
{
this.manualTotalLen = manualTotalLen;
}
public BigDecimal getManualTotalLen()
{
return manualTotalLen;
}
public void setAutoTotalLen(BigDecimal autoTotalLen)
{
this.autoTotalLen = autoTotalLen;
}
public BigDecimal getAutoTotalLen()
{
return autoTotalLen;
}
public String getRefTemp() {
return refTemp;
}
public void setRefTemp(String refTemp) {
this.refTemp = refTemp;
}
public BigDecimal getVentTotalLen() {
return ventTotalLen;
}
public void setVentTotalLen(BigDecimal ventTotalLen) {
this.ventTotalLen = ventTotalLen;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -0,0 +1,49 @@
package com.agri.system.domain.vo;
import lombok.Data;
import java.math.BigDecimal;
/**
* @ClassName AgriAutoInfoVo
* @Description TODO
* @Author lld
* @Date 2026/3/5 22:07
* @Version 1.0
*/
@Data
public class AgriAutoInfoVo {
/** 设备IMEI */
private String imei;
/** 大棚名称 */
private String agriName;
/** 工作模式 */
private Integer workMode;
/** 逻辑删除(0-未删1-已删) */
private Integer isDeleted;
/** 卷膜标识 */
private String roller;
/** 参考温度 */
private String refTempCode;
/** 参考温度 */
private String refTemp;
/** 预留风口长度(cm) */
private BigDecimal reservedLen;
/** 手动计算风口总长(cm) */
private BigDecimal manualTotalLen;
/** 自动计算风口总长(cm) */
private BigDecimal autoTotalLen;
private BigDecimal ventTotalLen;
}

View File

@ -0,0 +1,32 @@
package com.agri.system.domain.vo;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* @ClassName RollerTermVO
* @Description TODO
* @Author lld
* @Date 2026/3/6 1:13
* @Version 1.0
*/
// 用于承接rollerParam+autoTerms关联查询的结果
@Data
public class RollerTermVO {
// rollerParam字段
private String imei;
private String roller;
private String refTempCode;
private BigDecimal reservedLen;
private BigDecimal manualTotalLen;
private BigDecimal autoTotalLen;
private BigDecimal ventTotalLen;
// autoTerms字段一对多允许为null
private BigDecimal temp;
private BigDecimal vent;
private LocalDateTime startTime;
private LocalDateTime endTime;
}

View File

@ -1,6 +1,7 @@
package com.agri.system.mapper;
import com.agri.system.domain.SysAgriInfo;
import com.agri.system.domain.vo.AgriAutoInfoVo;
import com.agri.system.domain.vo.AgriInfoView;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@ -71,4 +72,5 @@ public interface SysAgriInfoMapper extends BaseMapper<SysAgriInfo> {
public List<AgriInfoView> findAgriInfoByUser(SysAgriInfo sysAgriInfo);
List<AgriAutoInfoVo> findAgriOfAutoInfo();
}

View File

@ -1,8 +1,11 @@
package com.agri.system.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.agri.system.domain.SysRollerParam;
import com.agri.system.domain.vo.RollerTermVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* Mapper
@ -59,4 +62,7 @@ public interface SysRollerParamMapper extends BaseMapper<SysRollerParam>
* @return
*/
public int deleteSysRollerParamByIds(String[] ids);
List<RollerTermVO> getRollerTerms(@Param("imeiList") List<String> imeiList);
}

View File

@ -1,6 +1,7 @@
package com.agri.system.service;
import com.agri.system.domain.SysAgriInfo;
import com.agri.system.domain.vo.AgriAutoInfoVo;
import com.agri.system.domain.vo.AgriInfoView;
import com.baomidou.mybatisplus.extension.service.IService;
@ -68,4 +69,6 @@ public interface ISysAgriInfoService extends IService<SysAgriInfo> {
public List<AgriInfoView> findAgriInfoByUser(SysAgriInfo sysAgriInfo);
Map<String,Object> addAgriFromMobile(SysAgriInfo sysAgriInfo);
List<AgriAutoInfoVo> findAgriOfAutoInfo();
}

View File

@ -1,11 +1,11 @@
package com.agri.system.service;
import java.util.List;
import com.agri.system.domain.SysAgriAlarmRelation;
import com.agri.system.domain.SysDtuData;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Map;
/**
* DTU湿Service
*
@ -68,4 +68,7 @@ public interface ISysDtuDataService extends IService<SysDtuData>
* @return
*/
public int deleteSysDtuDataById(Long id);
List<Map<String, Object>> getLastDtuDataByImeiList(List<String> imeiList);
}

View File

@ -1,8 +1,10 @@
package com.agri.system.service;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.IService;
import com.agri.system.domain.SysRollerParam;
import com.agri.system.domain.vo.RollerTermVO;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* Service
@ -58,4 +60,7 @@ public interface ISysRollerParamService extends IService<SysRollerParam> {
* @return
*/
public int deleteSysRollerParamById(String id);
List<RollerTermVO> getRollerTerms(List<String> imeiList);
}

View File

@ -1,17 +1,16 @@
package com.agri.system.service.impl;
import com.agri.common.core.domain.entity.SysUser;
import com.agri.common.enums.AgriEnum;
import com.agri.common.utils.DateUtils;
import com.agri.common.utils.SecurityUtils;
import com.agri.common.utils.wechat.WxUtil;
import com.agri.system.domain.SysAgriInfo;
import com.agri.system.domain.SysUserAgri;
import com.agri.system.domain.vo.AgriAutoInfoVo;
import com.agri.system.domain.vo.AgriInfoView;
import com.agri.system.mapper.SysAgriInfoMapper;
import com.agri.system.service.ISysAgriInfoService;
import com.agri.system.service.ISysUserAgriService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -258,6 +257,9 @@ public class SysAgriInfoServiceImpl extends ServiceImpl<SysAgriInfoMapper, SysAg
}
@Override
public List<AgriAutoInfoVo> findAgriOfAutoInfo() {
return baseMapper.findAgriOfAutoInfo();
}
}

View File

@ -1,13 +1,18 @@
package com.agri.system.service.impl;
import java.util.List;
import com.agri.common.utils.DateUtils;
import com.agri.system.domain.SysDtuData;
import com.agri.system.mapper.SysDtuDataMapper;
import com.agri.system.service.ISysDtuDataService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.agri.system.mapper.SysDtuDataMapper;
import com.agri.system.domain.SysDtuData;
import com.agri.system.service.ISysDtuDataService;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
/**
* DTU湿Service
@ -100,4 +105,38 @@ public class SysDtuDataServiceImpl extends ServiceImpl<SysDtuDataMapper, SysDtuD
{
return sysDtuDataMapper.deleteSysDtuDataById(id);
}
/**
* imeiimeiidid
* @param imeiList imei
*
* @return imei
*/
@Override
public List<Map<String, Object>> getLastDtuDataByImeiList(List<String> imeiList) {
// 1. 计算最后一分钟的起始时间(当前时间 - 1分钟
LocalDateTime lastOneMinute = LocalDateTime.now().minusMinutes(1);
// 2. 子查询按imei分组 + 最后一分钟过滤 + 取每组最大ID
QueryWrapper<SysDtuData> subQuery = new QueryWrapper<>();
subQuery.select("imei", "MAX(id) as max_id") // 雪花ID的MAX(id)就是最新记录
.in("imei", imeiList)
.ge("time", lastOneMinute)
.groupBy("imei");
// 3. 主查询通过MAX(id)匹配完整数据 + 指定字段
LambdaQueryWrapper<SysDtuData> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.inSql(SysDtuData::getId,
"SELECT max_id FROM (" + subQuery.getCustomSqlSegment() + ") t")
.select(SysDtuData::getImei,
SysDtuData::getTemp1,
SysDtuData::getTemp2,
SysDtuData::getTemp3,
SysDtuData::getTemp4,
SysDtuData::getTime);
return baseMapper.selectMaps(queryWrapper);
}
}

View File

@ -1,12 +1,14 @@
package com.agri.system.service.impl;
import java.util.List;
import com.agri.common.utils.DateUtils;
import com.agri.system.domain.SysRollerParam;
import com.agri.system.domain.vo.RollerTermVO;
import com.agri.system.mapper.SysRollerParamMapper;
import com.agri.system.service.ISysRollerParamService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import com.agri.system.mapper.SysRollerParamMapper;
import com.agri.system.domain.SysRollerParam;
import com.agri.system.service.ISysRollerParamService;
import java.util.List;
/**
* Service
@ -90,4 +92,11 @@ public class SysRollerParamServiceImpl extends ServiceImpl<SysRollerParamMapper,
{
return baseMapper.deleteSysRollerParamById(id);
}
@Override
public List<RollerTermVO> getRollerTerms(List<String> imeiList) {
return baseMapper.getRollerTerms(imeiList);
}
}

View File

@ -192,4 +192,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="isDeleted != null "> and agri.is_deleted = #{isDeleted}</if>
</where>
</select>
<!-- 查询自动模式下的所有imei以及卷膜参数 -->
<select id="findAgriOfAutoInfo" resultType="com.agri.system.domain.vo.AgriAutoInfoVo">
SELECT
agri.`imei`,
agri.`agri_name`,
agri.`work_mode`,
agri.`is_deleted`,
roller_param.`roller`,
roller_param.`ref_temp_code`,
roller_param.`reserved_len`,
roller_param.`manual_total_len`,
roller_param.`auto_total_len`,
roller_param.`vent_total_len`
FROM
sys_agri_info agri
LEFT JOIN sys_roller_param roller_param ON agri.imei = roller_param.imei
WHERE
agri.`is_deleted` = 0
and agri.work_mode = 1
</select>
</mapper>

View File

@ -91,4 +91,28 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{id}
</foreach>
</delete>
<select id="getRollerTerms" resultType="com.agri.system.domain.vo.RollerTermVO" >
SELECT
rp.imei,
rp.roller,
rp.ref_temp_code,
rp.reserved_len,
rp.manual_total_len,
rp.auto_total_len,
rp.vent_total_len,
at.temp,
at.vent,
at.start_time,
at.end_time
FROM sys_roller_param rp
LEFT JOIN sys_auto_term at
ON rp.imei = at.imei
AND rp.roller = at.roller -- 关键按imei+roller双字段关联精准匹配
WHERE rp.imei IN
<foreach collection="imeiList" item="imei" open="(" separator="," close=")">
#{imei}
</foreach>
</select>
</mapper>