diff --git a/pom.xml b/pom.xml index 97f03fe..9d54e53 100644 --- a/pom.xml +++ b/pom.xml @@ -49,6 +49,12 @@ org.springframework.boot spring-boot-starter + + + com.github.xiaoymin + knife4j-spring-boot-starter + 3.0.3 + @@ -270,6 +276,11 @@ lombok provided + + io.springfox + springfox-boot-starter + 3.0.0 + diff --git a/src/main/java/com/evobms/framework/config/SecurityConfig.java b/src/main/java/com/evobms/framework/config/SecurityConfig.java index 1380bf7..d930240 100644 --- a/src/main/java/com/evobms/framework/config/SecurityConfig.java +++ b/src/main/java/com/evobms/framework/config/SecurityConfig.java @@ -114,7 +114,8 @@ public class SecurityConfig requests.antMatchers("/login", "/register", "/captchaImage").permitAll() // 静态资源,可匿名访问 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() - .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() + .antMatchers("/swagger-ui.html", "/swagger-ui/**", "/swagger-resources/**", "/webjars/**", "/v3/api-docs/**", "/*/api-docs", "/druid/**", "/doc.html", "/doc.html/**", "/knife4j/**").permitAll() + .antMatchers("/dev-api/swagger-ui/**", "/dev-api/swagger-resources/**", "/dev-api/v3/api-docs/**", "/dev-api/doc.html", "/dev-api/knife4j/**").permitAll() .antMatchers("/devices/**","/ota/**").permitAll() .antMatchers("/battery-data/**").permitAll() .antMatchers("/vehicle-data/**").permitAll() diff --git a/src/main/java/com/evobms/framework/config/SwaggerConfig.java b/src/main/java/com/evobms/framework/config/SwaggerConfig.java index 8abcf83..0f31dbc 100644 --- a/src/main/java/com/evobms/framework/config/SwaggerConfig.java +++ b/src/main/java/com/evobms/framework/config/SwaggerConfig.java @@ -54,11 +54,7 @@ public class SwaggerConfig .apiInfo(apiInfo()) // 设置哪些接口暴露给Swagger展示 .select() - // 扫描所有有注解的api,用这种方式更灵活 - .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) - // 扫描指定包中的swagger注解 - // .apis(RequestHandlerSelectors.basePackage("com.evobms.project.tool.swagger")) - // 扫描所有 .apis(RequestHandlerSelectors.any()) + .apis(RequestHandlerSelectors.basePackage("com.evobms.project")) .paths(PathSelectors.any()) .build() /* 设置安全模式,swagger可以设置访问token */ diff --git a/src/main/java/com/evobms/project/Battery/domain/SubsystemTemperature.java b/src/main/java/com/evobms/project/Battery/domain/SubsystemTemperature.java index c46c9b1..c9aa8b5 100644 --- a/src/main/java/com/evobms/project/Battery/domain/SubsystemTemperature.java +++ b/src/main/java/com/evobms/project/Battery/domain/SubsystemTemperature.java @@ -2,6 +2,7 @@ package com.evobms.project.Battery.domain; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import com.evobms.framework.aspectj.lang.annotation.Excel; @@ -9,10 +10,11 @@ import com.evobms.framework.web.domain.BaseEntity; /** * 可充电储能子系统温度信息对象 subsystem_temperature - * + * * @author 田志阳 * @date 2025-11-15 */ +@Data public class SubsystemTemperature extends BaseEntity { private static final long serialVersionUID = 1L; @@ -48,115 +50,11 @@ public class SubsystemTemperature extends BaseEntity /** 创建时间 */ @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd") - private Date createdAt; + private Date createTime; /** 更新时间 */ @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd") - private Date updatedAt; + private Date updateTime; - public void setId(Long id) - { - this.id = id; - } - - public Long getId() - { - return id; - } - - public void setDeviceId(String deviceId) - { - this.deviceId = deviceId; - } - - public String getDeviceId() - { - return deviceId; - } - - public void setTimestamp(Date timestamp) - { - this.timestamp = timestamp; - } - - public Date getTimestamp() - { - return timestamp; - } - - public void setSubsystemCount(Integer subsystemCount) - { - this.subsystemCount = subsystemCount; - } - - public Integer getSubsystemCount() - { - return subsystemCount; - } - - public void setSubsystemNo(Integer subsystemNo) - { - this.subsystemNo = subsystemNo; - } - - public Integer getSubsystemNo() - { - return subsystemNo; - } - - public void setTempProbeCount(Integer tempProbeCount) - { - this.tempProbeCount = tempProbeCount; - } - - public Integer getTempProbeCount() - { - return tempProbeCount; - } - - public void setTemperatureValues(String temperatureValues) - { - this.temperatureValues = temperatureValues; - } - - public String getTemperatureValues() - { - return temperatureValues; - } - - public void setCreatedAt(Date createdAt) - { - this.createdAt = createdAt; - } - - public Date getCreatedAt() - { - return createdAt; - } - - public void setUpdatedAt(Date updatedAt) - { - this.updatedAt = updatedAt; - } - - public Date getUpdatedAt() - { - return updatedAt; - } - - @Override - public String toString() { - return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) - .append("id", getId()) - .append("deviceId", getDeviceId()) - .append("timestamp", getTimestamp()) - .append("subsystemCount", getSubsystemCount()) - .append("subsystemNo", getSubsystemNo()) - .append("tempProbeCount", getTempProbeCount()) - .append("temperatureValues", getTemperatureValues()) - .append("createdAt", getCreatedAt()) - .append("updatedAt", getUpdatedAt()) - .toString(); - } } diff --git a/src/main/java/com/evobms/project/VehicleData/controller/BatteryChartController.java b/src/main/java/com/evobms/project/VehicleData/controller/BatteryChartController.java index 11be9b9..a050d55 100644 --- a/src/main/java/com/evobms/project/VehicleData/controller/BatteryChartController.java +++ b/src/main/java/com/evobms/project/VehicleData/controller/BatteryChartController.java @@ -21,6 +21,8 @@ import com.evobms.project.Battery.service.IExtremeValuesService; import com.evobms.project.Battery.domain.ExtremeValues; import java.text.ParseException; import java.text.SimpleDateFormat; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; /** * 图标组件Controller * @@ -28,6 +30,7 @@ import java.text.SimpleDateFormat; * @date 2025-11-15 */ @RestController +@Api(tags = "图表组件") public class BatteryChartController { @Autowired @@ -47,6 +50,7 @@ public class BatteryChartController { // 图表数据:按最近 hours 小时返回整车电压/电流/SOC 的时间序列 @GetMapping("/battery-data/{deviceId}/chart") + @ApiOperation(value = "整车电压电流SOC时间序列", notes = "按最近hours小时返回时间序列") public List getChartData(@PathVariable("deviceId") String deviceId, @RequestParam(value = "hours", required = false, defaultValue = "24") int hours) { long millis = System.currentTimeMillis() - (long) hours * 3600_000L; Date startTime = new Date(millis); @@ -61,18 +65,21 @@ public class BatteryChartController { // 整车最新:返回 deviceId 最新的一条整车数据 @GetMapping("/vehicle-data/{deviceId}/latest") + @ApiOperation(value = "整车最新数据", notes = "返回指定设备最新整车数据") public VehicleData latestVehicleData(@PathVariable("deviceId") String deviceId) { return vehicleDataService.selectLatestByDeviceId(deviceId); } // 位置最新:返回 deviceId 最新的一条位置数据 @GetMapping("/vehicle-location/{deviceId}/latest") + @ApiOperation(value = "车辆最新位置", notes = "返回指定设备最新位置数据") public VehicleLocation latestVehicleLocation(@PathVariable("deviceId") String deviceId) { return vehicleLocationService.selectLatestByDeviceId(deviceId); } // 位置轨迹:按时间范围返回位置列表,start/end 为毫秒时间戳,可选 limit 限制条数 @GetMapping("/vehicle-location/{deviceId}") + @ApiOperation(value = "车辆位置轨迹", notes = "按时间范围返回位置列表") public List locationRange(@PathVariable("deviceId") String deviceId, @RequestParam("start") long startMillis, @RequestParam("end") long endMillis, @@ -84,25 +91,28 @@ public class BatteryChartController { // 子系统最新帧(电压):返回指定子系统号最新的一帧电压数据 @GetMapping("/subsystem-voltage/{deviceId}/{subsystemNo}/latest") + @ApiOperation(value = "子系统最新电压帧", notes = "返回指定子系统最新电压数据") public SubsystemVoltage latestVoltage(@PathVariable("deviceId") String deviceId, @PathVariable("subsystemNo") Integer subsystemNo) { return subsystemVoltageService.selectLatestByDeviceAndSubsystem(deviceId, subsystemNo); } // 子系统最新帧(温度):返回指定子系统号最新的一帧温度数据 @GetMapping("/subsystem-temperature/{deviceId}/{subsystemNo}/latest") + @ApiOperation(value = "子系统最新温度帧", notes = "返回指定子系统最新温度数据") public SubsystemTemperature latestTemperature(@PathVariable("deviceId") String deviceId, @PathVariable("subsystemNo") Integer subsystemNo) { return subsystemTemperatureService.selectLatestByDeviceAndSubsystem(deviceId, subsystemNo); } @GetMapping("/extreme-values/{deviceId}/latest") + @ApiOperation(value = "极值最新数据", notes = "返回指定设备极值数据,支持before筛选") public ExtremeValues latestExtremeValues(@PathVariable("deviceId") String deviceId, @RequestParam(value = "before", required = false) String before) { if (before == null || before.isEmpty()) { return extremeValuesService.selectLatestByDeviceId(deviceId); } - java.util.Date beforeTime = null; + Date beforeTime = null; if (before.matches("\\d+")) { - beforeTime = new java.util.Date(Long.parseLong(before)); + beforeTime = new Date(Long.parseLong(before)); } else { try { beforeTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(before); diff --git a/src/main/java/com/evobms/project/VehicleData/domain/VehicleData.java b/src/main/java/com/evobms/project/VehicleData/domain/VehicleData.java index 9c8c7e9..24926ec 100644 --- a/src/main/java/com/evobms/project/VehicleData/domain/VehicleData.java +++ b/src/main/java/com/evobms/project/VehicleData/domain/VehicleData.java @@ -26,8 +26,8 @@ public class VehicleData extends BaseEntity private String deviceId; /** 数据时间戳 */ - @JsonFormat(pattern = "yyyy-MM-dd") - @Excel(name = "数据时间戳", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "数据时间戳", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") private Date timestamp; /** 车辆状态 (1:启动 2:熄火 3:其他 254:异常 255:无效) */ diff --git a/src/main/java/com/evobms/project/VehicleData/domain/VehicleLocation.java b/src/main/java/com/evobms/project/VehicleData/domain/VehicleLocation.java index 15b9433..71160f7 100644 --- a/src/main/java/com/evobms/project/VehicleData/domain/VehicleLocation.java +++ b/src/main/java/com/evobms/project/VehicleData/domain/VehicleLocation.java @@ -2,6 +2,7 @@ package com.evobms.project.VehicleData.domain; import java.math.BigDecimal; import java.util.Date; + import com.fasterxml.jackson.annotation.JsonFormat; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @@ -14,105 +15,103 @@ import com.evobms.framework.web.domain.BaseEntity; * @author ruoyi * @date 2025-11-15 */ -public class VehicleLocation extends BaseEntity -{ +public class VehicleLocation extends BaseEntity { private static final long serialVersionUID = 1L; - /** 主键ID */ + /** + * 主键ID + */ private Long id; - /** 设备ID */ + /** + * 设备ID + */ @Excel(name = "设备ID") private String deviceId; - /** 数据时间戳 */ + /** + * 数据时间戳 + */ @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "数据时间戳", width = 30, dateFormat = "yyyy-MM-dd") private Date timestamp; - /** 定位状态 (0:无效 1:有效) */ + /** + * 定位状态 (0:无效 1:有效) + */ @Excel(name = "定位状态 (0:无效 1:有效)") private Integer positioningStatus; - /** 经度 */ + /** + * 经度 + */ @Excel(name = "经度") private BigDecimal longitude; - /** 纬度 */ + /** + * 纬度 + */ @Excel(name = "纬度") private BigDecimal latitude; - public void setId(Long id) - { + public void setId(Long id) { this.id = id; } - public Long getId() - { + public Long getId() { return id; } - public void setDeviceId(String deviceId) - { + public void setDeviceId(String deviceId) { this.deviceId = deviceId; } - public String getDeviceId() - { + public String getDeviceId() { return deviceId; } - public void setTimestamp(Date timestamp) - { + public void setTimestamp(Date timestamp) { this.timestamp = timestamp; } - public Date getTimestamp() - { + public Date getTimestamp() { return timestamp; } - public void setPositioningStatus(Integer positioningStatus) - { + public void setPositioningStatus(Integer positioningStatus) { this.positioningStatus = positioningStatus; } - public Integer getPositioningStatus() - { + public Integer getPositioningStatus() { return positioningStatus; } - public void setLongitude(BigDecimal longitude) - { + public void setLongitude(BigDecimal longitude) { this.longitude = longitude; } - public BigDecimal getLongitude() - { + public BigDecimal getLongitude() { return longitude; } - public void setLatitude(BigDecimal latitude) - { + public void setLatitude(BigDecimal latitude) { this.latitude = latitude; } - public BigDecimal getLatitude() - { + public BigDecimal getLatitude() { return latitude; } - @Override public String toString() { - return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) - .append("id", getId()) - .append("deviceId", getDeviceId()) - .append("timestamp", getTimestamp()) - .append("positioningStatus", getPositioningStatus()) - .append("longitude", getLongitude()) - .append("latitude", getLatitude()) - .toString(); + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("deviceId", getDeviceId()) + .append("timestamp", getTimestamp()) + .append("positioningStatus", getPositioningStatus()) + .append("longitude", getLongitude()) + .append("latitude", getLatitude()) + .toString(); } } diff --git a/src/main/java/com/evobms/project/bms/controller/GBT32960FullDecoder.java b/src/main/java/com/evobms/project/bms/controller/GBT32960FullDecoder.java index ed73cde..7786a48 100644 --- a/src/main/java/com/evobms/project/bms/controller/GBT32960FullDecoder.java +++ b/src/main/java/com/evobms/project/bms/controller/GBT32960FullDecoder.java @@ -5,17 +5,28 @@ import org.slf4j.LoggerFactory; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; import java.util.Arrays; public class GBT32960FullDecoder { private static final Logger log = LoggerFactory.getLogger(GBT32960FullDecoder.class); // 从SN码生成AES密钥 private static byte[] generateKeyFromSn(String sn) { - StringBuilder keyStr = new StringBuilder(sn); - while (keyStr.length() < 16) { - keyStr.append("0"); + String s = sn == null ? "" : sn; + String key; + if ("EVO0001".equals(s)) { + StringBuilder sb = new StringBuilder(16); + sb.append("EVO0001"); + while (sb.length() < 16) sb.append('0'); + key = sb.toString(); + } else if (s.length() >= 16) { + key = s.substring(s.length() - 16); + } else { + StringBuilder sb = new StringBuilder(16); + sb.append(s); + while (sb.length() < 16) sb.append('0'); + key = sb.toString(); } - keyStr = new StringBuilder(keyStr.substring(0, 16)); - return keyStr.toString().getBytes(java.nio.charset.StandardCharsets.UTF_8); + return key.getBytes(StandardCharsets.UTF_8); } // AES解密 @@ -173,6 +184,7 @@ public class GBT32960FullDecoder { //使用的AES密钥 byte[] aesKey = generateKeyFromSn(deviceSn); + System.out.println("密钥------------------------>"+aesKey); byte[] decryptedData = decryptData(encryptedData, aesKey); bytesData = bytesToHex(decryptedData); log.info("解密成功!"); diff --git a/src/main/java/com/evobms/project/bms/service/MqttService.java b/src/main/java/com/evobms/project/bms/service/MqttService.java index d37bf4c..992f22a 100644 --- a/src/main/java/com/evobms/project/bms/service/MqttService.java +++ b/src/main/java/com/evobms/project/bms/service/MqttService.java @@ -30,6 +30,7 @@ import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; +import java.util.stream.Collectors; import com.evobms.project.system.service.IBmsDevicesService; import com.evobms.project.system.domain.BmsDevices; @@ -73,7 +74,6 @@ public class MqttService { private IChargeDischargeSummaryService chargeDischargeSummaryService; - @Value("${mqtt.publishTopic}") private String publishTopic; @@ -86,7 +86,7 @@ public class MqttService { /** * 发送MQTT消息 * - * @param topic 主题 + * @param topic 主题 * @param payload 消息内容 */ public void sendMessage(String topic, String payload) { @@ -100,7 +100,7 @@ public class MqttService { /** * 发送MQTT字节消息 * - * @param topic 主题 + * @param topic 主题 * @param payload 原始字节 */ public void sendMessageBytes(String topic, byte[] payload) { @@ -168,7 +168,7 @@ public class MqttService { * 发送设备控制命令 * * @param deviceCode 设备编号 - * @param command 控制命令 + * @param command 控制命令 */ public void sendDeviceCommand(String deviceCode, String command) { Map commandData = new HashMap<>(); @@ -185,7 +185,7 @@ public class MqttService { /** * 处理接收到的设备数据 * - * @param topic 主题 + * @param topic 主题 * @param message 消息内容 */ public void handleDeviceData(String topic, byte[] message) { @@ -220,10 +220,11 @@ public class MqttService { log.error("处理设备数据时发生错误: {}", e.getMessage(), e); } } + /** * 逐字段解析数据字符串 - 直接解析十六进制数据 * - * @param data 十六进制数据字符串 + * @param data 十六进制数据字符串 * @param deviceSn 设备SN码 */ private void parseDataFields(String data, String deviceSn) { @@ -252,31 +253,35 @@ public class MqttService { log.error("设备 {} 解析数据字段时发生错误: {}", deviceSn, e.getMessage(), e); } } + /** * 按照协议定义的索引位置解析各个数据段 */ private void parseByProtocolIndex(byte[] message, String deviceSn) { try { // 1. 时间信息 - 索引24-29 (6字节) - parseTimeAtIndex(message, 0, deviceSn); + Date frameTime = parseTimeAtIndex(message, 0, deviceSn); + if (frameTime == null) { + frameTime = new Date(); + } // 2. 整车数据 - 索引30-49 (20字节) - parseVehicleDataAtIndex(message, 6, deviceSn); + parseVehicleDataAtIndex(message, 6, deviceSn, frameTime); // 3. 位置信息 - 索引51-60 (10字节) - parseLocationDataAtIndex(message, 27, deviceSn); + parseLocationDataAtIndex(message, 27, deviceSn, frameTime); // 4. 极值数据 - 索引61-75 (14字节) - parseExtremeDataAtIndex(message, 37, deviceSn); + parseExtremeDataAtIndex(message, 37, deviceSn, frameTime); // 5. 单体电压数据 - 索引76-447 (372字节) - parseCellVoltageAtIndex(message, 52, deviceSn); + parseCellVoltageAtIndex(message, 52, deviceSn, frameTime); // 6. 单体温度数据 - 索引448-542 (95字节) - parseCellTemperatureAtIndex(message, 424, deviceSn); + parseCellTemperatureAtIndex(message, 424, deviceSn, frameTime); // 7. 累计充放电量 - 索引543-553 (11字节) - parseChargeDischargeAtIndex(message, 519, deviceSn); + parseChargeDischargeAtIndex(message, 519, deviceSn, frameTime); log.info("设备 {} 所有数据段解析完成", deviceSn); @@ -284,15 +289,16 @@ public class MqttService { log.error("设备 {} 按索引解析时发生错误: {}", deviceSn, e.getMessage(), e); } } + /** * 解析时间信息 - 索引24-29 (6字节) * 格式: 年(偏移2000) + 月 + 日 + 时 + 分 + 秒 */ - private void parseTimeAtIndex(byte[] message, int startIndex, String deviceSn) { + private Date parseTimeAtIndex(byte[] message, int startIndex, String deviceSn) { try { if (message.length < startIndex + 6) { log.warn("设备 {}: 时间数据索引越界", deviceSn); - return; + return null; } int year = (message[startIndex] & 0xFF) + 2000; // 索引24: 年 @@ -307,19 +313,26 @@ public class MqttService { year, month, day, hour, minute, second); log.info("设备 {} - 时间: {}", deviceSn, time); saveTimeData(deviceSn, time); + Calendar cal = Calendar.getInstance(TimeZone.getDefault()); + cal.set(year, month - 1, day, hour, minute, second); + cal.set(Calendar.MILLISECOND, 0); + return cal.getTime(); } else { log.info("设备 {} - 时间: 无效数据({}-{}-{} {}:{}:{})", deviceSn, year, month, day, hour, minute, second); + return null; } } catch (Exception e) { log.error("设备 {} 解析时间数据时发生错误: {}", deviceSn, e.getMessage()); + return null; } } + /** * 解析整车数据 - 索引30-49 (20字节) */ - private void parseVehicleDataAtIndex(byte[] message, int startIndex, String deviceSn) { + private void parseVehicleDataAtIndex(byte[] message, int startIndex, String deviceSn, Date frameTime) { try { if (message.length < startIndex + 20) { log.warn("设备 {}: 整车数据索引越界", deviceSn); @@ -359,7 +372,7 @@ public class MqttService { log.info("设备 {} - 正极绝缘电阻: {} Ω", deviceSn, insulationResistance); // 保存整车数据 - saveVehicleData(deviceSn, voltageValue, currentValue, soc, chargeStatus,insulationResistance); + saveVehicleData(deviceSn, voltageValue, currentValue, soc, chargeStatus, insulationResistance, frameTime); } catch (Exception e) { log.error("设备 {} 解析整车数据时发生错误: {}", deviceSn, e.getMessage()); @@ -370,7 +383,7 @@ public class MqttService { /** * 解析位置信息 - 索引51-60 (10字节) */ - private void parseLocationDataAtIndex(byte[] message, int startIndex, String deviceSn) { + private void parseLocationDataAtIndex(byte[] message, int startIndex, String deviceSn, Date frameTime) { try { if (message.length < startIndex + 10) { log.warn("设备 {}: 位置数据索引越界", deviceSn); @@ -388,7 +401,8 @@ public class MqttService { // 索引52: 位置状态 byte locationStatus = message[startIndex + 1]; - + // 转成十六进制字符串,例如 "00", "01" + String locationStatusHex = String.format("%02X", locationStatus); // 索引53-56: 经度 (0.000001°) long longitude = ((message[startIndex + 2] & 0xFFL) << 24) | ((message[startIndex + 3] & 0xFFL) << 16) | @@ -404,8 +418,9 @@ public class MqttService { if (longitude != 0 || latitude != 0) { double lon = longitude / 1000000.0; double lat = latitude / 1000000.0; - log.info("设备 {} - 位置: 经度={}°, 纬度={}° (状态:0x{})", deviceSn, lon, lat, String.format("%02X", locationStatus)); - processLocationData(deviceSn, lon, lat,String.format("%02X", locationStatus)); + + log.info("设备 {} - 位置: 经度={}°, 纬度={}° (状态:0x{})", deviceSn, lon, lat, locationStatusHex); + processLocationData(deviceSn, lon, lat, locationStatusHex, frameTime); } else { log.info("设备 {} - 位置: 无效数据", deviceSn); } @@ -418,7 +433,7 @@ public class MqttService { /** * 解析极值数据 - 索引61-75 (14字节) */ - private void parseExtremeDataAtIndex(byte[] message, int startIndex, String deviceSn) { + private void parseExtremeDataAtIndex(byte[] message, int startIndex, String deviceSn, Date frameTime) { try { if (message.length < startIndex + 14) { log.warn("设备 {}: 极值数据索引越界", deviceSn); @@ -468,7 +483,7 @@ public class MqttService { int minTempValue = minTemperature - 40; log.info("设备 {} - 最低温度: 子系统{}-探针{}, {}°C", deviceSn, minTempSystem, minTempProbe, minTempValue); // 保存极值数据 - saveExtremeData(deviceSn, (maxVoltageSystem & 0xFF), (maxVoltageProbe & 0xFF), maxVoltageValue, (minVoltageSystem & 0xFF), (minVoltageProbe & 0xFF), minVoltageValue, (maxTempSystem & 0xFF), (maxTempProbe & 0xFF), maxTempValue, (minTempSystem & 0xFF), (minTempProbe & 0xFF), minTempValue); + saveExtremeData(deviceSn, (maxVoltageSystem & 0xFF), (maxVoltageProbe & 0xFF), maxVoltageValue, (minVoltageSystem & 0xFF), (minVoltageProbe & 0xFF), minVoltageValue, (maxTempSystem & 0xFF), (maxTempProbe & 0xFF), maxTempValue, (minTempSystem & 0xFF), (minTempProbe & 0xFF), minTempValue, frameTime); } catch (Exception e) { log.error("设备 {} 解析极值数据时发生错误: {}", deviceSn, e.getMessage()); @@ -479,7 +494,7 @@ public class MqttService { /** * 解析单体电压数据 - 索引76-447 (372字节) */ - private void parseCellVoltageAtIndex(byte[] message, int startIndex, String deviceSn) { + private void parseCellVoltageAtIndex(byte[] message, int startIndex, String deviceSn, Date frameTime) { try { if (message.length < startIndex + 372) { log.warn("设备 {}: 单体电压数据索引越界", deviceSn); @@ -535,7 +550,7 @@ public class MqttService { } SubsystemVoltage sv = new SubsystemVoltage(); sv.setDeviceId(deviceSn); - sv.setTimestamp(new Date()); + sv.setTimestamp(frameTime); sv.setSubsystemCount((int) subsystemCount); sv.setSubsystemNo((int) subsystemNum); sv.setSubsystemVoltage(BigDecimal.valueOf(storageVoltageValue)); @@ -546,7 +561,7 @@ public class MqttService { sv.setCreateTime(new Date()); sv.setCreateBy(deviceSn); String voltagesStr = voltages.stream().map(Object::toString).collect(java.util.stream.Collectors.joining(",")); - sv.setBatteryVoltages(voltagesStr); + sv.setBatteryVoltages(JSON.toJSONString(voltagesStr)); subsystemVoltageService.insertSubsystemVoltage(sv); parseCellVoltagesDetail(message, voltageDataStart, deviceSn, startCellIndex, frameCellCount); } else { @@ -562,7 +577,7 @@ public class MqttService { /** * 解析单体温度数据 - 索引448-542 (95字节) */ - private void parseCellTemperatureAtIndex(byte[] message, int startIndex, String deviceSn) { + private void parseCellTemperatureAtIndex(byte[] message, int startIndex, String deviceSn, Date frameTime) { try { if (message.length < startIndex + 89) { log.warn("设备 {}: 单体温度数据索引越界", deviceSn); @@ -603,14 +618,14 @@ public class MqttService { } SubsystemTemperature st = new SubsystemTemperature(); st.setDeviceId(deviceSn); - st.setTimestamp(new Date()); + st.setTimestamp(frameTime); st.setSubsystemCount((int) subsystemCount); st.setSubsystemNo((int) subsystemNum); st.setTempProbeCount(totalTempCount); st.setCreateTime(new Date()); st.setCreateBy(deviceSn); - String tempsStr = temperatures.stream().map(Object::toString).collect(java.util.stream.Collectors.joining(",")); - st.setTemperatureValues(tempsStr); + String tempsStr = temperatures.stream().map(Object::toString).collect(Collectors.joining(",")); + st.setTemperatureValues(JSON.toJSONString(tempsStr)); subsystemTemperatureService.insertSubsystemTemperature(st); parseCellTemperaturesDetail(message, tempDataStart, deviceSn, totalTempCount); } else { @@ -625,7 +640,7 @@ public class MqttService { /** * 解析累计充放电量 - 索引543-553 (11字节) */ - private void parseChargeDischargeAtIndex(byte[] message, int startIndex, String deviceSn) { + private void parseChargeDischargeAtIndex(byte[] message, int startIndex, String deviceSn, Date frameTime) { try { if (message.length < startIndex + 11) { log.warn("设备 {}: 充放电数据索引越界", deviceSn); @@ -659,7 +674,7 @@ public class MqttService { log.info("设备 {} - 累计充放电量: 放电{}kWh, 充电{}kWh", deviceSn, dischargeKwh, chargeKwh); - saveChargeDischargeSummary(deviceSn, dischargeKwh, chargeKwh); + saveChargeDischargeSummary(deviceSn, dischargeKwh, chargeKwh, frameTime); } catch (Exception e) { log.error("设备 {} 解析充放电数据时发生错误: {}", deviceSn, e.getMessage()); @@ -667,8 +682,6 @@ public class MqttService { } - - /** * 解析详细的单体温度数据 */ @@ -734,6 +747,7 @@ public class MqttService { log.info("设备 {} - 电压统计: 最小值{}V, 最大值{}V, 平均值{}V", deviceSn, minVoltage, maxVoltage, avgVoltage); } + /** * 检查单体电压数据有效性 */ @@ -746,18 +760,25 @@ public class MqttService { } return false; } + /** * 充电状态描述 */ private int getChargeStatusDescription(byte status) { /** 充电状态 (1:停车充电 2:行驶充电 3:未充电 4:充电完成 254:异常 255:无效) */ switch (status & 0xFF) { - case 0x01: return 1; - case 0x02: return 2; - case 0x03: return 3; - case 0x04: return 4; - case 0xFE: return 254; - case 0xFF: return 255; + case 0x01: + return 1; + case 0x02: + return 2; + case 0x03: + return 3; + case 0x04: + return 4; + case 0xFE: + return 254; + case 0xFF: + return 255; } return 0; @@ -774,6 +795,7 @@ public class MqttService { minute >= 0 && minute <= 59 && second >= 0 && second <= 59; } + /** * 十六进制字符串转字节数组 */ @@ -793,8 +815,7 @@ public class MqttService { */ private void saveCellVoltageData(String deviceSn, byte subsystemNum, int startIndex, int count, List voltages, double min, double max, double avg) { // TODO: 实现单体电压数据保存逻辑 - log.debug("保存设备 {} 子系统 {} 电压数据: 起始{}, 数量{}, 范围{}-{}V", - deviceSn, subsystemNum, startIndex, count, min, max); + log.debug("保存设备 {} 子系统 {} 电压数据: 起始{}, 数量{}, 范围{}-{}V", deviceSn, subsystemNum, startIndex, count, min, max); } /** @@ -802,8 +823,7 @@ public class MqttService { */ private void saveCellTemperatureData(String deviceSn, byte subsystemNum, int count, List temperatures, int min, int max, double avg) { // TODO: 实现单体温度数据保存逻辑 - log.debug("保存设备 {} 子系统 {} 温度数据: 数量{}, 范围{}-{}°C", - deviceSn, subsystemNum, count, min, max); + log.debug("保存设备 {} 子系统 {} 温度数据: 数量{}, 范围{}-{}°C", deviceSn, subsystemNum, count, min, max); } /** @@ -813,13 +833,15 @@ public class MqttService { // TODO: 实现时间数据保存逻辑 log.debug("保存设备 {} 时间数据: {}", deviceSn, time); } + /** * 保存整车数据 */ - private void saveVehicleData(String deviceSn, double voltage, double current, int soc, byte chargeStatus,int insulationResistance) { + private void saveVehicleData(String deviceSn, double voltage, double current, int soc, byte chargeStatus,int insulationResistance, Date frameTime) { // 保存整车数据到数据库 VehicleData ve = new VehicleData(); ve.setDeviceId(deviceSn); + ve.setTimestamp(frameTime); ve.setTotalVoltage(BigDecimal.valueOf(voltage)); ve.setTotalCurrent(BigDecimal.valueOf(current)); ve.setSoc(soc); @@ -831,11 +853,13 @@ public class MqttService { } - private void processLocationData(String deviceSn, double longitude, double latitude,String locationStatus) { + private void processLocationData(String deviceSn, double longitude, double latitude,String locationStatus, Date frameTime) { VehicleLocation ve = new VehicleLocation(); ve.setDeviceId(deviceSn); - ve.setTimestamp(new Date()); - ve.setPositioningStatus(Integer.valueOf(String.format("%02X", locationStatus))); + ve.setTimestamp(frameTime); + // 十六进制字符串(如 "00")转成整数(如 0) + int status = Integer.parseInt(locationStatus, 16); + ve.setPositioningStatus(status); ve.setLongitude(BigDecimal.valueOf(longitude)); ve.setLatitude(BigDecimal.valueOf(latitude)); ve.setCreateTime(new Date()); @@ -844,10 +868,10 @@ public class MqttService { } private void saveExtremeData(String deviceSn, int maxVoltageSubsystemNo, int maxVoltageBatteryNo, double maxVoltageValue, int minVoltageSubsystemNo, int minVoltageBatteryNo, double minVoltageValue, int maxTempSubsystemNo, - int maxTempProbeNo, int maxTempValue, int minTempSubsystemNo, int minTempProbeNo, int minTempValue) { + int maxTempProbeNo, int maxTempValue, int minTempSubsystemNo, int minTempProbeNo, int minTempValue, Date frameTime) { ExtremeValues ex = new ExtremeValues(); ex.setDeviceId(deviceSn); - ex.setTimestamp(new Date()); + ex.setTimestamp(frameTime); ex.setMaxVoltageSubsystemNo(maxVoltageSubsystemNo); ex.setMaxVoltageBatteryNo(maxVoltageBatteryNo); ex.setMaxVoltageValue(BigDecimal.valueOf(maxVoltageValue)); @@ -863,16 +887,17 @@ public class MqttService { extremeValuesService.insertExtremeValues(ex); } - private void saveChargeDischargeSummary(String deviceSn, double dischargeKwh, double chargeKwh) { + private void saveChargeDischargeSummary(String deviceSn, double dischargeKwh, double chargeKwh, Date frameTime) { ChargeDischargeSummary s = new ChargeDischargeSummary(); s.setDeviceId(deviceSn); - s.setTimestamp(new Date()); + s.setTimestamp(frameTime); s.setDischargeKwh(BigDecimal.valueOf(dischargeKwh)); s.setChargeKwh(BigDecimal.valueOf(chargeKwh)); s.setCreateTime(new Date()); s.setCreateBy(deviceSn); chargeDischargeSummaryService.insertChargeDischargeSummary(s); } + /** * 处理单体温度数据 */ @@ -888,70 +913,56 @@ public class MqttService { } - - - - - - - - - - - - /** * 更新设备数据 * * @param device 设备对象 - * @param data 数据 + * @param data 数据 */ - private void updateDeviceData(BmsDevice device, Map data) { - if (data.containsKey("voltage")) { - device.setCurrentVoltage(Double.valueOf(data.get("voltage").toString())); - } - if (data.containsKey("current")) { - device.setCurrentCurrent(Double.valueOf(data.get("current").toString())); - } - if (data.containsKey("capacity")) { - device.setRemainingCapacity(Double.valueOf(data.get("capacity").toString())); - } - if (data.containsKey("temperature")) { - device.setTemperature(Double.valueOf(data.get("temperature").toString())); - } + private void updateDeviceData(BmsDevice device, Map data) { + if (data.containsKey("voltage")) { + device.setCurrentVoltage(Double.valueOf(data.get("voltage").toString())); + } + if (data.containsKey("current")) { + device.setCurrentCurrent(Double.valueOf(data.get("current").toString())); + } + if (data.containsKey("capacity")) { + device.setRemainingCapacity(Double.valueOf(data.get("capacity").toString())); + } + if (data.containsKey("temperature")) { + device.setTemperature(Double.valueOf(data.get("temperature").toString())); + } - device.setLastCommTime(new Date()); - } + device.setLastCommTime(new Date()); + } - /** + /** * 发送设备状态查询命令 * * @param deviceCode 设备编号 */ - public void queryDeviceStatus(String deviceCode) { - sendDeviceCommand(deviceCode, "STATUS_QUERY"); - } + public void queryDeviceStatus(String deviceCode) { + sendDeviceCommand(deviceCode, "STATUS_QUERY"); + } - - - /** + /** * 根据设备唯一编号(deviceCode)查询系统设备表的SN码 */ - private String lookupDeviceSnByCode(String deviceCode) { - try { - BmsDevices query = new BmsDevices(); - query.setDeviceId(deviceCode); - List list = bmsDevicesService.selectBmsDevicesList(query); - if (list != null && !list.isEmpty()) { - String sn = list.get(0).getDeviceSn(); - if (sn != null && !sn.isEmpty()) { - return sn; - } - } - } catch (Exception e) { - log.warn("查询设备SN失败: {}", e.getMessage()); - } - return null; - } + private String lookupDeviceSnByCode(String deviceCode) { + try { + BmsDevices query = new BmsDevices(); + query.setDeviceId(deviceCode); + List list = bmsDevicesService.selectBmsDevicesList(query); + if (list != null && !list.isEmpty()) { + String sn = list.get(0).getDeviceSn(); + if (sn != null && !sn.isEmpty()) { + return sn; + } + } + } catch (Exception e) { + log.warn("查询设备SN失败: {}", e.getMessage()); + } + return null; + } } diff --git a/src/main/java/com/evobms/project/iot/controller/IotAuthController.java b/src/main/java/com/evobms/project/iot/controller/IotAuthController.java index 0a8ee29..6bc286b 100644 --- a/src/main/java/com/evobms/project/iot/controller/IotAuthController.java +++ b/src/main/java/com/evobms/project/iot/controller/IotAuthController.java @@ -9,6 +9,10 @@ import com.evobms.project.iot.service.DeviceTokenService; import com.evobms.project.system.domain.BmsDevices; import com.evobms.project.system.service.IBmsDevicesService; import com.evobms.project.ota.service.IOtaTasksService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; @@ -25,6 +29,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; + import javax.servlet.http.HttpServletRequest; import java.io.ByteArrayOutputStream; import java.io.InputStream; @@ -46,6 +51,7 @@ import java.util.Map; * 路径:POST /iot/auth/token */ @RestController +@Tag(name = "设备鉴权", description = "设备鉴权令牌接口") @RequestMapping("/iot") public class IotAuthController { private static final Logger log = LoggerFactory.getLogger(IotAuthController.class); @@ -89,6 +95,7 @@ public class IotAuthController { * 返回:{ code, success, token } */ @PostMapping("/auth/token") + @Operation(summary = "设备请求令牌", description = "通过SN码,设备号,版本信息生成TOKEN") public Map requestToken(@RequestBody Map body) { String sn = safeTrim(body.get("sn")); String model = safeTrim(body.get("device")); @@ -133,7 +140,7 @@ public class IotAuthController { return resp; } - // 设备合法,改为自定义非JWT令牌,长度固定65 + // 设备合法,改为JWT令牌,长度固定65 String token = deviceTokenService.issueTokenForSn(sn); log.info("BBOX设备token: {}", token); log.info("设备令牌签发成功: sn={} model={} version={} tokenLen={}", sn, model, version, token != null ? token.length() : 0); @@ -162,6 +169,8 @@ public class IotAuthController { * 请求参数:version(可选) * 返回:{ code, success, data(Base64) } */ + @Operation(summary = " MQTT 登录", description = "获取设备端 MQTT 登录信息") + @ApiOperation(value = "MQTT 登录", notes = "获取设备端 MQTT 登录信息") @GetMapping("/auth/mqtt") public Map getMqttCredentials(@RequestParam(value = "version", required = false) String version, HttpServletRequest request) { @@ -186,10 +195,11 @@ public class IotAuthController { if (uri.getPort() != -1) { port = uri.getPort(); } - } catch (Exception ignore) {} + } catch (Exception ignore) { + } String use = fixLengthRight(mqttUsername, 8); - String pass = fixLengthRight(mqttPassword,16); + String pass = fixLengthRight(mqttPassword, 16); Map data = new HashMap<>(); data.put("clientid", sn); @@ -199,10 +209,17 @@ public class IotAuthController { data.put("passwd", pass); String json = JSON.toJSONString(data); - log.debug("登录mqtt信息====》{}",json); - String key16 = fixLengthRight(sn, 16); // AES密钥:sn后补0到16位 - String encryptedBase64 = AesEcbPkcs5Utils.encryptToAscII16(json, key16); - log.debug("登录mqtt信息加密===================》{}",encryptedBase64); + log.debug("登录mqtt信息====》{}", json); + // AES密钥:sn后补0到16位 + String encryptedBase64; + if (sn.equals("EVO0001")) { + String key161 = fixLengthRight("EVO0001", 16); + encryptedBase64 = AesEcbPkcs5Utils.encryptToAscII16(json, key161); + } else { + String keyTail6 = sn.length() >= 16 ? sn.substring(sn.length() - 16) : sn; + encryptedBase64 = AesEcbPkcs5Utils.encryptToAscII16(json, keyTail6); + } + log.debug("登录mqtt信息加密===================》{}", encryptedBase64); resp.put("code", BboxApiConstants.CODE_SUCCESS); resp.put("success", "1"); resp.put("data", encryptedBase64); @@ -221,6 +238,7 @@ public class IotAuthController { * 请求参数(body):{ "version":"1.0.0" } * 返回:{ code(3位), success(1位), update(1位), version(5位), url(11位), count(3位) } */ + @ApiOperation(value = "设备登录", notes = "设备登录并上报固件版本,服务端判断是否需要OTA升级") @PostMapping("/auth/login") public Map deviceLogin(@RequestBody(required = false) String body, @RequestParam(value = "version", required = false) String versionParam, HttpServletRequest request) { Map resp = new HashMap<>(); @@ -285,7 +303,8 @@ public class IotAuthController { // 目标升级版本:直接取设备记录中的固件版本(跳过 OTA 任务查询) String targetVersion = null; - try { targetVersion = device.getFirmwareVersion(); + try { + targetVersion = device.getFirmwareVersion(); } catch (Exception ignore) { } @@ -362,13 +381,14 @@ public class IotAuthController { * - 路径:`/iot/ota/{num}`,num 为三位数字字符串(000 起始) * - 参数:`version`(必填,目标固件版本号,例如 `1.0.1`) * - 响应: - * 成功:`application/octet-stream` 二进制数据;每次返回最多 1024 字节(最后一片可能不足 1024) - * 失败:`{ code, success }` JSON,错误码沿用 `BboxApiConstants` + * 成功:`application/octet-stream` 二进制数据;每次返回最多 1024 字节(最后一片可能不足 1024) + * 失败:`{ code, success }` JSON,错误码沿用 `BboxApiConstants` * - 首片摘要计算:针对首片1024字节数据生成摘要并作为校验头:32字节SHA-256原始摘要 * - 首片结构:`[header] + [首片数据(最多1024)]`,总长 `headerLen + 1024` * - 后续分片:与首片相同,每片前置相同模式的校验头(摘要基于该分片的数据),随后紧跟该分片数据 */ @GetMapping("/ota/{num}") + @Operation(summary = "OTA固件分片下载", description = " OTA 固件分片下载接口") public Object downloadOtaChunk(@PathVariable("num") String num, @RequestParam(value = "version", required = false) String version, HttpServletRequest request) { @@ -453,7 +473,8 @@ public class IotAuthController { log.info("OTA首片头HEX({}): {}", headerLen, toHex(header)); int prefixLen = Math.min(64, firstData.length); log.info("OTA首片数据HEX前{}字节: {}", prefixLen, toHex(Arrays.copyOfRange(firstData, 0, prefixLen))); - } catch (Exception ignore) {} + } catch (Exception ignore) { + } } else { // 后续分片:从首片实际数据(1024)之后开始切片;并在分片前置校验头(摘要基于该分片数据) int firstDataLen = Math.min(otaChunkSize, firmwareBytes); @@ -486,8 +507,9 @@ public class IotAuthController { log.info("OTA分片头HEX({}): {}", headerLen, toHex(header)); int prefixLen = Math.min(64, dataForDigest.length); log.info("OTA分片数据HEX前{}字节: {}", prefixLen, toHex(Arrays.copyOfRange(dataForDigest, 0, prefixLen))); - } catch (Exception ignore) {} - } + } catch (Exception ignore) { + } + } log.debug("OTA分片发送: sn={} version={} num={} chunkLen={}", sn, version, num, chunk.length); @@ -497,14 +519,14 @@ public class IotAuthController { .contentLength(chunk.length) .body(chunk); } catch (Exception e) { - log.error("OTA分片下载异常: {}", e.getMessage(), e); - err.put("code", BboxApiConstants.CODE_UNAUTHORIZED); - err.put("success", "0"); - return err; - } finally { - MDC.clear(); + log.error("OTA分片下载异常: {}", e.getMessage(), e); + err.put("code", BboxApiConstants.CODE_UNAUTHORIZED); + err.put("success", "0"); + return err; + } finally { + MDC.clear(); + } } -} /** * 动态计算 OTA 分片总数 @@ -554,7 +576,8 @@ public class IotAuthController { String rel = base + version + ".bin"; Resource res = new ClassPathResource(rel); if (!res.exists()) return null; - try (InputStream in = res.getInputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + try (InputStream in = res.getInputStream(); + ByteArrayOutputStream bos = new ByteArrayOutputStream()) { byte[] buf = new byte[4096]; int r; while ((r = in.read(buf)) != -1) bos.write(buf, 0, r); @@ -580,7 +603,7 @@ public class IotAuthController { private static String sha256Hex(byte[] data) throws Exception { MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] digest = md.digest(data); - StringBuilder sb = new StringBuilder(digest.length ); + StringBuilder sb = new StringBuilder(digest.length); for (byte b : digest) { //转为 16 进制字符串 String s = Integer.toHexString(0xff & b); @@ -608,7 +631,9 @@ public class IotAuthController { private static String fixLengthRight(String s, int len) { if (s == null) s = ""; - if (s.length() >= len) return s.substring(0, len); + if (s.length() >= len){ + return s.substring(0, len); + } StringBuilder sb = new StringBuilder(len); sb.append(s); while (sb.length() < len) sb.append('0'); diff --git a/src/main/java/com/evobms/project/system/domain/BmsDevices.java b/src/main/java/com/evobms/project/system/domain/BmsDevices.java index 2804035..c4254fe 100644 --- a/src/main/java/com/evobms/project/system/domain/BmsDevices.java +++ b/src/main/java/com/evobms/project/system/domain/BmsDevices.java @@ -47,7 +47,7 @@ public class BmsDevices extends BaseEntity @Excel(name = "设备IP地址") private String ipAddress; - /** 固件版本号 */ + /** 服务器固件版本号 */ @Excel(name = "固件版本号") private String firmwareVersion; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9bcccf9..f99a863 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -6,7 +6,7 @@ ruoyi: version: 3.9.0 # 版权年份 copyrightYear: 2025 - # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + # 文件路径 profile: D:/ruoyi/uploadPath # 获取ip地址开关 addressEnabled: false @@ -15,8 +15,8 @@ ruoyi: # 开发环境配置 server: - # 服务器的HTTP端口,默认为8080 - port: 8080 + # 服务器HTTP端口,支持环境变量覆盖:SERVER_PORT,默认8080 + port: ${SERVER_PORT:8081} servlet: # 应用的访问路径 context-path: / @@ -208,11 +208,11 @@ mqtt: # 默认QoS等级 defaultQos: 1 # 订阅主题 - subscribeTopic: /bbox/EVO0002/# + subscribeTopic: "/bbox/+/#" # 发布主题 publishTopic: evobms/command # 调试:开启HTTP请求打印 -debug: - httpdump: + debug: + httpdump: enabled: true diff --git a/src/main/resources/mybatis/temperature/SubsystemTemperatureMapper.xml b/src/main/resources/mybatis/temperature/SubsystemTemperatureMapper.xml index 1bf2066..81d225a 100644 --- a/src/main/resources/mybatis/temperature/SubsystemTemperatureMapper.xml +++ b/src/main/resources/mybatis/temperature/SubsystemTemperatureMapper.xml @@ -13,13 +13,13 @@ - + - select id, device_id, timestamp, subsystem_count, subsystem_no, temp_probe_count, temperature_values, create_time, updated_time, create_by, update_by from subsystem_temperature + select id, device_id, timestamp, subsystem_count, subsystem_no, temp_probe_count, temperature_values, create_time, update_time, create_by, update_by from subsystem_temperature @@ -50,7 +50,7 @@ temp_probe_count, temperature_values, create_time, - updated_time, + update_time, create_by, update_by, @@ -62,7 +62,7 @@ #{tempProbeCount}, #{temperatureValues}, #{createTime}, - #{updatedTime}, + #{updateTime}, #{createBy}, #{updateBy}, @@ -78,7 +78,7 @@ temp_probe_count = #{tempProbeCount}, temperature_values = #{temperatureValues}, create_time = #{createTime}, - updated_time = #{updatedTime}, + update_time = #{updateTime}, create_by = #{createBy}, update_by = #{updateBy},