diff --git a/.vite/deps/package.json b/.vite/deps/package.json new file mode 100644 index 0000000..3dbc1ca --- /dev/null +++ b/.vite/deps/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/src/main/java/com/evobms/framework/config/MqttConfig.java b/src/main/java/com/evobms/framework/config/MqttConfig.java index 29fb55d..b671597 100644 --- a/src/main/java/com/evobms/framework/config/MqttConfig.java +++ b/src/main/java/com/evobms/framework/config/MqttConfig.java @@ -150,7 +150,6 @@ public class MqttConfig { // 尽最大可能保留原始字节(ISO_8859_1一一映射) payloadBytes = ((String) payloadObj).getBytes(StandardCharsets.ISO_8859_1); } else { - // 兜底:从toString获取,再按ISO_8859_1转换 payloadBytes = payloadObj.toString().getBytes(StandardCharsets.ISO_8859_1); } diff --git a/src/main/java/com/evobms/framework/config/SwaggerConfig.java b/src/main/java/com/evobms/framework/config/SwaggerConfig.java index 0f31dbc..40e72cb 100644 --- a/src/main/java/com/evobms/framework/config/SwaggerConfig.java +++ b/src/main/java/com/evobms/framework/config/SwaggerConfig.java @@ -23,7 +23,7 @@ import springfox.documentation.spring.web.plugins.Docket; /** * Swagger2的接口配置 - * + * * @author ruoyi */ @Configuration @@ -108,9 +108,9 @@ public class SwaggerConfig // 用ApiInfoBuilder进行定制 return new ApiInfoBuilder() // 设置标题 - .title("标题:若依管理系统_接口文档") + .title("标题:EVO-BMS 电池管理系统_接口文档") // 描述 - .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...") + .description("") // 作者信息 .contact(new Contact(ruoyiConfig.getName(), null, null)) // 版本 diff --git a/src/main/java/com/evobms/framework/web/domain/BaseEntity.java b/src/main/java/com/evobms/framework/web/domain/BaseEntity.java index f0f5d92..07ca85d 100644 --- a/src/main/java/com/evobms/framework/web/domain/BaseEntity.java +++ b/src/main/java/com/evobms/framework/web/domain/BaseEntity.java @@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModelProperty; /** * Entity基类 @@ -21,28 +22,35 @@ public class BaseEntity implements Serializable /** 搜索值 */ @JsonIgnore @TableField(exist = false) + @ApiModelProperty(value = "搜索值") private String searchValue; /** 创建者 */ + @ApiModelProperty(value = "创建者") private String createBy; /** 创建时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") private Date createTime; /** 更新者 */ + @ApiModelProperty(value = "更新者") private String updateBy; /** 更新时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新时间") private Date updateTime; /** 备注 */ @TableField(exist = false) + @ApiModelProperty(value = "备注") private String remark; /** 请求参数 */ @JsonInclude(JsonInclude.Include.NON_EMPTY) + @ApiModelProperty(value = "请求参数") @TableField(exist = false) private Map params; diff --git a/src/main/java/com/evobms/project/battery/controller/ExtremeValuesController.java b/src/main/java/com/evobms/project/battery/controller/ExtremeValuesController.java index 71c5d5b..ca6d553 100644 --- a/src/main/java/com/evobms/project/battery/controller/ExtremeValuesController.java +++ b/src/main/java/com/evobms/project/battery/controller/ExtremeValuesController.java @@ -20,15 +20,18 @@ import com.evobms.framework.web.controller.BaseController; import com.evobms.framework.web.domain.AjaxResult; import com.evobms.common.utils.poi.ExcelUtil; import com.evobms.framework.web.page.TableDataInfo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; /** * 电池极值数据Controller * * @author 田志阳 - * @date 2025-10-14 + * @date 2025-11-15 */ @RestController -@RequestMapping("/BatteryData/BatteryData") +@RequestMapping("/Battery/ExtremeValues") +@Api(tags = "电池极值数据") public class ExtremeValuesController extends BaseController { @Autowired @@ -37,8 +40,9 @@ public class ExtremeValuesController extends BaseController /** * 查询电池极值数据列表 */ - @PreAuthorize("@ss.hasPermi('BatteryData:BatteryData:list')") + @PreAuthorize("@ss.hasPermi('Battery:ExtremeValues:list')") @GetMapping("/list") + @ApiOperation("查询电池极值数据列表") public TableDataInfo list(ExtremeValues extremeValues) { startPage(); @@ -49,9 +53,10 @@ public class ExtremeValuesController extends BaseController /** * 导出电池极值数据列表 */ - @PreAuthorize("@ss.hasPermi('BatteryData:BatteryData:export')") + @PreAuthorize("@ss.hasPermi('Battery:ExtremeValues:export')") @Log(title = "电池极值数据", businessType = BusinessType.EXPORT) @PostMapping("/export") + @ApiOperation("导出电池极值数据列表") public void export(HttpServletResponse response, ExtremeValues extremeValues) { List list = extremeValuesService.selectExtremeValuesList(extremeValues); @@ -62,8 +67,9 @@ public class ExtremeValuesController extends BaseController /** * 获取电池极值数据详细信息 */ - @PreAuthorize("@ss.hasPermi('BatteryData:BatteryData:query')") + @PreAuthorize("@ss.hasPermi('Battery:ExtremeValues:query')") @GetMapping(value = "/{id}") + @ApiOperation("获取电池极值数据详细信息") public AjaxResult getInfo(@PathVariable("id") Long id) { return success(extremeValuesService.selectExtremeValuesById(id)); @@ -72,9 +78,10 @@ public class ExtremeValuesController extends BaseController /** * 新增电池极值数据 */ - @PreAuthorize("@ss.hasPermi('BatteryData:BatteryData:add')") + @PreAuthorize("@ss.hasPermi('Battery:ExtremeValues:add')") @Log(title = "电池极值数据", businessType = BusinessType.INSERT) @PostMapping + @ApiOperation("新增电池极值数据") public AjaxResult add(@RequestBody ExtremeValues extremeValues) { return toAjax(extremeValuesService.insertExtremeValues(extremeValues)); @@ -83,9 +90,10 @@ public class ExtremeValuesController extends BaseController /** * 修改电池极值数据 */ - @PreAuthorize("@ss.hasPermi('BatteryData:BatteryData:edit')") + @PreAuthorize("@ss.hasPermi('Battery:ExtremeValues:edit')") @Log(title = "电池极值数据", businessType = BusinessType.UPDATE) @PutMapping + @ApiOperation("修改电池极值数据") public AjaxResult edit(@RequestBody ExtremeValues extremeValues) { return toAjax(extremeValuesService.updateExtremeValues(extremeValues)); @@ -94,9 +102,10 @@ public class ExtremeValuesController extends BaseController /** * 删除电池极值数据 */ - @PreAuthorize("@ss.hasPermi('BatteryData:BatteryData:remove')") + @PreAuthorize("@ss.hasPermi('Battery:ExtremeValues:remove')") @Log(title = "电池极值数据", businessType = BusinessType.DELETE) - @DeleteMapping("/{ids}") + @DeleteMapping("/{ids}") + @ApiOperation("删除电池极值数据") public AjaxResult remove(@PathVariable Long[] ids) { return toAjax(extremeValuesService.deleteExtremeValuesByIds(ids)); diff --git a/src/main/java/com/evobms/project/battery/controller/SubsystemTemperatureController.java b/src/main/java/com/evobms/project/battery/controller/SubsystemTemperatureController.java index fd230dc..c9eaf5d 100644 --- a/src/main/java/com/evobms/project/battery/controller/SubsystemTemperatureController.java +++ b/src/main/java/com/evobms/project/battery/controller/SubsystemTemperatureController.java @@ -20,6 +20,8 @@ import com.evobms.framework.web.controller.BaseController; import com.evobms.framework.web.domain.AjaxResult; import com.evobms.common.utils.poi.ExcelUtil; import com.evobms.framework.web.page.TableDataInfo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; /** * 可充电储能子系统温度信息Controller @@ -28,7 +30,8 @@ import com.evobms.framework.web.page.TableDataInfo; * @date 2025-11-15 */ @RestController -@RequestMapping("/temperature/temperature") +@RequestMapping("/Battery/SubsystemTemperature") +@Api(tags = "可充电储能子系统温度信息") public class SubsystemTemperatureController extends BaseController { @Autowired @@ -37,8 +40,9 @@ public class SubsystemTemperatureController extends BaseController /** * 查询可充电储能子系统温度信息列表 */ - @PreAuthorize("@ss.hasPermi('temperature:temperature:list')") + @PreAuthorize("@ss.hasPermi('Battery:SubsystemTemperature:list')") @GetMapping("/list") + @ApiOperation("查询子系统温度信息列表") public TableDataInfo list(SubsystemTemperature subsystemTemperature) { startPage(); @@ -49,9 +53,10 @@ public class SubsystemTemperatureController extends BaseController /** * 导出可充电储能子系统温度信息列表 */ - @PreAuthorize("@ss.hasPermi('temperature:temperature:export')") + @PreAuthorize("@ss.hasPermi('Battery:SubsystemTemperature:export')") @Log(title = "可充电储能子系统温度信息", businessType = BusinessType.EXPORT) @PostMapping("/export") + @ApiOperation("导出子系统温度信息列表") public void export(HttpServletResponse response, SubsystemTemperature subsystemTemperature) { List list = subsystemTemperatureService.selectSubsystemTemperatureList(subsystemTemperature); @@ -62,8 +67,9 @@ public class SubsystemTemperatureController extends BaseController /** * 获取可充电储能子系统温度信息详细信息 */ - @PreAuthorize("@ss.hasPermi('temperature:temperature:query')") + @PreAuthorize("@ss.hasPermi('Battery:SubsystemTemperature:query')") @GetMapping(value = "/{id}") + @ApiOperation("获取子系统温度信息详细信息") public AjaxResult getInfo(@PathVariable("id") Long id) { return success(subsystemTemperatureService.selectSubsystemTemperatureById(id)); @@ -72,9 +78,10 @@ public class SubsystemTemperatureController extends BaseController /** * 新增可充电储能子系统温度信息 */ - @PreAuthorize("@ss.hasPermi('temperature:temperature:add')") + @PreAuthorize("@ss.hasPermi('Battery:SubsystemTemperature:add')") @Log(title = "可充电储能子系统温度信息", businessType = BusinessType.INSERT) @PostMapping + @ApiOperation("新增子系统温度信息") public AjaxResult add(@RequestBody SubsystemTemperature subsystemTemperature) { return toAjax(subsystemTemperatureService.insertSubsystemTemperature(subsystemTemperature)); @@ -83,9 +90,10 @@ public class SubsystemTemperatureController extends BaseController /** * 修改可充电储能子系统温度信息 */ - @PreAuthorize("@ss.hasPermi('temperature:temperature:edit')") + @PreAuthorize("@ss.hasPermi('Battery:SubsystemTemperature:edit')") @Log(title = "可充电储能子系统温度信息", businessType = BusinessType.UPDATE) @PutMapping + @ApiOperation("修改子系统温度信息") public AjaxResult edit(@RequestBody SubsystemTemperature subsystemTemperature) { return toAjax(subsystemTemperatureService.updateSubsystemTemperature(subsystemTemperature)); @@ -94,9 +102,10 @@ public class SubsystemTemperatureController extends BaseController /** * 删除可充电储能子系统温度信息 */ - @PreAuthorize("@ss.hasPermi('temperature:temperature:remove')") + @PreAuthorize("@ss.hasPermi('Battery:SubsystemTemperature:remove')") @Log(title = "可充电储能子系统温度信息", businessType = BusinessType.DELETE) - @DeleteMapping("/{ids}") + @DeleteMapping("/{ids}") + @ApiOperation("删除子系统温度信息") public AjaxResult remove(@PathVariable Long[] ids) { return toAjax(subsystemTemperatureService.deleteSubsystemTemperatureByIds(ids)); diff --git a/src/main/java/com/evobms/project/battery/controller/SubsystemVoltageController.java b/src/main/java/com/evobms/project/battery/controller/SubsystemVoltageController.java index 16c4b38..2b44afa 100644 --- a/src/main/java/com/evobms/project/battery/controller/SubsystemVoltageController.java +++ b/src/main/java/com/evobms/project/battery/controller/SubsystemVoltageController.java @@ -20,6 +20,8 @@ import com.evobms.framework.web.controller.BaseController; import com.evobms.framework.web.domain.AjaxResult; import com.evobms.common.utils.poi.ExcelUtil; import com.evobms.framework.web.page.TableDataInfo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; /** * 可充电储能子系统电压信息Controller @@ -28,7 +30,8 @@ import com.evobms.framework.web.page.TableDataInfo; * @date 2025-11-15 */ @RestController -@RequestMapping("/voltage/voltage") +@RequestMapping("/Battery/SubsystemVoltage") +@Api(tags = "可充电储能子系统电压信息") public class SubsystemVoltageController extends BaseController { @Autowired @@ -37,8 +40,9 @@ public class SubsystemVoltageController extends BaseController /** * 查询可充电储能子系统电压信息列表 */ - @PreAuthorize("@ss.hasPermi('voltage:voltage:list')") + @PreAuthorize("@ss.hasPermi('Battery:SubsystemVoltage:list')") @GetMapping("/list") + @ApiOperation("查询子系统电压信息列表") public TableDataInfo list(SubsystemVoltage subsystemVoltage) { startPage(); @@ -49,9 +53,10 @@ public class SubsystemVoltageController extends BaseController /** * 导出可充电储能子系统电压信息列表 */ - @PreAuthorize("@ss.hasPermi('voltage:voltage:export')") + @PreAuthorize("@ss.hasPermi('Battery:SubsystemVoltage:export')") @Log(title = "可充电储能子系统电压信息", businessType = BusinessType.EXPORT) @PostMapping("/export") + @ApiOperation("导出子系统电压信息列表") public void export(HttpServletResponse response, SubsystemVoltage subsystemVoltage) { List list = subsystemVoltageService.selectSubsystemVoltageList(subsystemVoltage); @@ -62,8 +67,9 @@ public class SubsystemVoltageController extends BaseController /** * 获取可充电储能子系统电压信息详细信息 */ - @PreAuthorize("@ss.hasPermi('voltage:voltage:query')") + @PreAuthorize("@ss.hasPermi('Battery:SubsystemVoltage:query')") @GetMapping(value = "/{id}") + @ApiOperation("获取子系统电压信息详细信息") public AjaxResult getInfo(@PathVariable("id") Long id) { return success(subsystemVoltageService.selectSubsystemVoltageById(id)); @@ -72,9 +78,10 @@ public class SubsystemVoltageController extends BaseController /** * 新增可充电储能子系统电压信息 */ - @PreAuthorize("@ss.hasPermi('voltage:voltage:add')") + @PreAuthorize("@ss.hasPermi('Battery:SubsystemVoltage:add')") @Log(title = "可充电储能子系统电压信息", businessType = BusinessType.INSERT) @PostMapping + @ApiOperation("新增子系统电压信息") public AjaxResult add(@RequestBody SubsystemVoltage subsystemVoltage) { return toAjax(subsystemVoltageService.insertSubsystemVoltage(subsystemVoltage)); @@ -83,9 +90,10 @@ public class SubsystemVoltageController extends BaseController /** * 修改可充电储能子系统电压信息 */ - @PreAuthorize("@ss.hasPermi('voltage:voltage:edit')") + @PreAuthorize("@ss.hasPermi('Battery:SubsystemVoltage:edit')") @Log(title = "可充电储能子系统电压信息", businessType = BusinessType.UPDATE) @PutMapping + @ApiOperation("修改子系统电压信息") public AjaxResult edit(@RequestBody SubsystemVoltage subsystemVoltage) { return toAjax(subsystemVoltageService.updateSubsystemVoltage(subsystemVoltage)); @@ -94,9 +102,10 @@ public class SubsystemVoltageController extends BaseController /** * 删除可充电储能子系统电压信息 */ - @PreAuthorize("@ss.hasPermi('voltage:voltage:remove')") + @PreAuthorize("@ss.hasPermi('Battery:SubsystemVoltage:remove')") @Log(title = "可充电储能子系统电压信息", businessType = BusinessType.DELETE) - @DeleteMapping("/{ids}") + @DeleteMapping("/{ids}") + @ApiOperation("删除子系统电压信息") public AjaxResult remove(@PathVariable Long[] ids) { return toAjax(subsystemVoltageService.deleteSubsystemVoltageByIds(ids)); diff --git a/src/main/java/com/evobms/project/battery/domain/ExtremeValues.java b/src/main/java/com/evobms/project/battery/domain/ExtremeValues.java index efc1949..73b65e7 100644 --- a/src/main/java/com/evobms/project/battery/domain/ExtremeValues.java +++ b/src/main/java/com/evobms/project/battery/domain/ExtremeValues.java @@ -2,7 +2,11 @@ package com.evobms.project.battery.domain; import java.math.BigDecimal; import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import com.evobms.framework.aspectj.lang.annotation.Excel; @@ -14,67 +18,85 @@ import com.evobms.framework.web.domain.BaseEntity; * @author 田志阳 * @date 2025-10-14 */ +@ApiModel(description = "电池极值数据对象") +@Data +@EqualsAndHashCode(callSuper = false) public class ExtremeValues extends BaseEntity { private static final long serialVersionUID = 1L; /** 主键ID */ + @ApiModelProperty(value = "主键ID") private Long id; /** 设备ID */ + @ApiModelProperty(value = "设备ID") @Excel(name = "设备ID") private String deviceId; /** 数据时间戳 */ + @ApiModelProperty(value = "数据时间戳") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Excel(name = "数据时间戳", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") private Date timestamp; /** 最高电压电池子系统号 */ + @ApiModelProperty(value = "最高电压电池子系统号") @Excel(name = "最高电压电池子系统号") private Integer maxVoltageSubsystemNo; /** 最高电压电池单体代号 */ + @ApiModelProperty(value = "最高电压电池单体代号") @Excel(name = "最高电压电池单体代号") private Integer maxVoltageBatteryNo; /** 电池单体电压最高值(V) */ + @ApiModelProperty(value = "电池单体电压最高值(V)") @Excel(name = "电池单体电压最高值(V)") private BigDecimal maxVoltageValue; /** 最低电压电池子系统号 */ + @ApiModelProperty(value = "最低电压电池子系统号") @Excel(name = "最低电压电池子系统号") private Integer minVoltageSubsystemNo; /** 最低电压电池单体代号 */ + @ApiModelProperty(value = "最低电压电池单体代号") @Excel(name = "最低电压电池单体代号") private Integer minVoltageBatteryNo; /** 电池单体电压最低值(V) */ + @ApiModelProperty(value = "电池单体电压最低值(V)") @Excel(name = "电池单体电压最低值(V)") private BigDecimal minVoltageValue; /** 最高温度子系统号 */ + @ApiModelProperty(value = "最高温度子系统号") @Excel(name = "最高温度子系统号") private Integer maxTempSubsystemNo; /** 最高温度探针序号 */ + @ApiModelProperty(value = "最高温度探针序号") @Excel(name = "最高温度探针序号") private Integer maxTempProbeNo; /** 最高温度值(℃) */ + @ApiModelProperty(value = "最高温度值(℃)") @Excel(name = "最高温度值(℃)") private BigDecimal maxTempValue; /** 最低温度子系统号 */ + @ApiModelProperty(value = "最低温度子系统号") @Excel(name = "最低温度子系统号") private Integer minTempSubsystemNo; /** 最低温度探针序号 */ + @ApiModelProperty(value = "最低温度探针序号") @Excel(name = "最低温度探针序号") private Integer minTempProbeNo; /** 最低温度值(℃) */ + @ApiModelProperty(value = "最低温度值(℃)") @Excel(name = "最低温度值(℃)") private BigDecimal minTempValue; 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 28f2fb9..5d69965 100644 --- a/src/main/java/com/evobms/project/battery/domain/SubsystemTemperature.java +++ b/src/main/java/com/evobms/project/battery/domain/SubsystemTemperature.java @@ -1,10 +1,13 @@ package com.evobms.project.battery.domain; import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import com.evobms.framework.aspectj.lang.annotation.Excel; import com.evobms.framework.web.domain.BaseEntity; +import lombok.EqualsAndHashCode; /** * 可充电储能子系统温度信息对象 subsystem_temperature @@ -13,44 +16,55 @@ import com.evobms.framework.web.domain.BaseEntity; * @date 2025-11-15 */ @Data +@ApiModel(description = "可充电储能子系统温度信息对象") +@EqualsAndHashCode(callSuper = false) public class SubsystemTemperature extends BaseEntity { private static final long serialVersionUID = 1L; /** 主键ID */ + @ApiModelProperty(value = "主键ID") private Long id; /** 设备ID */ + @ApiModelProperty(value = "设备ID") @Excel(name = "设备ID") private String deviceId; /** 数据时间戳 */ + @ApiModelProperty(value = "数据时间戳") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Excel(name = "数据时间戳", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") private Date timestamp; /** 可充电储能子系统个数 */ + @ApiModelProperty(value = "可充电储能子系统个数") @Excel(name = "可充电储能子系统个数") private Integer subsystemCount; /** 可充电储能子系统号 */ + @ApiModelProperty(value = "可充电储能子系统号") @Excel(name = "可充电储能子系统号") private Integer subsystemNo; /** 可充电储能温度探针个数 */ + @ApiModelProperty(value = "可充电储能温度探针个数") @Excel(name = "可充电储能温度探针个数") private Integer tempProbeCount; /** 各温度探针检测的温度值数组(℃) */ + @ApiModelProperty(value = "各温度探针检测的温度值数组(℃)") @Excel(name = "各温度探针检测的温度值数组(℃)") private String temperatureValues; /** 创建时间 */ + @ApiModelProperty(value = "创建时间") @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd") private Date createTime; /** 更新时间 */ + @ApiModelProperty(value = "更新时间") @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd") private Date updateTime; diff --git a/src/main/java/com/evobms/project/battery/domain/SubsystemVoltage.java b/src/main/java/com/evobms/project/battery/domain/SubsystemVoltage.java index 6dab1c8..7f1e3b3 100644 --- a/src/main/java/com/evobms/project/battery/domain/SubsystemVoltage.java +++ b/src/main/java/com/evobms/project/battery/domain/SubsystemVoltage.java @@ -2,6 +2,8 @@ package com.evobms.project.battery.domain; import java.math.BigDecimal; import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import org.apache.commons.lang3.builder.ToStringBuilder; @@ -16,60 +18,74 @@ import com.evobms.framework.web.domain.BaseEntity; * @date 2025-11-15 */ @Data +@ApiModel(description = "可充电储能子系统电压信息对象") public class SubsystemVoltage extends BaseEntity { private static final long serialVersionUID = 1L; /** 主键ID */ + @ApiModelProperty(value = "主键ID") private Long id; /** 设备ID */ + @ApiModelProperty(value = "设备ID") @Excel(name = "设备ID") private String deviceId; /** 数据时间戳 */ + @ApiModelProperty(value = "数据时间戳") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Excel(name = "数据时间戳", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") private Date timestamp; /** 可充电储能子系统个数 */ + @ApiModelProperty(value = "可充电储能子系统个数") @Excel(name = "可充电储能子系统个数") private Integer subsystemCount; /** 可充电储能子系统号 */ + @ApiModelProperty(value = "可充电储能子系统号") @Excel(name = "可充电储能子系统号") private Integer subsystemNo; /** 可充电储能装置电压(V) */ + @ApiModelProperty(value = "可充电储能装置电压(V)") @Excel(name = "可充电储能装置电压(V)") private BigDecimal subsystemVoltage; /** 可充电储能装置电流(A) */ + @ApiModelProperty(value = "可充电储能装置电流(A)") @Excel(name = "可充电储能装置电流(A)") private BigDecimal subsystemCurrent; /** 单体电池总数 */ + @ApiModelProperty(value = "单体电池总数") @Excel(name = "单体电池总数") private Integer totalBatteryCount; /** 本帧起始电池序号 */ + @ApiModelProperty(value = "本帧起始电池序号") @Excel(name = "本帧起始电池序号") private Integer frameStartBatteryNo; /** 本帧单体电池总数 */ + @ApiModelProperty(value = "本帧单体电池总数") @Excel(name = "本帧单体电池总数") private Integer frameBatteryCount; /** 单体电池电压数组(V) */ + @ApiModelProperty(value = "单体电池电压数组(V)") @Excel(name = "单体电池电压数组(V)") private String batteryVoltages; /** 创建时间 */ + @ApiModelProperty(value = "创建时间") @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd") private Date createTime; /** 更新时间 */ + @ApiModelProperty(value = "更新时间") @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd") private Date updateTime; 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 7786a48..4901a24 100644 --- a/src/main/java/com/evobms/project/bms/controller/GBT32960FullDecoder.java +++ b/src/main/java/com/evobms/project/bms/controller/GBT32960FullDecoder.java @@ -7,8 +7,10 @@ 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) { String s = sn == null ? "" : sn; @@ -68,150 +70,236 @@ public class GBT32960FullDecoder { } // 详细的协议解析方法 - public static String parseGBT32960Data(byte[] receivedData, String deviceSn) { - String bytesData = null; - try { - log.info("=== GBT32960协议数据解析 ==="); - log.info("实际数据长度: " + receivedData.length + " 字节"); - // 1. 检查起始位 - if (receivedData.length < 2 || receivedData[0] != 0x23 || receivedData[1] != 0x23) { - log.error("无效的起始位或数据过短"); - return null; - } - log.info("起始位: 0x2323 ✓"); + public static String parseGBT32960Data(byte[] receivedData, String deviceSn) { + String bytesData = null; + try { + log.info("=== GBT32960协议数据解析 ==="); + log.info("实际数据长度: " + receivedData.length + " 字节"); + // 1. 检查起始位 + if (receivedData.length < 2 || receivedData[0] != 0x23 || receivedData[1] != 0x23) { + log.error("无效的起始位或数据过短"); + return null; + } + log.info("起始位: 0x2323 ✓"); - // 2. 打印完整数据用于调试 - log.info("完整数据: " + bytesToHex(receivedData)); + // 2. 打印完整数据用于调试 + log.info("完整数据: " + bytesToHex(receivedData)); - // 3. 分析协议结构 - int offset = 2; // 跳过起始位 + // 3. 分析协议结构 + int offset = 2; // 跳过起始位 - // 命令标识 - byte commandId = receivedData[offset++]; - log.info("命令标识: 0x" + String.format("%02X", commandId)); + // 命令标识 + byte commandId = receivedData[offset++]; + log.info("命令标识: 0x" + String.format("%02X", commandId)); - // 应答标志 - byte responseFlag = receivedData[offset++]; - log.info("应答标志: 0x" + String.format("%02X", responseFlag)); + // 应答标志 + byte responseFlag = receivedData[offset++]; + log.info("应答标志: 0x" + String.format("%02X", responseFlag)); - // VIN码 (17字节) - byte[] vin = Arrays.copyOfRange(receivedData, offset, offset + 17); - offset += 17; - log.info("VIN码: " + bytesToHex(vin) + " (" + new String(vin).trim() + ")"); + // VIN码 (17字节) + byte[] vin = Arrays.copyOfRange(receivedData, offset, offset + 17); + offset += 17; + log.info("VIN码: " + bytesToHex(vin) + " (" + new String(vin).trim() + ")"); - // 加密方式 - byte encryptionMethod = receivedData[offset++]; - log.info("加密方式: 0x" + String.format("%02X", encryptionMethod)); + // 加密方式 + byte encryptionMethod = receivedData[offset++]; + log.info("加密方式: 0x" + String.format("%02X", encryptionMethod)); - if (encryptionMethod != 0x03) { - log.error("不支持的解密方式,期望AES128(0x03)"); - return null; - } + if (encryptionMethod != 0x03) { + log.error("不支持的解密方式,期望AES128(0x03)"); + return null; + } - // 数据单元长度 (WORD, 大端序) - int dataUnitLength = ((receivedData[offset] & 0xFF) << 8) | (receivedData[offset + 1] & 0xFF); - offset += 2; - log.info("声明的数据单元长度: " + dataUnitLength + " 字节"); + // 数据单元长度 (WORD, 大端序) + int dataUnitLength = ((receivedData[offset] & 0xFF) << 8) | (receivedData[offset + 1] & 0xFF); + offset += 2; + log.info("声明的数据单元长度: " + dataUnitLength + " 字节"); - // 计算当前头部长度 - int headerLength = offset; - log.info("协议头部长度: " + headerLength + " 字节"); + // 计算当前头部长度 + int headerLength = offset; + log.info("协议头部长度: " + headerLength + " 字节"); - // 剩余数据长度 - int remainingDataLength = receivedData.length - headerLength; - log.info("剩余数据长度: " + remainingDataLength + " 字节"); + // 剩余数据长度 + int remainingDataLength = receivedData.length - headerLength; + log.info("剩余数据长度: " + remainingDataLength + " 字节"); - // 4. 重新计算期望长度 - // 方案1: 如果BCC是1字节 - int expectedLength1 = headerLength + dataUnitLength + 1; - // 方案2: 如果BCC是2字节(根据您最初描述) - int expectedLength2 = headerLength + dataUnitLength + 2; + // 4. 重新计算期望长度 + // 方案1: 如果BCC是1字节 + int expectedLength1 = headerLength + dataUnitLength + 1; + // 方案2: 如果BCC是2字节(根据您最初描述) + int expectedLength2 = headerLength + dataUnitLength + 2; - log.info("期望长度 (BCC=1字节): " + expectedLength1); - log.info("期望长度 (BCC=2字节): " + expectedLength2); - log.info("实际长度: " + receivedData.length); + log.info("期望长度 (BCC=1字节): " + expectedLength1); + log.info("期望长度 (BCC=2字节): " + expectedLength2); + log.info("实际长度: " + receivedData.length); - // 5. 确定正确的数据范围 - int encryptedDataStart = offset; - int encryptedDataEnd; - int bccStart; + // 5. 确定正确的数据范围 + int encryptedDataStart = offset; + int encryptedDataEnd; + int bccStart; - if (receivedData.length == expectedLength1) { - // BCC为1字节 - encryptedDataEnd = encryptedDataStart + dataUnitLength; - bccStart = encryptedDataEnd; - log.info("采用方案: BCC为1字节"); - } else if (receivedData.length == expectedLength2) { - // BCC为2字节 - encryptedDataEnd = encryptedDataStart + dataUnitLength; - bccStart = encryptedDataEnd; - log.info("采用方案: BCC为2字节"); - } else { - // 自动适应:使用剩余的所有数据作为加密数据 - encryptedDataEnd = receivedData.length - 1; // 假设BCC为1字节 - int actualDataUnitLength = encryptedDataEnd - encryptedDataStart; - log.info("长度不匹配,使用实际数据单元长度: " + actualDataUnitLength + " 字节"); - dataUnitLength = actualDataUnitLength; - bccStart = encryptedDataEnd; - } + if (receivedData.length == expectedLength1) { + // BCC为1字节 + encryptedDataEnd = encryptedDataStart + dataUnitLength; + bccStart = encryptedDataEnd; + log.info("采用方案: BCC为1字节"); + } else if (receivedData.length == expectedLength2) { + // BCC为2字节 + encryptedDataEnd = encryptedDataStart + dataUnitLength; + bccStart = encryptedDataEnd; + log.info("采用方案: BCC为2字节"); + } else { + // 自动适应:使用剩余的所有数据作为加密数据 + encryptedDataEnd = receivedData.length - 1; // 假设BCC为1字节 + int actualDataUnitLength = encryptedDataEnd - encryptedDataStart; + log.info("长度不匹配,使用实际数据单元长度: " + actualDataUnitLength + " 字节"); + dataUnitLength = actualDataUnitLength; + bccStart = encryptedDataEnd; + } - // 6. 提取加密数据 - byte[] encryptedData = Arrays.copyOfRange(receivedData, encryptedDataStart, encryptedDataStart + dataUnitLength); - log.info("加密数据长度: " + encryptedData.length + " 字节"); - log.info("加密数据 (前64字节): " + bytesToHex(Arrays.copyOf(encryptedData, Math.min(64, encryptedData.length))) + "..."); + // 6. 提取加密数据 + byte[] encryptedData = Arrays.copyOfRange(receivedData, encryptedDataStart, encryptedDataStart + dataUnitLength); + log.info("加密数据长度: " + encryptedData.length + " 字节"); + log.info("加密数据 (前64字节): " + bytesToHex(Arrays.copyOf(encryptedData, Math.min(64, encryptedData.length))) + "..."); + if (encryptedData.length % 16 != 0) { + log.error("AES密文长度非法,不是16倍数,length=" + encryptedData.length); + return null; + } + // 7. 提取BCC校验码 + int bccLength = receivedData.length - (encryptedDataStart + dataUnitLength); + byte[] receivedBCC = Arrays.copyOfRange(receivedData, encryptedDataStart + dataUnitLength, receivedData.length); + //log.info("BCC长度: " + bccLength + " 字节"); + //log.info("接收到的BCC: " + bytesToHex(receivedBCC)); - // 7. 提取BCC校验码 - int bccLength = receivedData.length - (encryptedDataStart + dataUnitLength); - byte[] receivedBCC = Arrays.copyOfRange(receivedData, encryptedDataStart + dataUnitLength, receivedData.length); - //log.info("BCC长度: " + bccLength + " 字节"); - //log.info("接收到的BCC: " + bytesToHex(receivedBCC)); + // 8. 计算BCC校验范围:从命令单元开始到加密数据结束 + int bccCalcStart = 2; // 从命令标识开始 (跳过0x2323) + int bccCalcEnd = encryptedDataStart + dataUnitLength; + byte calculatedBCC = calculateBCC(receivedData, bccCalcStart, bccCalcEnd); - // 8. 计算BCC校验范围:从命令单元开始到加密数据结束 - int bccCalcStart = 2; // 从命令标识开始 (跳过0x2323) - int bccCalcEnd = encryptedDataStart + dataUnitLength; - byte calculatedBCC = calculateBCC(receivedData, bccCalcStart, bccCalcEnd); + log.info("BCC计算范围: 字节[" + bccCalcStart + "~" + bccCalcEnd + ")"); + log.info("计算出的BCC: 0x" + String.format("%02X", calculatedBCC)); - log.info("BCC计算范围: 字节[" + bccCalcStart + "~" + bccCalcEnd + ")"); - log.info("计算出的BCC: 0x" + String.format("%02X", calculatedBCC)); - - // 验证BCC (只比较第一个字节) - if (receivedBCC.length > 0 && calculatedBCC == receivedBCC[0]) { - log.info("BCC校验通过 ✓"); - } else { - log.error("BCC校验失败!"); - } + // 验证BCC (只比较第一个字节) + if (receivedBCC.length > 0 && calculatedBCC == receivedBCC[0]) { + log.info("BCC校验通过 ✓"); + } else { + log.error("BCC校验失败!"); + } - //使用的AES密钥 - byte[] aesKey = generateKeyFromSn(deviceSn); - System.out.println("密钥------------------------>"+aesKey); - byte[] decryptedData = decryptData(encryptedData, aesKey); - bytesData = bytesToHex(decryptedData); - log.info("解密成功!"); - log.info("解密后数据长度: " + decryptedData.length + " 字节"); - log.info("解密后数据 (完整): " + bytesData); + //使用的AES密钥 + byte[] aesKey = generateKeyFromSn(deviceSn); + System.out.println(Arrays.toString(aesKey)); + System.out.println(aesKey.length); + log.info("AES密钥: " + bytesToHex(aesKey)); + byte[] decryptedData = decryptData(encryptedData, aesKey); + bytesData = bytesToHex(decryptedData); + log.info("解密成功!"); + log.info("解密后数据长度: " + decryptedData.length + " 字节"); + log.info("解密后数据 (完整): " + bytesData); - // 10. 解析解密后的数据单元 - // parseDecryptedDataUnit(decryptedData); + // 10. 解析解密后的数据单元 + // parseDecryptedDataUnit(decryptedData); - } catch (Exception e) { - log.error("解析过程中发生错误: " + e.getMessage()); - e.printStackTrace(); + } catch (Exception e) { + log.error("解析过程中发生错误: " + e.getMessage()); + e.printStackTrace(); + } + return bytesData; + } + + /* public static String parseGBT32960Data(byte[] frame, String deviceSn) throws Exception { + + if (frame == null || frame.length < 25) { + throw new IllegalArgumentException("报文长度非法"); } - return bytesData; + int offset = 0; + // 1. 起始符校验 0x23 0x23 + + if (frame[offset++] != 0x23 || frame[offset++] != 0x23) { + throw new IllegalArgumentException("非法起始位,非0x2323"); + } + // 2. 命令标识 + byte commandId = frame[offset++]; + // 3. 应答标志 + byte responseFlag = frame[offset++]; + // 4. VIN (17字节) + byte[] vinBytes = Arrays.copyOfRange(frame, offset, offset + 17); + String vin = new String(vinBytes).trim(); + offset += 17; + // 5. 加密方式 + byte encryptType = frame[offset++]; + // 6. 数据单元长度 (大端) + if (offset + 2 > frame.length) { + throw new IllegalArgumentException("数据单元长度字段越界"); + } + int dataUnitLength = ((frame[offset] & 0xFF) << 8) | (frame[offset + 1] & 0xFF); + offset += 2; + int headerLength = offset; + + // 7. 校验整体长度 + // 标准格式: + // 头部 + 数据单元 + 1字节BCC + int expectedLength = headerLength + dataUnitLength + 1; + if (frame.length != expectedLength) { + throw new IllegalArgumentException("报文长度不匹配,声明长度=" + dataUnitLength + ",实际长度=" + frame.length + ",期望总长度=" + expectedLength); + } + // 8. 提取数据单元 + byte[] dataUnit = Arrays.copyOfRange(frame, headerLength, headerLength + dataUnitLength + ); + // 9. BCC 校验 + // BCC范围:从命令标识开始 + byte receivedBcc = frame[frame.length - 1]; + byte calculatedBcc = calculateBCC(frame, 2, headerLength + dataUnitLength + ); + if (receivedBcc != calculatedBcc) { + throw new IllegalStateException( + String.format("BCC校验失败,收到=0x%02X 计算=0x%02X", + receivedBcc, calculatedBcc) + ); + } + + + // 10. 加密处理 + + if (encryptType == 0x01) { + // 不加密 + return bytesToHex(dataUnit); + } + + if (encryptType != 0x03) { + throw new UnsupportedOperationException( + "不支持的加密方式: " + encryptType); + } + + // AES 必须 16倍数 + if (dataUnitLength % 16 != 0) { + throw new IllegalStateException( + "AES密文长度非法,不是16倍数,length=" + dataUnitLength); + } + + + // 11. AES解密 + + byte[] aesKey = generateKeyFromSn(deviceSn); + + byte[] decrypted = decryptData(dataUnit, aesKey); + + return bytesToHex(decrypted); } +*/ private static void parseDecryptedDataUnit(byte[] decryptedData) { - log.info("\n=== 数据单元解析 ==="); + log.info("\n=== 数据单元解析 ==="); if (decryptedData == null || decryptedData.length == 0) { - log.info("解密数据为空"); + log.info("解密数据为空"); return; } - log.info("数据单元总长度: " + decryptedData.length + " 字节"); - log.info("数据单元内容: " + bytesToHex(decryptedData)); + log.info("数据单元总长度: " + decryptedData.length + " 字节"); + log.info("数据单元内容: " + bytesToHex(decryptedData)); // 尝试解析采集时间(前6字节BCD) if (decryptedData.length >= 6) { @@ -280,16 +368,26 @@ public class GBT32960FullDecoder { private static String typeName(int typeId) { switch (typeId & 0xFF) { - case 0x01: return "整车数据"; - case 0x02: return "驱动电机数据"; - case 0x03: return "燃料电池数据"; - case 0x04: return "发动机数据"; - case 0x05: return "车辆位置数据"; - case 0x06: return "极值数据"; - case 0x07: return "报警数据"; - case 0x08: return "储能装置电压数据"; - case 0x09: return "储能装置温度数据"; - default: return String.format("未知类型(0x%02X)", typeId); + case 0x01: + return "整车数据"; + case 0x02: + return "驱动电机数据"; + case 0x03: + return "燃料电池数据"; + case 0x04: + return "发动机数据"; + case 0x05: + return "车辆位置数据"; + case 0x06: + return "极值数据"; + case 0x07: + return "报警数据"; + case 0x08: + return "储能装置电压数据"; + case 0x09: + return "储能装置温度数据"; + default: + return String.format("未知类型(0x%02X)", typeId); } } diff --git a/src/main/java/com/evobms/project/bms/controller/MqttPublishController.java b/src/main/java/com/evobms/project/bms/controller/MqttPublishController.java index 7584d49..03f0edb 100644 --- a/src/main/java/com/evobms/project/bms/controller/MqttPublishController.java +++ b/src/main/java/com/evobms/project/bms/controller/MqttPublishController.java @@ -5,6 +5,8 @@ import com.evobms.common.constant.Constants; import com.evobms.common.constant.BboxApiConstants; import com.evobms.common.utils.StringUtils; import com.evobms.project.bms.service.MqttService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import javax.servlet.http.HttpServletRequest; @@ -25,6 +27,7 @@ import org.slf4j.LoggerFactory; */ @RestController @RequestMapping("/bms/mqtt") +@Api(tags = "MQTT消息发布") public class MqttPublishController { private static final Logger log = LoggerFactory.getLogger(MqttPublishController.class); @@ -39,6 +42,7 @@ public class MqttPublishController { */ @PostMapping("/publish") // @Log(title = "MQTT消息发布", businessType = BusinessType.INSERT) + @ApiOperation("发布文本消息") public AjaxResult publishMessage(@RequestParam String topic, @RequestParam String message) { try { if (mqttService == null) { @@ -58,6 +62,7 @@ public class MqttPublishController { * 发布原始十六进制字节消息到指定主题 */ @PostMapping("/publishHex") + @ApiOperation("发布HEX消息") public AjaxResult publishHex(@RequestParam String topic, @RequestParam String hex) { try { if (mqttService == null) { @@ -78,6 +83,7 @@ public class MqttPublishController { * 获取当前请求的鉴权令牌(从请求头读取并去除前缀) */ @GetMapping("/authToken") + @ApiOperation("获取鉴权令牌") public AjaxResult getAuthToken(HttpServletRequest request) { try { String raw = request.getHeader(tokenHeader); @@ -129,6 +135,7 @@ public class MqttPublishController { */ @PostMapping("/publishDeviceData") // @Log(title = "设备数据发布", businessType = BusinessType.INSERT) + @ApiOperation("发布设备测试数据") public AjaxResult publishDeviceData(@RequestParam String deviceCode) { try { if (mqttService == null) { @@ -160,6 +167,7 @@ public class MqttPublishController { * 快速测试 - 发布消息到test设备 */ @GetMapping("/quickTest") + @ApiOperation("快速测试发布") public AjaxResult quickTest() { try { if (mqttService == null) { @@ -192,6 +200,7 @@ public class MqttPublishController { */ @PostMapping("/batchPublish") // @Log(title = "批量MQTT消息发布", businessType = BusinessType.INSERT) + @ApiOperation("批量发布测试消息") public AjaxResult batchPublish(@RequestParam String deviceCode, @RequestParam(defaultValue = "5") int count) { try { if (mqttService == null) { diff --git a/src/main/java/com/evobms/project/bms/controller/MqttTestController.java b/src/main/java/com/evobms/project/bms/controller/MqttTestController.java index 5aa32e3..ce5da7f 100644 --- a/src/main/java/com/evobms/project/bms/controller/MqttTestController.java +++ b/src/main/java/com/evobms/project/bms/controller/MqttTestController.java @@ -1,6 +1,8 @@ package com.evobms.project.bms.controller; import com.evobms.project.bms.service.MqttService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.slf4j.Logger; @@ -17,6 +19,7 @@ import java.util.Map; */ @RestController @RequestMapping("/mqtt/test") +@Api(tags = "MQTT测试") public class MqttTestController { private static final Logger log = LoggerFactory.getLogger(MqttTestController.class); @@ -31,6 +34,7 @@ public class MqttTestController { * @return 测试结果 */ @PostMapping("/handleDeviceData") + @ApiOperation("测试处理设备数据") public Map testHandleDeviceData( @RequestParam String topic, @RequestParam byte[] payload) { @@ -70,6 +74,7 @@ public class MqttTestController { * @return 测试用的JSON数据 */ @GetMapping("/generateTestData") + @ApiOperation("生成测试数据") public Map generateTestData() { Map testData = new HashMap<>(); testData.put("voltage", 12.5); diff --git a/src/main/java/com/evobms/project/bms/domain/BmsChargeDetail.java b/src/main/java/com/evobms/project/bms/domain/BmsChargeDetail.java new file mode 100644 index 0000000..6a7cf38 --- /dev/null +++ b/src/main/java/com/evobms/project/bms/domain/BmsChargeDetail.java @@ -0,0 +1,75 @@ +package com.evobms.project.bms.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import com.evobms.framework.aspectj.lang.annotation.Excel; +import com.evobms.framework.web.domain.BaseEntity; + +@Data +@ApiModel(description = "BMS充电过程详细数据") +public class BmsChargeDetail extends BaseEntity { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("主键ID") + private Long id; + + @ApiModelProperty("设备ID") + @Excel(name = "设备ID") + private String deviceId; + + @ApiModelProperty("数据时间戳") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "数据时间戳", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date timestamp; + + @ApiModelProperty("慢充电流(A)") + @Excel(name = "慢充电流(A)") + private java.math.BigDecimal acChargeCurrent; + + @ApiModelProperty("慢充电压(V)") + @Excel(name = "慢充电压(V)") + private java.math.BigDecimal acChargeVoltage; + + @ApiModelProperty("快充电流(A)") + @Excel(name = "快充电流(A)") + private java.math.BigDecimal dcChargeCurrent; + + @ApiModelProperty("快充电压(V)") + @Excel(name = "快充电压(V)") + private java.math.BigDecimal dcChargeVoltage; + + @ApiModelProperty("充电时长(min)") + @Excel(name = "充电时长(min)") + private Integer chargeTime; + + @ApiModelProperty("慢充停止码") + @Excel(name = "慢充停止码") + private Integer acStopCode; + + @ApiModelProperty("快充停止码") + @Excel(name = "快充停止码") + private Integer dcStopCode; + + @ApiModelProperty("慢充CP值") + @Excel(name = "慢充CP值") + private Integer acCpValue; + + @ApiModelProperty("慢充枪阻值") + @Excel(name = "慢充枪阻值") + private Integer acGunResistance; + + @ApiModelProperty("充电阶段") + @Excel(name = "充电阶段") + private Integer chargingStage; + + @ApiModelProperty("慢充阶段") + @Excel(name = "慢充阶段") + private Integer acStage; + + @ApiModelProperty("快充阶段") + @Excel(name = "快充阶段") + private Integer dcStage; +} diff --git a/src/main/java/com/evobms/project/bms/domain/BmsSopData.java b/src/main/java/com/evobms/project/bms/domain/BmsSopData.java new file mode 100644 index 0000000..41a8de4 --- /dev/null +++ b/src/main/java/com/evobms/project/bms/domain/BmsSopData.java @@ -0,0 +1,67 @@ +package com.evobms.project.bms.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import com.evobms.framework.aspectj.lang.annotation.Excel; +import com.evobms.framework.web.domain.BaseEntity; + +@Data +@ApiModel(description = "BMS功率能力(SOP)数据") +public class BmsSopData extends BaseEntity { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("主键ID") + private Long id; + + @ApiModelProperty("设备ID") + @Excel(name = "设备ID") + private String deviceId; + + @ApiModelProperty("数据时间戳") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "数据时间戳", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date timestamp; + + @ApiModelProperty("10秒放电SOP(A)") + @Excel(name = "10秒放电SOP(A)") + private Integer dischargeSop10s; + + @ApiModelProperty("30秒放电SOP(A)") + @Excel(name = "30秒放电SOP(A)") + private Integer dischargeSop30s; + + @ApiModelProperty("60秒放电SOP(A)") + @Excel(name = "60秒放电SOP(A)") + private Integer dischargeSop60s; + + @ApiModelProperty("持续放电SOP(A)") + @Excel(name = "持续放电SOP(A)") + private Integer dischargeSopContinuous; + + @ApiModelProperty("10秒回馈SOP(A)") + @Excel(name = "10秒回馈SOP(A)") + private Integer regenSop10s; + + @ApiModelProperty("30秒回馈SOP(A)") + @Excel(name = "30秒回馈SOP(A)") + private Integer regenSop30s; + + @ApiModelProperty("60秒回馈SOP(A)") + @Excel(name = "60秒回馈SOP(A)") + private Integer regenSop60s; + + @ApiModelProperty("持续回馈SOP(A)") + @Excel(name = "持续回馈SOP(A)") + private Integer regenSopContinuous; + + @ApiModelProperty("充电SOP(A)") + @Excel(name = "充电SOP(A)") + private Integer chargeSop; + + @ApiModelProperty("慢充SOP(A)") + @Excel(name = "慢充SOP(A)") + private Integer acChargeSop; +} diff --git a/src/main/java/com/evobms/project/bms/domain/BmsSystemStatus.java b/src/main/java/com/evobms/project/bms/domain/BmsSystemStatus.java new file mode 100644 index 0000000..0d65d05 --- /dev/null +++ b/src/main/java/com/evobms/project/bms/domain/BmsSystemStatus.java @@ -0,0 +1,59 @@ +package com.evobms.project.bms.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import com.evobms.framework.aspectj.lang.annotation.Excel; +import com.evobms.framework.web.domain.BaseEntity; + +@Data +@ApiModel(description = "BMS系统状态数据") +public class BmsSystemStatus extends BaseEntity { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("主键ID") + private Long id; + + @ApiModelProperty("设备ID") + @Excel(name = "设备ID") + private String deviceId; + + @ApiModelProperty("数据时间戳") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "数据时间戳", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date timestamp; + + @ApiModelProperty("继电器状态") + @Excel(name = "继电器状态") + private Integer relayStatus; + + @ApiModelProperty("ON/A+/CC状态") + @Excel(name = "ON/A+/CC状态") + private Integer onaaccStatus; + + @ApiModelProperty("系统复位次数") + @Excel(name = "系统复位次数") + private Integer resetCount; + + @ApiModelProperty("电池循环次数") + @Excel(name = "电池循环次数") + private Integer cycleCount; + + @ApiModelProperty("2.5V采样电压(V)") + @Excel(name = "2.5V采样电压(V)") + private java.math.BigDecimal sample25v; + + @ApiModelProperty("5V采样电压(V)") + @Excel(name = "5V采样电压(V)") + private java.math.BigDecimal sample5v; + + @ApiModelProperty("单体数量") + @Excel(name = "单体数量") + private Integer cellCount; + + @ApiModelProperty("温度探头数量") + @Excel(name = "温度探头数量") + private Integer tempSensorCount; +} diff --git a/src/main/java/com/evobms/project/bms/mapper/BmsChargeDetailMapper.java b/src/main/java/com/evobms/project/bms/mapper/BmsChargeDetailMapper.java new file mode 100644 index 0000000..b605020 --- /dev/null +++ b/src/main/java/com/evobms/project/bms/mapper/BmsChargeDetailMapper.java @@ -0,0 +1,9 @@ +package com.evobms.project.bms.mapper; + +import com.evobms.project.bms.domain.BmsChargeDetail; +import java.util.List; + +public interface BmsChargeDetailMapper { + int insertBmsChargeDetail(BmsChargeDetail data); + List selectBmsChargeDetailList(BmsChargeDetail filter); +} diff --git a/src/main/java/com/evobms/project/bms/mapper/BmsSopDataMapper.java b/src/main/java/com/evobms/project/bms/mapper/BmsSopDataMapper.java new file mode 100644 index 0000000..65e6660 --- /dev/null +++ b/src/main/java/com/evobms/project/bms/mapper/BmsSopDataMapper.java @@ -0,0 +1,9 @@ +package com.evobms.project.bms.mapper; + +import com.evobms.project.bms.domain.BmsSopData; +import java.util.List; + +public interface BmsSopDataMapper { + int insertBmsSopData(BmsSopData data); + List selectBmsSopDataList(BmsSopData filter); +} diff --git a/src/main/java/com/evobms/project/bms/mapper/BmsSystemStatusMapper.java b/src/main/java/com/evobms/project/bms/mapper/BmsSystemStatusMapper.java new file mode 100644 index 0000000..1ae6a08 --- /dev/null +++ b/src/main/java/com/evobms/project/bms/mapper/BmsSystemStatusMapper.java @@ -0,0 +1,9 @@ +package com.evobms.project.bms.mapper; + +import com.evobms.project.bms.domain.BmsSystemStatus; +import java.util.List; + +public interface BmsSystemStatusMapper { + int insertBmsSystemStatus(BmsSystemStatus data); + List selectBmsSystemStatusList(BmsSystemStatus filter); +} diff --git a/src/main/java/com/evobms/project/bms/service/IBmsChargeDetailService.java b/src/main/java/com/evobms/project/bms/service/IBmsChargeDetailService.java new file mode 100644 index 0000000..b50ff56 --- /dev/null +++ b/src/main/java/com/evobms/project/bms/service/IBmsChargeDetailService.java @@ -0,0 +1,7 @@ +package com.evobms.project.bms.service; + +import com.evobms.project.bms.domain.BmsChargeDetail; + +public interface IBmsChargeDetailService { + int insertBmsChargeDetail(BmsChargeDetail data); +} diff --git a/src/main/java/com/evobms/project/bms/service/IBmsSopDataService.java b/src/main/java/com/evobms/project/bms/service/IBmsSopDataService.java new file mode 100644 index 0000000..8436310 --- /dev/null +++ b/src/main/java/com/evobms/project/bms/service/IBmsSopDataService.java @@ -0,0 +1,7 @@ +package com.evobms.project.bms.service; + +import com.evobms.project.bms.domain.BmsSopData; + +public interface IBmsSopDataService { + int insertBmsSopData(BmsSopData data); +} diff --git a/src/main/java/com/evobms/project/bms/service/IBmsSystemStatusService.java b/src/main/java/com/evobms/project/bms/service/IBmsSystemStatusService.java new file mode 100644 index 0000000..01afb85 --- /dev/null +++ b/src/main/java/com/evobms/project/bms/service/IBmsSystemStatusService.java @@ -0,0 +1,7 @@ +package com.evobms.project.bms.service; + +import com.evobms.project.bms.domain.BmsSystemStatus; + +public interface IBmsSystemStatusService { + int insertBmsSystemStatus(BmsSystemStatus data); +} 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 ec21c82..ec12864 100644 --- a/src/main/java/com/evobms/project/bms/service/MqttService.java +++ b/src/main/java/com/evobms/project/bms/service/MqttService.java @@ -261,30 +261,32 @@ public class MqttService { */ private void parseByProtocolIndex(byte[] message, String deviceSn) { try { - // 1. 时间信息 - 索引24-29 (6字节) + // 1.时间戳- 索引24-29 (6字节) Date frameTime = parseTimeAtIndex(message, 0, deviceSn); if (frameTime == null) { frameTime = new Date(); } - // 2. 整车数据 - 索引30-49 (20字节) + // 2. 整车数据 - 绝对索引30-49(20字节) | 相对偏移: 6-25 parseVehicleDataAtIndex(message, 6, deviceSn, frameTime); - // 3. 位置信息 - 索引51-60 (10字节) + // 3. 位置信息 - 绝对索引51-60(10字节) | 相对偏移: 27-36 parseLocationDataAtIndex(message, 27, deviceSn, frameTime); - // 4. 极值数据 - 索引61-75 (14字节) + // 4. 极值数据 - 绝对索引61-75(15字节) | 相对偏移: 37-51 parseExtremeDataAtIndex(message, 37, deviceSn, frameTime); - // 5. 单体电压数据 - 索引76-447 (372字节) + // 5. 单体电压数据 - 绝对索引76-447(372字节) | 相对偏移: 52-423 parseCellVoltageAtIndex(message, 52, deviceSn, frameTime); - // 6. 单体温度数据 - 索引448-542 (95字节) + // 6. 单体温度数据 - 绝对索引448-542(95字节) | 相对偏移: 424-518 parseCellTemperatureAtIndex(message, 424, deviceSn, frameTime); - // 7. 累计充放电量 - 索引543-553 (11字节) + // 7. 累计充放电量 - 绝对索引543-553(11字节) | 相对偏移: 519-529 parseChargeDischargeAtIndex(message, 519, deviceSn, frameTime); + parseExtendedDataAtIndex(message, 506, deviceSn, frameTime); + log.info("设备 {} 所有数据段解析完成", deviceSn); } catch (Exception e) { @@ -293,7 +295,7 @@ public class MqttService { } /** - * 解析时间信息 - 索引24-29 (6字节) + * 解析时间信息 - 绝对索引24-29(6字节) | 相对偏移: 0-5 * 格式: 年(偏移2000) + 月 + 日 + 时 + 分 + 秒 */ private Date parseTimeAtIndex(byte[] message, int startIndex, String deviceSn) { @@ -330,7 +332,7 @@ public class MqttService { } /** - * 解析整车数据 - 索引30-49 (20字节) + * 解析整车数据 - 绝对索引30-49(20字节) | 相对偏移: 6-25 */ private void parseVehicleDataAtIndex(byte[] message, int startIndex, String deviceSn, Date frameTime) { try { @@ -381,7 +383,7 @@ public class MqttService { /** - * 解析位置信息 - 索引51-60 (10字节) + * 解析位置信息 - 绝对索引51-60(10字节) | 相对偏移: 27-36 */ private void parseLocationDataAtIndex(byte[] message, int startIndex, String deviceSn, Date frameTime) { try { @@ -431,7 +433,7 @@ public class MqttService { } /** - * 解析极值数据 - 索引61-75 (14字节) + * 解析极值数据 - 绝对索引61-75(15字节) | 相对偏移: 37-51 */ private void parseExtremeDataAtIndex(byte[] message, int startIndex, String deviceSn, Date frameTime) { try { @@ -492,7 +494,7 @@ public class MqttService { /** - * 解析单体电压数据 - 索引76-447 (372字节) + * 解析单体电压数据 - 绝对索引76-447(372字节) | 相对偏移: 52-423 */ private void parseCellVoltageAtIndex(byte[] message, int startIndex, String deviceSn, Date frameTime) { try { @@ -575,7 +577,7 @@ public class MqttService { /** - * 解析单体温度数据 - 索引448-542 (95字节) + * 解析单体温度数据 - 绝对索引448-542(95字节) | 相对偏移: 424-518 */ private void parseCellTemperatureAtIndex(byte[] message, int startIndex, String deviceSn, Date frameTime) { try { @@ -638,7 +640,7 @@ public class MqttService { } /** - * 解析累计充放电量 - 索引543-553 (11字节) + * 解析累计充放电量 - 绝对索引543-553(11字节) | 相对偏移: 519-529 */ private void parseChargeDischargeAtIndex(byte[] message, int startIndex, String deviceSn, Date frameTime) { try { @@ -646,7 +648,6 @@ public class MqttService { log.warn("设备 {}: 充放电数据索引越界", deviceSn); return; } - // 索引543: 数据标识 (应该是0x80) byte dataFlag = message[startIndex]; if (dataFlag != (byte) 0x80) { @@ -658,16 +659,10 @@ public class MqttService { // 跳过索引544-545的保留字节 // 索引546-549: 累计放电电量 (0.1kWh) - long dischargeEnergy = ((message[startIndex + 3] & 0xFFL) << 24) | - ((message[startIndex + 4] & 0xFFL) << 16) | - ((message[startIndex + 5] & 0xFFL) << 8) | - (message[startIndex + 6] & 0xFFL); + long dischargeEnergy = ((message[startIndex + 3] & 0xFFL) << 24) | ((message[startIndex + 4] & 0xFFL) << 16) | ((message[startIndex + 5] & 0xFFL) << 8) | (message[startIndex + 6] & 0xFFL); // 索引550-553: 累计充电电量 (0.1kWh) - long chargeEnergy = ((message[startIndex + 7] & 0xFFL) << 24) | - ((message[startIndex + 8] & 0xFFL) << 16) | - ((message[startIndex + 9] & 0xFFL) << 8) | - (message[startIndex + 10] & 0xFFL); + long chargeEnergy = ((message[startIndex + 7] & 0xFFL) << 24) |((message[startIndex + 8] & 0xFFL) << 16) | ((message[startIndex + 9] & 0xFFL) << 8) | (message[startIndex + 10] & 0xFFL); double dischargeKwh = dischargeEnergy * 0.1; double chargeKwh = chargeEnergy * 0.1; @@ -944,6 +939,132 @@ public class MqttService { sendDeviceCommand(deviceCode, "STATUS_QUERY"); } + /** + * 扩展区块解析(BatteryData[530..716]) + * 索引换算: 绝对索引abs → message索引 = startIndex + (abs - 530) + * 单位与偏移: + * - 电压/电流 ×0.1(除特殊 2.5V/5V 采样为 ×0.001) + * - 温度值需减去 40(协议偏移) + * - 车速 ×0.1 km/h + * - 里程为 u32 原始值(单位由上位业务确定) + */ + private void parseExtendedDataAtIndex(byte[] message, int startIndex, String deviceSn, Date frameTime) { + try { + int base = startIndex; + int need = (716 - 530 + 1); + if (message.length < base + need) { + log.warn("设备 {}: 扩展数据索引越界", deviceSn); + return; + } + // 系统计数/绝缘/车速/总压 + long resetCount = ((message[base + 0] & 0xFFL) << 24) | ((message[base + 1] & 0xFFL) << 16) | ((message[base + 2] & 0xFFL) << 8) | (message[base + 3] & 0xFFL); // 复位次数(u32) + int insulationVal = ((message[base + 4] & 0xFF) << 8) | (message[base + 5] & 0xFF); // 绝缘值(单位KΩ) + int carSpdRaw = ((message[base + 6] & 0xFF) << 8) | (message[base + 7] & 0xFF); // 车速原始(×0.1km/h) + double carSpd = carSpdRaw * 0.1; + int gpvRaw = ((message[base + 8] & 0xFF) << 8) | (message[base + 9] & 0xFF); // GPV(×0.1V) + double gpv = gpvRaw * 0.1; + // RTP1..7(×0.1V) + double rtp1 = (((message[base + 10] & 0xFF) << 8) | (message[base + 11] & 0xFF)) * 0.1; + double rtp2 = (((message[base + 12] & 0xFF) << 8) | (message[base + 13] & 0xFF)) * 0.1; + double rtp3 = (((message[base + 14] & 0xFF) << 8) | (message[base + 15] & 0xFF)) * 0.1; + double rtp4 = (((message[base + 16] & 0xFF) << 8) | (message[base + 17] & 0xFF)) * 0.1; + double rtp5 = (((message[base + 18] & 0xFF) << 8) | (message[base + 19] & 0xFF)) * 0.1; + double rtp6 = (((message[base + 20] & 0xFF) << 8) | (message[base + 21] & 0xFF)) * 0.1; + double rtp7 = (((message[base + 22] & 0xFF) << 8) | (message[base + 23] & 0xFF)) * 0.1; + // RTN探针序号 + int rtn1 = message[base + 24] & 0xFF; // RTN1 + int rtn2 = message[base + 25] & 0xFF; // RTN2 + int rtn3 = message[base + 26] & 0xFF; // RTN3 + int rtn4 = message[base + 27] & 0xFF; // RTN4 + double realSocMax = (((message[base + 28] & 0xFF) << 8) | (message[base + 29] & 0xFF)) * 0.1; // RealSOC最大(×0.1%) + double realSocMin = (((message[base + 30] & 0xFF) << 8) | (message[base + 31] & 0xFF)) * 0.1; // RealSOC最小(×0.1%) + // 充电座温度(℃,需减40) + int chgBs1Tmp = (message[base + 32] & 0xFF) - 40; + int chgBs2Tmp = (message[base + 33] & 0xFF) - 40; + int chgBs3Tmp = (message[base + 34] & 0xFF) - 40; + int chgBs4Tmp = (message[base + 35] & 0xFF) - 40; + int chgBs5Tmp = (message[base + 36] & 0xFF) - 40; + int chgBs6Tmp = (message[base + 37] & 0xFF) - 40; + int chgBs7Tmp = (message[base + 38] & 0xFF) - 40; + int chgBs8Tmp = (message[base + 39] & 0xFF) - 40; + // 慢充/快充电流电压(×0.1) + double tChgCur = (((message[base + 40] & 0xFF) << 8) | (message[base + 41] & 0xFF)) * 0.1; // 慢充电流(A) + double tChgVol = (((message[base + 42] & 0xFF) << 8) | (message[base + 43] & 0xFF)) * 0.1; // 慢充电压(V) + double fChgCur = (((message[base + 44] & 0xFF) << 8) | (message[base + 45] & 0xFF)) * 0.1; // 快充电流(A) + double fChgVol = (((message[base + 46] & 0xFF) << 8) | (message[base + 47] & 0xFF)) * 0.1; // 快充电压(V) + // 放电/回馈SOP能力(A) + int disSop10 = ((message[base + 48] & 0xFF) << 8) | (message[base + 49] & 0xFF); + int disSop30 = ((message[base + 50] & 0xFF) << 8) | (message[base + 51] & 0xFF); + int disSop60 = ((message[base + 52] & 0xFF) << 8) | (message[base + 53] & 0xFF); + int disSopCont = ((message[base + 54] & 0xFF) << 8) | (message[base + 55] & 0xFF); + int regSop10 = ((message[base + 56] & 0xFF) << 8) | (message[base + 57] & 0xFF); + int regSop30 = ((message[base + 58] & 0xFF) << 8) | (message[base + 59] & 0xFF); + int regSop60 = ((message[base + 60] & 0xFF) << 8) | (message[base + 61] & 0xFF); + int regSopCont = ((message[base + 62] & 0xFF) << 8) | (message[base + 63] & 0xFF); + int disSopTol = ((message[base + 64] & 0xFF) << 8) | (message[base + 65] & 0xFF); + int regSopTol = ((message[base + 66] & 0xFF) << 8) | (message[base + 67] & 0xFF); + // 版本与编码 + int hwVer = ((message[base + 68] & 0xFF) << 8) | (message[base + 69] & 0xFF); // 硬件版本 + int swVer = ((message[base + 70] & 0xFF) << 8) | (message[base + 71] & 0xFF); // 软件版本 + String bmsCode = readAsciiRange(message, 602, 28, base); // BMS编码(28字节ASCII) + String vin = readAsciiRange(message, 629, 21, base); // VIN码(21字节ASCII) + // 系统状态 + int sysVolRaw = ((message[base + (649 - 530)] & 0xFF) << 8) | (message[base + (650 - 530)] & 0xFF); // 系统电压(×0.1V) + int sysCurRaw = ((message[base + (651 - 530)] & 0xFF) << 8) | (message[base + (652 - 530)] & 0xFF); // 系统电流(×0.1A) + double sysVol = sysVolRaw * 0.1; + double sysCur = sysCurRaw * 0.1; + int cellCount = ((message[base + (653 - 530)] & 0xFF) << 8) | (message[base + (654 - 530)] & 0xFF); + int tempSensorCount = ((message[base + (655 - 530)] & 0xFF) << 8) | (message[base + (656 - 530)] & 0xFF); + int relayStatus = ((message[base + (657 - 530)] & 0xFF) << 8) | (message[base + (658 - 530)] & 0xFF); + int onaaccStatus = ((message[base + (659 - 530)] & 0xFF) << 8) | (message[base + (660 - 530)] & 0xFF); + int acStopCode = message[base + (661 - 530)] & 0xFF; + int dcStopCode = message[base + (662 - 530)] & 0xFF; + int cycleCount = ((message[base + (663 - 530)] & 0xFF) << 8) | (message[base + (664 - 530)] & 0xFF); + long devId = ((message[base + (665 - 530)] & 0xFFL) << 24) | ((message[base + (666 - 530)] & 0xFFL) << 16) | ((message[base + (667 - 530)] & 0xFFL) << 8) | (message[base + (668 - 530)] & 0xFFL); + String clientCode = readAsciiRange(message, 669, 28, base); // 客户编码(28字节ASCII) + double samp25v = (((message[base + (696 - 530)] & 0xFF) << 8) | (message[base + (697 - 530)] & 0xFF)) * 0.001; // 2.5V采样(×0.001V) + double samp5v = (((message[base + (698 - 530)] & 0xFF) << 8) | (message[base + (699 - 530)] & 0xFF)) * 0.001; // 5V采样(×0.001V) + int chargeSop = ((message[base + (700 - 530)] & 0xFF) << 8) | (message[base + (701 - 530)] & 0xFF); // 充电SOP(A) + int acChargeSop = ((message[base + (702 - 530)] & 0xFF) << 8) | (message[base + (703 - 530)] & 0xFF); // 慢充SOP(A) + // 运行阶段/充电阶段/时间与里程 + int runSts = message[base + (704 - 530)] & 0xFF; // 行车阶段 + int runPwrSts = message[base + (705 - 530)] & 0xFF; // 行车上电阶段 + int tChgCp = message[base + (706 - 530)] & 0xFF; // 慢充CP值 + int tChgR = message[base + (707 - 530)] & 0xFF; // 慢充枪阻值 + int tChgSts = message[base + (708 - 530)] & 0xFF; // 慢充阶段 + int fChgSts2 = message[base + (709 - 530)] & 0xFF; // 快充阶段 + int chgSts = message[base + (710 - 530)] & 0xFF; // 充电阶段 + int chgTime = ((message[base + (711 - 530)] & 0xFF) << 8) | (message[base + (712 - 530)] & 0xFF); // 充电时长(min) + long mileage = ((message[base + (713 - 530)] & 0xFFL) << 24) | ((message[base + (714 - 530)] & 0xFFL) << 16) | ((message[base + (715 - 530)] & 0xFFL) << 8) | (message[base + (716 - 530)] & 0xFFL); // 里程(u32) + log.info("设备 {} 扩展数据: resetCount={}, insulationValKOhm={}, carSpeedKmH={}, GPV0_1V={}, RTPs(V)=[{},{},{},{},{},{},{}], RTNs=[{},{},{},{}], realSOCMax0_1={}, realSOCMin0_1={}, chargeSeatTempsC=[{},{},{},{},{},{},{},{}]", deviceSn, resetCount, insulationVal, carSpd, gpv, rtp1, rtp2, rtp3, rtp4, rtp5, rtp6, rtp7, rtn1, rtn2, rtn3, rtn4, realSocMax, realSocMin, chgBs1Tmp, chgBs2Tmp, chgBs3Tmp, chgBs4Tmp, chgBs5Tmp, chgBs6Tmp, chgBs7Tmp, chgBs8Tmp); + log.info("设备 {} 充电详情: tChgCurA={}, tChgVolV={}, fChgCurA={}, fChgVolV={}, disSOP(A)=[{},{},{},{}], regSOP(A)=[{},{},{},{}], disSopTolA={}, regSopTolA={}", deviceSn, tChgCur, tChgVol, fChgCur, fChgVol, disSop10, disSop30, disSop60, disSopCont, regSop10, regSop30, regSop60, regSopCont, disSopTol, regSopTol); + log.info("设备 {} 版本与编码: hwVer={}, swVer={}, BMSCode='{}', VIN='{}', clientCode='{}', devId={}", deviceSn, hwVer, swVer, bmsCode, vin, clientCode, devId); + log.info("设备 {} 系统状态: sysVolV={}, sysCurA={}, cellCount={}, tempSensorCount={}, relayStatus={}, onaaccStatus={}, acStopCode={}, dcStopCode={}, cycleCount={}, samp25V={}, samp5V={}, chargeSopA={}, acChargeSopA={}", deviceSn, sysVol, sysCur, cellCount, tempSensorCount, relayStatus, onaaccStatus, acStopCode, dcStopCode, cycleCount, samp25v, samp5v, chargeSop, acChargeSop); + log.info("设备 {} 运行阶段: runSts={}, runPwrSts={}, tChgCp={}, tChgR={}, tChgSts={}, fChgSts={}, chgSts={}, chgTimeMin={}, mileage={}", deviceSn, runSts, runPwrSts, tChgCp, tChgR, tChgSts, fChgSts2, chgSts, chgTime, mileage); + } catch (Exception e) { + log.error("设备 {} 解析扩展数据时发生错误: {}", deviceSn, e.getMessage()); + } + } + + /** + * 读取 ASCII 字符串 + * @param startAbs BatteryData 绝对索引(例如 602 对应 BMS编码起始) + * @param len 字节长度 + * @param base 530 的映射起点(message 中的 startIndex) + */ + private String readAsciiRange(byte[] message, int startAbs, int len, int base) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < len; i++) { + int idx = base + (startAbs - 530) + i; + if (idx >= 0 && idx < message.length) { + int b = message[idx] & 0xFF; + if (b != 0) { + sb.append((char) b); + } + } + } + return sb.toString().trim(); + } /** * 根据设备唯一编号(deviceCode)查询系统设备表的SN码 diff --git a/src/main/java/com/evobms/project/bms/service/impl/BmsChargeDetailServiceImpl.java b/src/main/java/com/evobms/project/bms/service/impl/BmsChargeDetailServiceImpl.java new file mode 100644 index 0000000..2fb14d5 --- /dev/null +++ b/src/main/java/com/evobms/project/bms/service/impl/BmsChargeDetailServiceImpl.java @@ -0,0 +1,18 @@ +package com.evobms.project.bms.service.impl; + +import com.evobms.project.bms.domain.BmsChargeDetail; +import com.evobms.project.bms.mapper.BmsChargeDetailMapper; +import com.evobms.project.bms.service.IBmsChargeDetailService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class BmsChargeDetailServiceImpl implements IBmsChargeDetailService { + @Autowired + private BmsChargeDetailMapper mapper; + + @Override + public int insertBmsChargeDetail(BmsChargeDetail data) { + return mapper.insertBmsChargeDetail(data); + } +} diff --git a/src/main/java/com/evobms/project/bms/service/impl/BmsSopDataServiceImpl.java b/src/main/java/com/evobms/project/bms/service/impl/BmsSopDataServiceImpl.java new file mode 100644 index 0000000..778daf3 --- /dev/null +++ b/src/main/java/com/evobms/project/bms/service/impl/BmsSopDataServiceImpl.java @@ -0,0 +1,18 @@ +package com.evobms.project.bms.service.impl; + +import com.evobms.project.bms.domain.BmsSopData; +import com.evobms.project.bms.mapper.BmsSopDataMapper; +import com.evobms.project.bms.service.IBmsSopDataService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class BmsSopDataServiceImpl implements IBmsSopDataService { + @Autowired + private BmsSopDataMapper mapper; + + @Override + public int insertBmsSopData(BmsSopData data) { + return mapper.insertBmsSopData(data); + } +} diff --git a/src/main/java/com/evobms/project/bms/service/impl/BmsSystemStatusServiceImpl.java b/src/main/java/com/evobms/project/bms/service/impl/BmsSystemStatusServiceImpl.java new file mode 100644 index 0000000..37e9da2 --- /dev/null +++ b/src/main/java/com/evobms/project/bms/service/impl/BmsSystemStatusServiceImpl.java @@ -0,0 +1,18 @@ +package com.evobms.project.bms.service.impl; + +import com.evobms.project.bms.domain.BmsSystemStatus; +import com.evobms.project.bms.mapper.BmsSystemStatusMapper; +import com.evobms.project.bms.service.IBmsSystemStatusService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class BmsSystemStatusServiceImpl implements IBmsSystemStatusService { + @Autowired + private BmsSystemStatusMapper mapper; + + @Override + public int insertBmsSystemStatus(BmsSystemStatus data) { + return mapper.insertBmsSystemStatus(data); + } +} 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 a87144b..a9581d1 100644 --- a/src/main/java/com/evobms/project/iot/controller/IotAuthController.java +++ b/src/main/java/com/evobms/project/iot/controller/IotAuthController.java @@ -13,6 +13,7 @@ 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 lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; @@ -52,7 +53,9 @@ import java.util.Map; */ @RestController @Tag(name = "设备鉴权", description = "设备鉴权令牌接口") +@Api(tags = "IoT设备鉴权") @RequestMapping("/iot") +@Slf4j public class IotAuthController { private static final Logger log = LoggerFactory.getLogger(IotAuthController.class); @@ -96,11 +99,13 @@ public class IotAuthController { */ @PostMapping("/auth/token") @Operation(summary = "设备请求令牌", description = "通过SN码,设备号,版本信息生成TOKEN") + @ApiOperation("设备请求令牌") public Map requestToken(@RequestBody Map body) { String sn = safeTrim(body.get("sn")); String model = safeTrim(body.get("device")); String version = safeTrim(body.get("version")); - + log.info("设备请求:{}",body.toString()); + log.info("sn:{}, device:{}, version:{}", sn, model, version); MDC.put("sn", sn); MDC.put("model", model); MDC.put("version", version); @@ -388,6 +393,7 @@ public class IotAuthController { */ @GetMapping("/ota/{num}") @Operation(summary = "OTA固件分片下载", description = " OTA 固件分片下载接口") + @ApiOperation("OTA固件分片下载") public Object downloadOtaChunk(@PathVariable("num") String num, @RequestParam(value = "version", required = false) String version, HttpServletRequest request) { diff --git a/src/main/java/com/evobms/project/iot/controller/IotOtaController.java b/src/main/java/com/evobms/project/iot/controller/IotOtaController.java index fe980a1..a73c49f 100644 --- a/src/main/java/com/evobms/project/iot/controller/IotOtaController.java +++ b/src/main/java/com/evobms/project/iot/controller/IotOtaController.java @@ -3,6 +3,8 @@ package com.evobms.project.iot.controller; import com.evobms.common.constant.BboxApiConstants; import com.evobms.common.utils.StringUtils; import com.evobms.project.iot.service.DeviceTokenService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; @@ -25,6 +27,7 @@ import java.util.Map; */ @RestController @RequestMapping("/iot/ota") +@Api(tags = "IoT OTA状态上报") public class IotOtaController { private static final Logger log = LoggerFactory.getLogger(IotOtaController.class); @@ -32,6 +35,7 @@ public class IotOtaController { private DeviceTokenService deviceTokenService; @PostMapping("/status") + @ApiOperation("上报OTA升级状态") public Map reportOtaStatus(@RequestBody Map body, HttpServletRequest request) { Map resp = new HashMap<>(); diff --git a/src/main/java/com/evobms/project/ota/controller/OtaTasksController.java b/src/main/java/com/evobms/project/ota/controller/OtaTasksController.java index cbb5f3c..fbe4e13 100644 --- a/src/main/java/com/evobms/project/ota/controller/OtaTasksController.java +++ b/src/main/java/com/evobms/project/ota/controller/OtaTasksController.java @@ -20,6 +20,8 @@ import com.evobms.framework.web.controller.BaseController; import com.evobms.framework.web.domain.AjaxResult; import com.evobms.common.utils.poi.ExcelUtil; import com.evobms.framework.web.page.TableDataInfo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; /** * OTA任务Controller @@ -29,6 +31,7 @@ import com.evobms.framework.web.page.TableDataInfo; */ @RestController @RequestMapping("/ota/tasks") +@Api(tags = "OTA任务管理") public class OtaTasksController extends BaseController { @Autowired @@ -39,6 +42,7 @@ public class OtaTasksController extends BaseController */ //@PreAuthorize("@ss.hasPermi('OTA:tasks:list')") @GetMapping("/list") + @ApiOperation("查询OTA任务列表") public TableDataInfo list(OtaTasks otaTasks) { startPage(); @@ -52,6 +56,7 @@ public class OtaTasksController extends BaseController //@PreAuthorize("@ss.hasPermi('OTA:tasks:export')") @Log(title = "OTA任务", businessType = BusinessType.EXPORT) @PostMapping("/export") + @ApiOperation("导出OTA任务列表") public void export(HttpServletResponse response, OtaTasks otaTasks) { List list = otaTasksService.selectOtaTasksList(otaTasks); @@ -64,6 +69,7 @@ public class OtaTasksController extends BaseController */ //@PreAuthorize("@ss.hasPermi('OTA:tasks:query')") @GetMapping(value = "/{id}") + @ApiOperation("获取OTA任务详细信息") public AjaxResult getInfo(@PathVariable("id") String id) { return success(otaTasksService.selectOtaTasksById(id)); @@ -75,6 +81,7 @@ public class OtaTasksController extends BaseController //@PreAuthorize("@ss.hasPermi('OTA:tasks:add')") @Log(title = "OTA任务", businessType = BusinessType.INSERT) @PostMapping + @ApiOperation("新增OTA任务") public AjaxResult add(@RequestBody OtaTasks otaTasks) { return toAjax(otaTasksService.insertOtaTasks(otaTasks)); @@ -86,6 +93,7 @@ public class OtaTasksController extends BaseController //@PreAuthorize("@ss.hasPermi('OTA:tasks:edit')") @Log(title = "OTA任务", businessType = BusinessType.UPDATE) @PutMapping + @ApiOperation("修改OTA任务") public AjaxResult edit(@RequestBody OtaTasks otaTasks) { return toAjax(otaTasksService.updateOtaTasks(otaTasks)); @@ -96,6 +104,7 @@ public class OtaTasksController extends BaseController */ @Log(title = "OTA任务", businessType = BusinessType.DELETE) @DeleteMapping("/{ids}") + @ApiOperation("删除OTA任务") public AjaxResult remove(@PathVariable String[] ids) { return toAjax(otaTasksService.deleteOtaTasksByIds(ids)); diff --git a/src/main/java/com/evobms/project/ota/domain/OtaTasks.java b/src/main/java/com/evobms/project/ota/domain/OtaTasks.java index f6c8310..fc59acc 100644 --- a/src/main/java/com/evobms/project/ota/domain/OtaTasks.java +++ b/src/main/java/com/evobms/project/ota/domain/OtaTasks.java @@ -1,7 +1,11 @@ package com.evobms.project.ota.domain; import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import com.evobms.framework.aspectj.lang.annotation.Excel; @@ -9,157 +13,62 @@ import com.evobms.framework.web.domain.BaseEntity; /** * OTA任务对象 ota_tasks - * + * * @author ruoyi * @date 2025-10-14 */ +@EqualsAndHashCode(callSuper = true) +@ApiModel(description = "OTA任务对象") +@Data public class OtaTasks extends BaseEntity { private static final long serialVersionUID = 1L; /** 任务ID(UUID) */ + @ApiModelProperty(value = "任务ID(UUID)") private String id; /** 设备ID */ + @ApiModelProperty(value = "设备ID") @Excel(name = "设备ID") private String deviceId; /** 任务名称 */ + @ApiModelProperty(value = "任务名称") @Excel(name = "任务名称") private String taskName; /** 目标固件版本 */ + @ApiModelProperty(value = "目标固件版本") @Excel(name = "目标固件版本") private String firmwareVersion; /** 任务状态 */ + @ApiModelProperty(value = "任务状态") @Excel(name = "任务状态") private String status; /** 升级进度(0-100) */ + @ApiModelProperty(value = "升级进度(0-100)") @Excel(name = "升级进度(0-100)") private Long progress; /** 开始时间 */ + @ApiModelProperty(value = "开始时间") @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd") private Date startTime; /** 结束时间 */ + @ApiModelProperty(value = "结束时间") @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd") private Date endTime; /** 错误信息 */ + @ApiModelProperty(value = "错误信息") @Excel(name = "错误信息") private String errorMessage; - public void setId(String id) - { - this.id = id; - } - public String getId() - { - return id; - } - - public void setDeviceId(String deviceId) - { - this.deviceId = deviceId; - } - - public String getDeviceId() - { - return deviceId; - } - - public void setTaskName(String taskName) - { - this.taskName = taskName; - } - - public String getTaskName() - { - return taskName; - } - - public void setFirmwareVersion(String firmwareVersion) - { - this.firmwareVersion = firmwareVersion; - } - - public String getFirmwareVersion() - { - return firmwareVersion; - } - - public void setStatus(String status) - { - this.status = status; - } - - public String getStatus() - { - return status; - } - - public void setProgress(Long progress) - { - this.progress = progress; - } - - public Long getProgress() - { - return progress; - } - - public void setStartTime(Date startTime) - { - this.startTime = startTime; - } - - public Date getStartTime() - { - return startTime; - } - - public void setEndTime(Date endTime) - { - this.endTime = endTime; - } - - public Date getEndTime() - { - return endTime; - } - - public void setErrorMessage(String errorMessage) - { - this.errorMessage = errorMessage; - } - - public String getErrorMessage() - { - return errorMessage; - } - - @Override - public String toString() { - return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) - .append("id", getId()) - .append("deviceId", getDeviceId()) - .append("taskName", getTaskName()) - .append("firmwareVersion", getFirmwareVersion()) - .append("status", getStatus()) - .append("progress", getProgress()) - .append("startTime", getStartTime()) - .append("endTime", getEndTime()) - .append("errorMessage", getErrorMessage()) - .append("createTime", getCreateTime()) - .append("updateTime", getUpdateTime()) - .append("updateBy", getUpdateBy()) - .append("createBy", getCreateBy()) - .toString(); - } } diff --git a/src/main/java/com/evobms/project/summary/controller/ChargeDischargeSummaryController.java b/src/main/java/com/evobms/project/summary/controller/ChargeDischargeSummaryController.java index db34d65..2632de4 100644 --- a/src/main/java/com/evobms/project/summary/controller/ChargeDischargeSummaryController.java +++ b/src/main/java/com/evobms/project/summary/controller/ChargeDischargeSummaryController.java @@ -20,6 +20,8 @@ import com.evobms.framework.web.controller.BaseController; import com.evobms.framework.web.domain.AjaxResult; import com.evobms.common.utils.poi.ExcelUtil; import com.evobms.framework.web.page.TableDataInfo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; /** * 累计充放电量Controller @@ -29,6 +31,7 @@ import com.evobms.framework.web.page.TableDataInfo; */ @RestController @RequestMapping("/summary/summary") +@Api(tags = "充放电统计") public class ChargeDischargeSummaryController extends BaseController { @Autowired @@ -39,6 +42,7 @@ public class ChargeDischargeSummaryController extends BaseController */ @PreAuthorize("@ss.hasPermi('summary:summary:list')") @GetMapping("/list") + @ApiOperation("查询累计充放电量列表") public TableDataInfo list(ChargeDischargeSummary chargeDischargeSummary) { startPage(); @@ -52,6 +56,7 @@ public class ChargeDischargeSummaryController extends BaseController @PreAuthorize("@ss.hasPermi('summary:summary:export')") @Log(title = "累计充放电量", businessType = BusinessType.EXPORT) @PostMapping("/export") + @ApiOperation("导出累计充放电量列表") public void export(HttpServletResponse response, ChargeDischargeSummary chargeDischargeSummary) { List list = chargeDischargeSummaryService.selectChargeDischargeSummaryList(chargeDischargeSummary); @@ -64,6 +69,7 @@ public class ChargeDischargeSummaryController extends BaseController */ @PreAuthorize("@ss.hasPermi('summary:summary:query')") @GetMapping(value = "/{id}") + @ApiOperation("获取累计充放电量详细信息") public AjaxResult getInfo(@PathVariable("id") Long id) { return success(chargeDischargeSummaryService.selectChargeDischargeSummaryById(id)); @@ -75,6 +81,7 @@ public class ChargeDischargeSummaryController extends BaseController @PreAuthorize("@ss.hasPermi('summary:summary:add')") @Log(title = "累计充放电量", businessType = BusinessType.INSERT) @PostMapping + @ApiOperation("新增累计充放电量") public AjaxResult add(@RequestBody ChargeDischargeSummary chargeDischargeSummary) { return toAjax(chargeDischargeSummaryService.insertChargeDischargeSummary(chargeDischargeSummary)); @@ -86,6 +93,7 @@ public class ChargeDischargeSummaryController extends BaseController @PreAuthorize("@ss.hasPermi('summary:summary:edit')") @Log(title = "累计充放电量", businessType = BusinessType.UPDATE) @PutMapping + @ApiOperation("修改累计充放电量") public AjaxResult edit(@RequestBody ChargeDischargeSummary chargeDischargeSummary) { return toAjax(chargeDischargeSummaryService.updateChargeDischargeSummary(chargeDischargeSummary)); @@ -96,7 +104,8 @@ public class ChargeDischargeSummaryController extends BaseController */ @PreAuthorize("@ss.hasPermi('summary:summary:remove')") @Log(title = "累计充放电量", businessType = BusinessType.DELETE) - @DeleteMapping("/{ids}") + @DeleteMapping("/{ids}") + @ApiOperation("删除累计充放电量") public AjaxResult remove(@PathVariable Long[] ids) { return toAjax(chargeDischargeSummaryService.deleteChargeDischargeSummaryByIds(ids)); diff --git a/src/main/java/com/evobms/project/summary/domain/ChargeDischargeSummary.java b/src/main/java/com/evobms/project/summary/domain/ChargeDischargeSummary.java index 0ff9230..658ac62 100644 --- a/src/main/java/com/evobms/project/summary/domain/ChargeDischargeSummary.java +++ b/src/main/java/com/evobms/project/summary/domain/ChargeDischargeSummary.java @@ -3,6 +3,10 @@ package com.evobms.project.summary.domain; import java.math.BigDecimal; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import com.evobms.framework.aspectj.lang.annotation.Excel; @@ -14,6 +18,9 @@ import com.evobms.framework.web.domain.BaseEntity; * @author 田志阳 * @date 2026-01-09 */ +@Data +@EqualsAndHashCode(callSuper = true) +@ApiModel(value = "ChargeDischargeSummary", description = "累计充放电量对象") public class ChargeDischargeSummary extends BaseEntity { private static final long serialVersionUID = 1L; @@ -23,83 +30,23 @@ public class ChargeDischargeSummary extends BaseEntity /** 设备ID */ @Excel(name = "设备ID") + @ApiModelProperty(value = "设备ID") private String deviceId; /** 时间戳 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss ") + @ApiModelProperty(value = "时间戳") @Excel(name = "时间戳", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") private Date timestamp; /** 累计放电(kWh) */ + @ApiModelProperty(value = "累计放电(kWh)") @Excel(name = "累计放电(kWh)") private BigDecimal dischargeKwh; /** 累计充电kWh) */ - @Excel(name = "累计充电kWh)") + @ApiModelProperty(value = "累计充电kWh") + @Excel(name = "累计充电(kWh)") private BigDecimal chargeKwh; - 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 setDischargeKwh(BigDecimal dischargeKwh) - { - this.dischargeKwh = dischargeKwh; - } - - public BigDecimal getDischargeKwh() - { - return dischargeKwh; - } - - public void setChargeKwh(BigDecimal chargeKwh) - { - this.chargeKwh = chargeKwh; - } - - public BigDecimal getChargeKwh() - { - return chargeKwh; - } - - @Override - public String toString() { - return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) - .append("id", getId()) - .append("deviceId", getDeviceId()) - .append("timestamp", getTimestamp()) - .append("dischargeKwh", getDischargeKwh()) - .append("chargeKwh", getChargeKwh()) - .append("createTime", getCreateTime()) - .append("updateTime", getUpdateTime()) - .append("createBy", getCreateBy()) - .append("updateBy", getUpdateBy()) - .toString(); - } } diff --git a/src/main/java/com/evobms/project/system/controller/BmsDevicesController.java b/src/main/java/com/evobms/project/system/controller/BmsDevicesController.java index a2dd460..fb194b8 100644 --- a/src/main/java/com/evobms/project/system/controller/BmsDevicesController.java +++ b/src/main/java/com/evobms/project/system/controller/BmsDevicesController.java @@ -20,15 +20,18 @@ import com.evobms.framework.web.controller.BaseController; import com.evobms.framework.web.domain.AjaxResult; import com.evobms.common.utils.poi.ExcelUtil; import com.evobms.framework.web.page.TableDataInfo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; /** * BBOX管理Controller * * @author 田志阳 - * @date 2025-10-10 + * @date 2025-11-15 */ @RestController @RequestMapping("/devices/devices") +@Api(tags = "BBOX设备管理") public class BmsDevicesController extends BaseController { @Autowired @@ -37,7 +40,9 @@ public class BmsDevicesController extends BaseController /** * 查询BBOX管理列表 */ + @PreAuthorize("@ss.hasPermi('system:devices:list')") @GetMapping("/list") + @ApiOperation("查询BBOX设备列表") public TableDataInfo list(BmsDevices bmsDevices) { startPage(); @@ -48,8 +53,10 @@ public class BmsDevicesController extends BaseController /** * 导出BBOX管理列表 */ + @PreAuthorize("@ss.hasPermi('system:devices:export')") @Log(title = "BBOX管理", businessType = BusinessType.EXPORT) @PostMapping("/export") + @ApiOperation("导出BBOX设备列表") public void export(HttpServletResponse response, BmsDevices bmsDevices) { List list = bmsDevicesService.selectBmsDevicesList(bmsDevices); @@ -60,7 +67,9 @@ public class BmsDevicesController extends BaseController /** * 获取BBOX管理详细信息 */ + @PreAuthorize("@ss.hasPermi('system:devices:query')") @GetMapping(value = "/{id}") + @ApiOperation("获取BBOX设备详细信息") public AjaxResult getInfo(@PathVariable("id") String id) { return success(bmsDevicesService.selectBmsDevicesById(id)); @@ -69,8 +78,10 @@ public class BmsDevicesController extends BaseController /** * 新增BBOX管理 */ + @PreAuthorize("@ss.hasPermi('system:devices:add')") @Log(title = "BBOX管理", businessType = BusinessType.INSERT) @PostMapping + @ApiOperation("新增BBOX设备") public AjaxResult add(@RequestBody BmsDevices bmsDevices) { return toAjax(bmsDevicesService.insertBmsDevices(bmsDevices)); @@ -79,8 +90,10 @@ public class BmsDevicesController extends BaseController /** * 修改BBOX管理 */ + @PreAuthorize("@ss.hasPermi('system:devices:edit')") @Log(title = "BBOX管理", businessType = BusinessType.UPDATE) @PutMapping + @ApiOperation("修改BBOX设备") public AjaxResult edit(@RequestBody BmsDevices bmsDevices) { return toAjax(bmsDevicesService.updateBmsDevices(bmsDevices)); @@ -89,8 +102,10 @@ public class BmsDevicesController extends BaseController /** * 删除BBOX管理 */ + @PreAuthorize("@ss.hasPermi('system:devices:remove')") @Log(title = "BBOX管理", businessType = BusinessType.DELETE) - @DeleteMapping("/{ids}") + @DeleteMapping("/{ids}") + @ApiOperation("删除BBOX设备") public AjaxResult remove(@PathVariable String[] ids) { return toAjax(bmsDevicesService.deleteBmsDevicesByIds(ids)); 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 bc220ff..3c3acf8 100644 --- a/src/main/java/com/evobms/project/system/domain/BmsDevices.java +++ b/src/main/java/com/evobms/project/system/domain/BmsDevices.java @@ -2,6 +2,8 @@ package com.evobms.project.system.domain; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.lang3.builder.ToStringBuilder; @@ -17,41 +19,51 @@ import com.evobms.framework.web.domain.BaseEntity; */ @EqualsAndHashCode(callSuper = true) @Data +@ApiModel(value = "BmsDevices", description = "BBOX设备管理对象") public class BmsDevices extends BaseEntity { private static final long serialVersionUID = 1L; /** 主键ID */ + @ApiModelProperty("主键ID") private String id; /** 设备唯一编号 */ + @ApiModelProperty("设备唯一编号") @Excel(name = "设备唯一编号") private String deviceId; /** 设备名称 */ + @ApiModelProperty("设备名称") @Excel(name = "设备名称") private String deviceName; /** 设备名称 */ + @ApiModelProperty("设备SN码") @Excel(name = "设备SN码") private String deviceSn; /** 设备类型 */ + @ApiModelProperty("设备类型") @Excel(name = "设备类型") private String deviceType; /** 设备状态 */ + @ApiModelProperty("设备状态") @Excel(name = "设备状态") private String status; /** 设备IP地址 */ + @ApiModelProperty("设备IP地址") @Excel(name = "设备IP地址") private String ipAddress; /** 服务器固件版本号 */ + @ApiModelProperty("固件版本号") @Excel(name = "固件版本号") private String firmwareVersion; /** 最后在线时间 */ + @ApiModelProperty("最后在线时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Excel(name = "最后在线时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") private Date lastOnline; 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 06efb22..f6b36e2 100644 --- a/src/main/java/com/evobms/project/vehicledata/controller/BatteryChartController.java +++ b/src/main/java/com/evobms/project/vehicledata/controller/BatteryChartController.java @@ -29,6 +29,7 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; /** * 图标组件Controller * @@ -57,7 +58,9 @@ 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) { + public List getChartData( + @ApiParam(value = "设备ID", required = true) @PathVariable("deviceId") String deviceId, + @ApiParam(value = "最近多少小时的数据", defaultValue = "24") @RequestParam(value = "hours", required = false, defaultValue = "24") int hours) { long millis = System.currentTimeMillis() - (long) hours * 3600_000L; Date startTime = new Date(millis); List rows = vehicleDataService.selectByDeviceAndStartTime(deviceId, startTime); @@ -72,21 +75,25 @@ public class BatteryChartController { // 整车最新:返回 deviceId 最新的一条整车数据 @GetMapping("/vehicle-data/{deviceId}/latest") @ApiOperation(value = "整车最新数据", notes = "返回指定设备最新整车数据") - public VehicleData latestVehicleData(@PathVariable("deviceId") String deviceId) { + public VehicleData latestVehicleData(@ApiParam(value = "设备ID", required = true) @PathVariable("deviceId") String deviceId) { return vehicleDataService.selectLatestByDeviceId(deviceId); } // 位置最新:返回 deviceId 最新的一条位置数据 @GetMapping("/vehicle-location/{deviceId}/latest") @ApiOperation(value = "车辆最新位置", notes = "返回指定设备最新位置数据") - public VehicleLocation latestVehicleLocation(@PathVariable("deviceId") String deviceId) { + public VehicleLocation latestVehicleLocation(@ApiParam(value = "设备ID", required = true) @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, @RequestParam(value = "limit", required = false) Integer limit) { + public List locationRange( + @ApiParam(value = "设备ID", required = true) @PathVariable("deviceId") String deviceId, + @ApiParam(value = "开始时间戳(毫秒)", required = true) @RequestParam("start") long startMillis, + @ApiParam(value = "结束时间戳(毫秒)", required = true) @RequestParam("end") long endMillis, + @ApiParam(value = "限制返回条数") @RequestParam(value = "limit", required = false) Integer limit) { Date start = new Date(startMillis); Date end = new Date(endMillis); return vehicleLocationService.selectByDeviceAndRange(deviceId, start, end, limit); @@ -95,21 +102,26 @@ public class BatteryChartController { // 子系统最新帧(电压):返回指定子系统号最新的一帧电压数据 @GetMapping("/subsystem-voltage/{deviceId}/{subsystemNo}/latest") @ApiOperation(value = "子系统最新电压帧", notes = "返回指定子系统最新电压数据") - public SubsystemVoltage latestVoltage(@PathVariable("deviceId") String deviceId, @PathVariable("subsystemNo") Integer subsystemNo) { + public SubsystemVoltage latestVoltage( + @ApiParam(value = "设备ID", required = true) @PathVariable("deviceId") String deviceId, + @ApiParam(value = "子系统号", required = true) @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) { + public SubsystemTemperature latestTemperature( + @ApiParam(value = "设备ID", required = true) @PathVariable("deviceId") String deviceId, + @ApiParam(value = "子系统号", required = true) @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) { + public ExtremeValues latestExtremeValues( + @ApiParam(value = "设备ID", required = true) @PathVariable("deviceId") String deviceId, + @ApiParam(value = "筛选指定时间之前的数据(yyyy-MM-dd HH:mm:ss 或 毫秒时间戳)") @RequestParam(value = "before", required = false) String before) { if (before == null || before.isEmpty()) { return extremeValuesService.selectLatestByDeviceId(deviceId); } @@ -126,7 +138,7 @@ public class BatteryChartController { return extremeValuesService.selectLatestByDeviceIdBefore(deviceId, beforeTime); } @GetMapping("/api/dashboard/home") - @ApiOperation(value = "首页所有分布数据", notes = "返回指定设备极值数据,支持before筛选") + @ApiOperation(value = "首页所有分布数据", notes = "获取首页大屏的分布统计数据") public R home(){ HomeDashboardDTO dto = vehicleDataService.getHomeDashboard(); return R.ok(dto); diff --git a/src/main/java/com/evobms/project/vehicledata/controller/VehicleDataController.java b/src/main/java/com/evobms/project/vehicledata/controller/VehicleDataController.java index c66f55d..ac08f46 100644 --- a/src/main/java/com/evobms/project/vehicledata/controller/VehicleDataController.java +++ b/src/main/java/com/evobms/project/vehicledata/controller/VehicleDataController.java @@ -20,6 +20,8 @@ import com.evobms.framework.web.controller.BaseController; import com.evobms.framework.web.domain.AjaxResult; import com.evobms.common.utils.poi.ExcelUtil; import com.evobms.framework.web.page.TableDataInfo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; /** * 整车数据Controller @@ -29,6 +31,7 @@ import com.evobms.framework.web.page.TableDataInfo; */ @RestController @RequestMapping("/VehicleData/VehicleData") +@Api(tags = "整车数据管理") public class VehicleDataController extends BaseController { @Autowired @@ -39,6 +42,7 @@ public class VehicleDataController extends BaseController */ @PreAuthorize("@ss.hasPermi('VehicleData:VehicleData:list')") @GetMapping("/list") + @ApiOperation("查询整车数据列表") public TableDataInfo list(VehicleData vehicleData) { startPage(); @@ -52,6 +56,7 @@ public class VehicleDataController extends BaseController @PreAuthorize("@ss.hasPermi('VehicleData:VehicleData:export')") @Log(title = "整车数据", businessType = BusinessType.EXPORT) @PostMapping("/export") + @ApiOperation("导出整车数据列表") public void export(HttpServletResponse response, VehicleData vehicleData) { List list = vehicleDataService.selectVehicleDataList(vehicleData); @@ -64,6 +69,7 @@ public class VehicleDataController extends BaseController */ @PreAuthorize("@ss.hasPermi('VehicleData:VehicleData:query')") @GetMapping(value = "/{id}") + @ApiOperation("获取整车数据详细信息") public AjaxResult getInfo(@PathVariable("id") Long id) { return success(vehicleDataService.selectVehicleDataById(id)); @@ -75,6 +81,7 @@ public class VehicleDataController extends BaseController @PreAuthorize("@ss.hasPermi('VehicleData:VehicleData:add')") @Log(title = "整车数据", businessType = BusinessType.INSERT) @PostMapping + @ApiOperation("新增整车数据") public AjaxResult add(@RequestBody VehicleData vehicleData) { return toAjax(vehicleDataService.insertVehicleData(vehicleData)); @@ -86,6 +93,7 @@ public class VehicleDataController extends BaseController @PreAuthorize("@ss.hasPermi('VehicleData:VehicleData:edit')") @Log(title = "整车数据", businessType = BusinessType.UPDATE) @PutMapping + @ApiOperation("修改整车数据") public AjaxResult edit(@RequestBody VehicleData vehicleData) { return toAjax(vehicleDataService.updateVehicleData(vehicleData)); @@ -96,7 +104,8 @@ public class VehicleDataController extends BaseController */ @PreAuthorize("@ss.hasPermi('VehicleData:VehicleData:remove')") @Log(title = "整车数据", businessType = BusinessType.DELETE) - @DeleteMapping("/{ids}") + @DeleteMapping("/{ids}") + @ApiOperation("删除整车数据") public AjaxResult remove(@PathVariable Long[] ids) { return toAjax(vehicleDataService.deleteVehicleDataByIds(ids)); diff --git a/src/main/java/com/evobms/project/vehicledata/controller/VehicleLocationController.java b/src/main/java/com/evobms/project/vehicledata/controller/VehicleLocationController.java index b211ff2..fbbdbcb 100644 --- a/src/main/java/com/evobms/project/vehicledata/controller/VehicleLocationController.java +++ b/src/main/java/com/evobms/project/vehicledata/controller/VehicleLocationController.java @@ -20,6 +20,8 @@ import com.evobms.framework.web.controller.BaseController; import com.evobms.framework.web.domain.AjaxResult; import com.evobms.common.utils.poi.ExcelUtil; import com.evobms.framework.web.page.TableDataInfo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; /** * 车辆位置数据Controller @@ -29,6 +31,7 @@ import com.evobms.framework.web.page.TableDataInfo; */ @RestController @RequestMapping("/location/location") +@Api(tags = "车辆位置管理") public class VehicleLocationController extends BaseController { @Autowired @@ -39,6 +42,7 @@ public class VehicleLocationController extends BaseController */ @PreAuthorize("@ss.hasPermi('location:location:list')") @GetMapping("/list") + @ApiOperation("查询车辆位置列表") public TableDataInfo list(VehicleLocation vehicleLocation) { startPage(); @@ -52,6 +56,7 @@ public class VehicleLocationController extends BaseController @PreAuthorize("@ss.hasPermi('location:location:export')") @Log(title = "车辆位置数据", businessType = BusinessType.EXPORT) @PostMapping("/export") + @ApiOperation("导出车辆位置列表") public void export(HttpServletResponse response, VehicleLocation vehicleLocation) { List list = vehicleLocationService.selectVehicleLocationList(vehicleLocation); @@ -64,6 +69,7 @@ public class VehicleLocationController extends BaseController */ @PreAuthorize("@ss.hasPermi('location:location:query')") @GetMapping(value = "/{id}") + @ApiOperation("获取车辆位置详细信息") public AjaxResult getInfo(@PathVariable("id") Long id) { return success(vehicleLocationService.selectVehicleLocationById(id)); @@ -75,6 +81,7 @@ public class VehicleLocationController extends BaseController @PreAuthorize("@ss.hasPermi('location:location:add')") @Log(title = "车辆位置数据", businessType = BusinessType.INSERT) @PostMapping + @ApiOperation("新增车辆位置") public AjaxResult add(@RequestBody VehicleLocation vehicleLocation) { return toAjax(vehicleLocationService.insertVehicleLocation(vehicleLocation)); @@ -86,6 +93,7 @@ public class VehicleLocationController extends BaseController @PreAuthorize("@ss.hasPermi('location:location:edit')") @Log(title = "车辆位置数据", businessType = BusinessType.UPDATE) @PutMapping + @ApiOperation("修改车辆位置") public AjaxResult edit(@RequestBody VehicleLocation vehicleLocation) { return toAjax(vehicleLocationService.updateVehicleLocation(vehicleLocation)); @@ -96,7 +104,8 @@ public class VehicleLocationController extends BaseController */ @PreAuthorize("@ss.hasPermi('location:location:remove')") @Log(title = "车辆位置数据", businessType = BusinessType.DELETE) - @DeleteMapping("/{ids}") + @DeleteMapping("/{ids}") + @ApiOperation("删除车辆位置") public AjaxResult remove(@PathVariable Long[] ids) { return toAjax(vehicleLocationService.deleteVehicleLocationByIds(ids)); diff --git a/src/main/java/com/evobms/project/vehicledata/domain/HomeDashboardDTO.java b/src/main/java/com/evobms/project/vehicledata/domain/HomeDashboardDTO.java index d28cbf5..e3962a2 100644 --- a/src/main/java/com/evobms/project/vehicledata/domain/HomeDashboardDTO.java +++ b/src/main/java/com/evobms/project/vehicledata/domain/HomeDashboardDTO.java @@ -1,18 +1,28 @@ package com.evobms.project.vehicledata.domain; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.Map; @Data +@ApiModel(description = "首页仪表盘数据传输对象") public class HomeDashboardDTO { + @ApiModelProperty(value = "设备总数") private Long deviceCount; // 设备总数 + @ApiModelProperty(value = "在线设备数") private Integer onlineCount; // 在线设备数 + @ApiModelProperty(value = "平均 SOC") private Double avgSoc; // 平均 SOC + @ApiModelProperty(value = "当前最高温度") private Double maxTemp; // 当前最高温度 + @ApiModelProperty(value = "最大单体压差") private Double maxVoltageDiff; // 最大单体压差 + @ApiModelProperty(value = "未恢复告警数") private Integer alarmCount; // 未恢复告警数 - + @ApiModelProperty(value = "SOC 分布") private Map socDistribution; // SOC 分布 + @ApiModelProperty(value = "温度分布") private Map tempDistribution; // 温度分布 } 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 3fcba36..eda5c3f 100644 --- a/src/main/java/com/evobms/project/vehicledata/domain/VehicleData.java +++ b/src/main/java/com/evobms/project/vehicledata/domain/VehicleData.java @@ -2,7 +2,11 @@ package com.evobms.project.vehicledata.domain; import java.math.BigDecimal; import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import com.evobms.framework.aspectj.lang.annotation.Excel; @@ -14,240 +18,87 @@ import com.evobms.framework.web.domain.BaseEntity; * @author 田志阳 * @date 2025-11-15 */ +@ApiModel(description = "整车数据对象") +@Data +@EqualsAndHashCode(callSuper = true) public class VehicleData extends BaseEntity { private static final long serialVersionUID = 1L; /** 主键ID */ + @ApiModelProperty(value = "主键ID") private Long id; /** 设备ID */ + @ApiModelProperty(value = "设备ID") @Excel(name = "设备ID") private String deviceId; /** 数据时间戳 */ + @ApiModelProperty(value = "数据时间戳") @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:无效) */ + @ApiModelProperty(value = "车辆状态 (1:启动 2:熄火 3:其他 254:异常 255:无效)") @Excel(name = "车辆状态 (1:启动 2:熄火 3:其他 254:异常 255:无效)") private Integer vehicleStatus; /** 充电状态 (1:停车充电 2:行驶充电 3:未充电 4:充电完成 254:异常 255:无效) */ + @ApiModelProperty(value = "充电状态 (1:停车充电 2:行驶充电 3:未充电 4:充电完成 254:异常 255:无效)") @Excel(name = "充电状态 (1:停车充电 2:行驶充电 3:未充电 4:充电完成 254:异常 255:无效)") private Integer chargingStatus; /** 运行模式 (1:纯电 2:混动 3:燃油 254:异常 255:无效) */ + @ApiModelProperty(value = "运行模式 (1:纯电 2:混动 3:燃油 254:异常 255:无效)") @Excel(name = "运行模式 (1:纯电 2:混动 3:燃油 254:异常 255:无效)") private Integer operationMode; /** 车速(km/h) */ + @ApiModelProperty(value = "车速(km/h)") @Excel(name = "车速(km/h)") private BigDecimal vehicleSpeed; /** 累计里程(km) */ + @ApiModelProperty(value = "累计里程(km)") @Excel(name = "累计里程(km)") private BigDecimal totalMileage; /** 总电压(V) */ + @ApiModelProperty(value = "总电压(V)") @Excel(name = "总电压(V)") private BigDecimal totalVoltage; /** 总电流(A) */ + @ApiModelProperty(value = "总电流(A)") @Excel(name = "总电流(A)") private BigDecimal totalCurrent; /** SOC电量百分比(%) */ + @ApiModelProperty(value = "SOC电量百分比(%)") @Excel(name = "SOC电量百分比(%)") private Integer soc; /** DC-DC状态 (1:工作 2:断开) */ + @ApiModelProperty(value = "DC-DC状态 (1:工作 2:断开)") @Excel(name = "DC-DC状态 (1:工作 2:断开)") private Integer dcdcStatus; /** 档位 (0:空档 1-6:1-6档 13:倒档 14:自动D档 15:停车P档) */ + @ApiModelProperty(value = "档位 (0:空档 1-6:1-6档 13:倒档 14:自动D档 15:停车P档)") @Excel(name = "档位 (0:空档 1-6:1-6档 13:倒档 14:自动D档 15:停车P档)") private Integer gearPosition; /** 绝缘电阻(kΩ) */ + @ApiModelProperty(value = "绝缘电阻(kΩ)") @Excel(name = "绝缘电阻(kΩ)") private Integer insulationResistance; /** 预留字段 */ + @ApiModelProperty(value = "预留字段") @Excel(name = "预留字段") private String reservedData; - 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 setVehicleStatus(Integer vehicleStatus) - { - this.vehicleStatus = vehicleStatus; - } - - public Integer getVehicleStatus() - { - return vehicleStatus; - } - - public void setChargingStatus(Integer chargingStatus) - { - this.chargingStatus = chargingStatus; - } - - public Integer getChargingStatus() - { - return chargingStatus; - } - - public void setOperationMode(Integer operationMode) - { - this.operationMode = operationMode; - } - - public Integer getOperationMode() - { - return operationMode; - } - - public void setVehicleSpeed(BigDecimal vehicleSpeed) - { - this.vehicleSpeed = vehicleSpeed; - } - - public BigDecimal getVehicleSpeed() - { - return vehicleSpeed; - } - - public void setTotalMileage(BigDecimal totalMileage) - { - this.totalMileage = totalMileage; - } - - public BigDecimal getTotalMileage() - { - return totalMileage; - } - - public void setTotalVoltage(BigDecimal totalVoltage) - { - this.totalVoltage = totalVoltage; - } - - public BigDecimal getTotalVoltage() - { - return totalVoltage; - } - - public void setTotalCurrent(BigDecimal totalCurrent) - { - this.totalCurrent = totalCurrent; - } - - public BigDecimal getTotalCurrent() - { - return totalCurrent; - } - - public void setSoc(Integer soc) - { - this.soc = soc; - } - - public Integer getSoc() - { - return soc; - } - - public void setDcdcStatus(Integer dcdcStatus) - { - this.dcdcStatus = dcdcStatus; - } - - public Integer getDcdcStatus() - { - return dcdcStatus; - } - - public void setGearPosition(Integer gearPosition) - { - this.gearPosition = gearPosition; - } - - public Integer getGearPosition() - { - return gearPosition; - } - - public void setInsulationResistance(Integer insulationResistance) - { - this.insulationResistance = insulationResistance; - } - - public Integer getInsulationResistance() - { - return insulationResistance; - } - - public void setReservedData(String reservedData) - { - this.reservedData = reservedData; - } - - public String getReservedData() - { - return reservedData; - } - - - @Override - public String toString() { - return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) - .append("id", getId()) - .append("deviceId", getDeviceId()) - .append("timestamp", getTimestamp()) - .append("vehicleStatus", getVehicleStatus()) - .append("chargingStatus", getChargingStatus()) - .append("operationMode", getOperationMode()) - .append("vehicleSpeed", getVehicleSpeed()) - .append("totalMileage", getTotalMileage()) - .append("totalVoltage", getTotalVoltage()) - .append("totalCurrent", getTotalCurrent()) - .append("soc", getSoc()) - .append("dcdcStatus", getDcdcStatus()) - .append("gearPosition", getGearPosition()) - .append("insulationResistance", getInsulationResistance()) - .append("reservedData", getReservedData()) - .toString(); - } } 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 5f97e7a..780452a 100644 --- a/src/main/java/com/evobms/project/vehicledata/domain/VehicleLocation.java +++ b/src/main/java/com/evobms/project/vehicledata/domain/VehicleLocation.java @@ -3,7 +3,11 @@ package com.evobms.project.vehicledata.domain; import java.math.BigDecimal; import java.util.Date; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import com.evobms.framework.aspectj.lang.annotation.Excel; @@ -15,23 +19,29 @@ import com.evobms.framework.web.domain.BaseEntity; * @author ruoyi * @date 2025-11-15 */ +@ApiModel(description = "车辆位置数据对象") +@Data +@EqualsAndHashCode(callSuper = false) public class VehicleLocation extends BaseEntity { private static final long serialVersionUID = 1L; /** * 主键ID */ + @ApiModelProperty(value = "主键ID") private Long id; /** * 设备ID */ + @ApiModelProperty(value = "设备ID") @Excel(name = "设备ID") private String deviceId; /** * 数据时间戳 */ + @ApiModelProperty(value = "数据时间戳") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Excel(name = "数据时间戳", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") private Date timestamp; @@ -39,79 +49,21 @@ public class VehicleLocation extends BaseEntity { /** * 定位状态 (0:无效 1:有效) */ + @ApiModelProperty(value = "定位状态 (0:无效 1:有效)") @Excel(name = "定位状态 (0:无效 1:有效)") private Integer positioningStatus; /** * 经度 */ + @ApiModelProperty(value = "经度") @Excel(name = "经度") private BigDecimal longitude; /** * 纬度 */ + @ApiModelProperty(value = "纬度") @Excel(name = "纬度") private BigDecimal latitude; - - 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 setPositioningStatus(Integer positioningStatus) { - this.positioningStatus = positioningStatus; - } - - public Integer getPositioningStatus() { - return positioningStatus; - } - - public void setLongitude(BigDecimal longitude) { - this.longitude = longitude; - } - - public BigDecimal getLongitude() { - return longitude; - } - - public void setLatitude(BigDecimal latitude) { - this.latitude = latitude; - } - - 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(); - } } diff --git a/src/main/resources/application-druid.yml b/src/main/resources/application-druid.yml index 3edbf21..0137c99 100644 --- a/src/main/resources/application-druid.yml +++ b/src/main/resources/application-druid.yml @@ -6,7 +6,7 @@ spring: druid: # 主库数据源 master: - url: jdbc:mysql://localhost:3306/evo_bms1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + url: jdbc:mysql://192.168.5.121:3306/evo_bms1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: root # 从库数据源 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 675e2f7..30b9f09 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -16,7 +16,7 @@ ruoyi: # 开发环境配置 server: # 服务器HTTP端口,支持环境变量覆盖:SERVER_PORT,默认8080 - port: ${SERVER_PORT:8080} + port: ${SERVER_PORT:8011} servlet: # 应用的访问路径 context-path: / diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt index 0931cb8..0f0bab9 100644 --- a/src/main/resources/banner.txt +++ b/src/main/resources/banner.txt @@ -1,24 +1,10 @@ -Application Version: ${ruoyi.version} +Application Version: ${ruoyi-vue-plus.version} Spring Boot Version: ${spring-boot.version} -//////////////////////////////////////////////////////////////////// -// _ooOoo_ // -// o8888888o // -// 88" . "88 // -// (| ^_^ |) // -// O\ = /O // -// ____/`---'\____ // -// .' \\| |// `. // -// / \\||| : |||// \ // -// / _||||| -:- |||||- \ // -// | | \\\ - /// | | // -// | \_| ''\---/'' | | // -// \ .-\__ `-` ___/-. / // -// ___`. .' /--.--\ `. . ___ // -// ."" '< `.___\_<|>_/___.' >'"". // -// | | : `- \`.;`\ _ /`;.`/ - ` : | | // -// \ \ `-. \_ __\ /__ _/ .-` / / // -// ========`-.____`-.___\_____/___.-`____.-'======== // -// `=---=' // -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // -// 佛祖保佑 永不宕机 永无BUG // -//////////////////////////////////////////////////////////////////// \ No newline at end of file + _______ _______ _________ _______ _______ +( ____ \|\ /|( ___ )\__ __/( ____ \( ____ \|\ /| +| ( \/| ) ( || ( ) | ) ( | ( \/| ( \/| ) ( | +| (__ | | | || | | | | | | (__ | | | (___) | +| __) ( ( ) )| | | | | | | __) | | | ___ | +| ( \ \_/ / | | | | | | | ( | | | ( ) | +| (____/\ \ / | (___) | | | | (____/\| (____/\| ) ( | +(_______/ \_/ (_______) )_( (_______/(_______/|/ \| diff --git a/src/main/resources/mybatis/bms/BmsChargeDetailMapper.xml b/src/main/resources/mybatis/bms/BmsChargeDetailMapper.xml new file mode 100644 index 0000000..11f7eba --- /dev/null +++ b/src/main/resources/mybatis/bms/BmsChargeDetailMapper.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + insert into bms_charge_detail + + device_id, + timestamp, + ac_charge_current, + ac_charge_voltage, + dc_charge_current, + dc_charge_voltage, + charge_time, + ac_stop_code, + dc_stop_code, + ac_cp_value, + ac_gun_resistance, + charging_stage, + ac_stage, + dc_stage, + create_time, + update_time, + create_by, + update_by, + + + #{deviceId}, + #{timestamp}, + #{acChargeCurrent}, + #{acChargeVoltage}, + #{dcChargeCurrent}, + #{dcChargeVoltage}, + #{chargeTime}, + #{acStopCode}, + #{dcStopCode}, + #{acCpValue}, + #{acGunResistance}, + #{chargingStage}, + #{acStage}, + #{dcStage}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + + + diff --git a/src/main/resources/mybatis/bms/BmsSopDataMapper.xml b/src/main/resources/mybatis/bms/BmsSopDataMapper.xml new file mode 100644 index 0000000..5c4904c --- /dev/null +++ b/src/main/resources/mybatis/bms/BmsSopDataMapper.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + insert into bms_sop_data + + device_id, + timestamp, + discharge_sop_10s, + discharge_sop_30s, + discharge_sop_60s, + discharge_sop_continuous, + regen_sop_10s, + regen_sop_30s, + regen_sop_60s, + regen_sop_continuous, + charge_sop, + ac_charge_sop, + create_time, + update_time, + create_by, + update_by, + + + #{deviceId}, + #{timestamp}, + #{dischargeSop10s}, + #{dischargeSop30s}, + #{dischargeSop60s}, + #{dischargeSopContinuous}, + #{regenSop10s}, + #{regenSop30s}, + #{regenSop60s}, + #{regenSopContinuous}, + #{chargeSop}, + #{acChargeSop}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + + + diff --git a/src/main/resources/mybatis/bms/BmsSystemStatusMapper.xml b/src/main/resources/mybatis/bms/BmsSystemStatusMapper.xml new file mode 100644 index 0000000..7f92049 --- /dev/null +++ b/src/main/resources/mybatis/bms/BmsSystemStatusMapper.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + insert into bms_system_status + + device_id, + timestamp, + relay_status, + onaacc_status, + reset_count, + cycle_count, + sample_25v, + sample_5v, + cell_count, + temp_sensor_count, + create_time, + update_time, + create_by, + update_by, + + + #{deviceId}, + #{timestamp}, + #{relayStatus}, + #{onaaccStatus}, + #{resetCount}, + #{cycleCount}, + #{sample25v}, + #{sample5v}, + #{cellCount}, + #{tempSensorCount}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + + + diff --git a/src/main/resources/ota/0.0.1.bin b/src/main/resources/ota/0.0.6.bin similarity index 68% rename from src/main/resources/ota/0.0.1.bin rename to src/main/resources/ota/0.0.6.bin index ab25ad7..1f674de 100644 Binary files a/src/main/resources/ota/0.0.1.bin and b/src/main/resources/ota/0.0.6.bin differ diff --git a/src/main/resources/ota/1.0.2.bin b/src/main/resources/ota/1.0.2.bin deleted file mode 100644 index c598fec..0000000 --- a/src/main/resources/ota/1.0.2.bin +++ /dev/null @@ -1 +0,0 @@ -qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶qweqweqweqwzxcasdasdasdasdasd按时打算大叔大婶 \ No newline at end of file diff --git a/src/main/resources/ota/2.2.1.bin b/src/main/resources/ota/2.2.1.bin deleted file mode 100644 index ff899bc..0000000 Binary files a/src/main/resources/ota/2.2.1.bin and /dev/null differ