车辆位置,极值,位置等重要数据数据
This commit is contained in:
parent
3290319ba7
commit
6b6be61716
3
.vite/deps/package.json
Normal file
3
.vite/deps/package.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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))
|
||||
// 版本
|
||||
|
||||
@ -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<String, Object> params;
|
||||
|
||||
|
||||
@ -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<ExtremeValues> 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));
|
||||
|
||||
@ -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<SubsystemTemperature> 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));
|
||||
|
||||
@ -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<SubsystemVoltage> 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));
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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<String, Object> testHandleDeviceData(
|
||||
@RequestParam String topic,
|
||||
@RequestParam byte[] payload) {
|
||||
@ -70,6 +74,7 @@ public class MqttTestController {
|
||||
* @return 测试用的JSON数据
|
||||
*/
|
||||
@GetMapping("/generateTestData")
|
||||
@ApiOperation("生成测试数据")
|
||||
public Map<String, Object> generateTestData() {
|
||||
Map<String, Object> testData = new HashMap<>();
|
||||
testData.put("voltage", 12.5);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
67
src/main/java/com/evobms/project/bms/domain/BmsSopData.java
Normal file
67
src/main/java/com/evobms/project/bms/domain/BmsSopData.java
Normal file
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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<BmsChargeDetail> selectBmsChargeDetailList(BmsChargeDetail filter);
|
||||
}
|
||||
@ -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<BmsSopData> selectBmsSopDataList(BmsSopData filter);
|
||||
}
|
||||
@ -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<BmsSystemStatus> selectBmsSystemStatusList(BmsSystemStatus filter);
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.evobms.project.bms.service;
|
||||
|
||||
import com.evobms.project.bms.domain.BmsChargeDetail;
|
||||
|
||||
public interface IBmsChargeDetailService {
|
||||
int insertBmsChargeDetail(BmsChargeDetail data);
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.evobms.project.bms.service;
|
||||
|
||||
import com.evobms.project.bms.domain.BmsSopData;
|
||||
|
||||
public interface IBmsSopDataService {
|
||||
int insertBmsSopData(BmsSopData data);
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.evobms.project.bms.service;
|
||||
|
||||
import com.evobms.project.bms.domain.BmsSystemStatus;
|
||||
|
||||
public interface IBmsSystemStatusService {
|
||||
int insertBmsSystemStatus(BmsSystemStatus data);
|
||||
}
|
||||
@ -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码
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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<String, Object> requestToken(@RequestBody Map<String, String> 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) {
|
||||
|
||||
@ -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<String, Object> reportOtaStatus(@RequestBody Map<String, String> body,
|
||||
HttpServletRequest request) {
|
||||
Map<String, Object> resp = new HashMap<>();
|
||||
|
||||
@ -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<OtaTasks> 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));
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<ChargeDischargeSummary> 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));
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<BmsDevices> 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));
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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<ChartDataPoint> getChartData(@PathVariable("deviceId") String deviceId, @RequestParam(value = "hours", required = false, defaultValue = "24") int hours) {
|
||||
public List<ChartDataPoint> 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<VehicleData> 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<VehicleLocation> locationRange(@PathVariable("deviceId") String deviceId, @RequestParam("start") long startMillis, @RequestParam("end") long endMillis, @RequestParam(value = "limit", required = false) Integer limit) {
|
||||
public List<VehicleLocation> 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<HomeDashboardDTO> home(){
|
||||
HomeDashboardDTO dto = vehicleDataService.getHomeDashboard();
|
||||
return R.ok(dto);
|
||||
|
||||
@ -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<VehicleData> 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));
|
||||
|
||||
@ -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<VehicleLocation> 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));
|
||||
|
||||
@ -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<String, Integer> socDistribution; // SOC 分布
|
||||
@ApiModelProperty(value = "温度分布")
|
||||
private Map<String, Integer> tempDistribution; // 温度分布
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
# 从库数据源
|
||||
|
||||
@ -16,7 +16,7 @@ ruoyi:
|
||||
# 开发环境配置
|
||||
server:
|
||||
# 服务器HTTP端口,支持环境变量覆盖:SERVER_PORT,默认8080
|
||||
port: ${SERVER_PORT:8080}
|
||||
port: ${SERVER_PORT:8011}
|
||||
servlet:
|
||||
# 应用的访问路径
|
||||
context-path: /
|
||||
|
||||
@ -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 //
|
||||
////////////////////////////////////////////////////////////////////
|
||||
_______ _______ _________ _______ _______
|
||||
( ____ \|\ /|( ___ )\__ __/( ____ \( ____ \|\ /|
|
||||
| ( \/| ) ( || ( ) | ) ( | ( \/| ( \/| ) ( |
|
||||
| (__ | | | || | | | | | | (__ | | | (___) |
|
||||
| __) ( ( ) )| | | | | | | __) | | | ___ |
|
||||
| ( \ \_/ / | | | | | | | ( | | | ( ) |
|
||||
| (____/\ \ / | (___) | | | | (____/\| (____/\| ) ( |
|
||||
(_______/ \_/ (_______) )_( (_______/(_______/|/ \|
|
||||
|
||||
71
src/main/resources/mybatis/bms/BmsChargeDetailMapper.xml
Normal file
71
src/main/resources/mybatis/bms/BmsChargeDetailMapper.xml
Normal file
@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.evobms.project.bms.mapper.BmsChargeDetailMapper">
|
||||
<resultMap type="com.evobms.project.bms.domain.BmsChargeDetail" id="BmsChargeDetailResult">
|
||||
<result property="id" column="id"/>
|
||||
<result property="deviceId" column="device_id"/>
|
||||
<result property="timestamp" column="timestamp"/>
|
||||
<result property="acChargeCurrent" column="ac_charge_current"/>
|
||||
<result property="acChargeVoltage" column="ac_charge_voltage"/>
|
||||
<result property="dcChargeCurrent" column="dc_charge_current"/>
|
||||
<result property="dcChargeVoltage" column="dc_charge_voltage"/>
|
||||
<result property="chargeTime" column="charge_time"/>
|
||||
<result property="acStopCode" column="ac_stop_code"/>
|
||||
<result property="dcStopCode" column="dc_stop_code"/>
|
||||
<result property="acCpValue" column="ac_cp_value"/>
|
||||
<result property="acGunResistance" column="ac_gun_resistance"/>
|
||||
<result property="chargingStage" column="charging_stage"/>
|
||||
<result property="acStage" column="ac_stage"/>
|
||||
<result property="dcStage" column="dc_stage"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
</resultMap>
|
||||
|
||||
<insert id="insertBmsChargeDetail" parameterType="com.evobms.project.bms.domain.BmsChargeDetail" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into bms_charge_detail
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="deviceId != null and deviceId != ''">device_id,</if>
|
||||
<if test="timestamp != null">timestamp,</if>
|
||||
<if test="acChargeCurrent != null">ac_charge_current,</if>
|
||||
<if test="acChargeVoltage != null">ac_charge_voltage,</if>
|
||||
<if test="dcChargeCurrent != null">dc_charge_current,</if>
|
||||
<if test="dcChargeVoltage != null">dc_charge_voltage,</if>
|
||||
<if test="chargeTime != null">charge_time,</if>
|
||||
<if test="acStopCode != null">ac_stop_code,</if>
|
||||
<if test="dcStopCode != null">dc_stop_code,</if>
|
||||
<if test="acCpValue != null">ac_cp_value,</if>
|
||||
<if test="acGunResistance != null">ac_gun_resistance,</if>
|
||||
<if test="chargingStage != null">charging_stage,</if>
|
||||
<if test="acStage != null">ac_stage,</if>
|
||||
<if test="dcStage != null">dc_stage,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
<if test="updateBy != null">update_by,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="deviceId != null and deviceId != ''">#{deviceId},</if>
|
||||
<if test="timestamp != null">#{timestamp},</if>
|
||||
<if test="acChargeCurrent != null">#{acChargeCurrent},</if>
|
||||
<if test="acChargeVoltage != null">#{acChargeVoltage},</if>
|
||||
<if test="dcChargeCurrent != null">#{dcChargeCurrent},</if>
|
||||
<if test="dcChargeVoltage != null">#{dcChargeVoltage},</if>
|
||||
<if test="chargeTime != null">#{chargeTime},</if>
|
||||
<if test="acStopCode != null">#{acStopCode},</if>
|
||||
<if test="dcStopCode != null">#{dcStopCode},</if>
|
||||
<if test="acCpValue != null">#{acCpValue},</if>
|
||||
<if test="acGunResistance != null">#{acGunResistance},</if>
|
||||
<if test="chargingStage != null">#{chargingStage},</if>
|
||||
<if test="acStage != null">#{acStage},</if>
|
||||
<if test="dcStage != null">#{dcStage},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="updateBy != null">#{updateBy},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
</mapper>
|
||||
65
src/main/resources/mybatis/bms/BmsSopDataMapper.xml
Normal file
65
src/main/resources/mybatis/bms/BmsSopDataMapper.xml
Normal file
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.evobms.project.bms.mapper.BmsSopDataMapper">
|
||||
<resultMap type="com.evobms.project.bms.domain.BmsSopData" id="BmsSopDataResult">
|
||||
<result property="id" column="id"/>
|
||||
<result property="deviceId" column="device_id"/>
|
||||
<result property="timestamp" column="timestamp"/>
|
||||
<result property="dischargeSop10s" column="discharge_sop_10s"/>
|
||||
<result property="dischargeSop30s" column="discharge_sop_30s"/>
|
||||
<result property="dischargeSop60s" column="discharge_sop_60s"/>
|
||||
<result property="dischargeSopContinuous" column="discharge_sop_continuous"/>
|
||||
<result property="regenSop10s" column="regen_sop_10s"/>
|
||||
<result property="regenSop30s" column="regen_sop_30s"/>
|
||||
<result property="regenSop60s" column="regen_sop_60s"/>
|
||||
<result property="regenSopContinuous" column="regen_sop_continuous"/>
|
||||
<result property="chargeSop" column="charge_sop"/>
|
||||
<result property="acChargeSop" column="ac_charge_sop"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
</resultMap>
|
||||
|
||||
<insert id="insertBmsSopData" parameterType="com.evobms.project.bms.domain.BmsSopData" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into bms_sop_data
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="deviceId != null and deviceId != ''">device_id,</if>
|
||||
<if test="timestamp != null">timestamp,</if>
|
||||
<if test="dischargeSop10s != null">discharge_sop_10s,</if>
|
||||
<if test="dischargeSop30s != null">discharge_sop_30s,</if>
|
||||
<if test="dischargeSop60s != null">discharge_sop_60s,</if>
|
||||
<if test="dischargeSopContinuous != null">discharge_sop_continuous,</if>
|
||||
<if test="regenSop10s != null">regen_sop_10s,</if>
|
||||
<if test="regenSop30s != null">regen_sop_30s,</if>
|
||||
<if test="regenSop60s != null">regen_sop_60s,</if>
|
||||
<if test="regenSopContinuous != null">regen_sop_continuous,</if>
|
||||
<if test="chargeSop != null">charge_sop,</if>
|
||||
<if test="acChargeSop != null">ac_charge_sop,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
<if test="updateBy != null">update_by,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="deviceId != null and deviceId != ''">#{deviceId},</if>
|
||||
<if test="timestamp != null">#{timestamp},</if>
|
||||
<if test="dischargeSop10s != null">#{dischargeSop10s},</if>
|
||||
<if test="dischargeSop30s != null">#{dischargeSop30s},</if>
|
||||
<if test="dischargeSop60s != null">#{dischargeSop60s},</if>
|
||||
<if test="dischargeSopContinuous != null">#{dischargeSopContinuous},</if>
|
||||
<if test="regenSop10s != null">#{regenSop10s},</if>
|
||||
<if test="regenSop30s != null">#{regenSop30s},</if>
|
||||
<if test="regenSop60s != null">#{regenSop60s},</if>
|
||||
<if test="regenSopContinuous != null">#{regenSopContinuous},</if>
|
||||
<if test="chargeSop != null">#{chargeSop},</if>
|
||||
<if test="acChargeSop != null">#{acChargeSop},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="updateBy != null">#{updateBy},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
</mapper>
|
||||
59
src/main/resources/mybatis/bms/BmsSystemStatusMapper.xml
Normal file
59
src/main/resources/mybatis/bms/BmsSystemStatusMapper.xml
Normal file
@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.evobms.project.bms.mapper.BmsSystemStatusMapper">
|
||||
<resultMap type="com.evobms.project.bms.domain.BmsSystemStatus" id="BmsSystemStatusResult">
|
||||
<result property="id" column="id"/>
|
||||
<result property="deviceId" column="device_id"/>
|
||||
<result property="timestamp" column="timestamp"/>
|
||||
<result property="relayStatus" column="relay_status"/>
|
||||
<result property="onaaccStatus" column="onaacc_status"/>
|
||||
<result property="resetCount" column="reset_count"/>
|
||||
<result property="cycleCount" column="cycle_count"/>
|
||||
<result property="sample25v" column="sample_25v"/>
|
||||
<result property="sample5v" column="sample_5v"/>
|
||||
<result property="cellCount" column="cell_count"/>
|
||||
<result property="tempSensorCount" column="temp_sensor_count"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
</resultMap>
|
||||
|
||||
<insert id="insertBmsSystemStatus" parameterType="com.evobms.project.bms.domain.BmsSystemStatus" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into bms_system_status
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="deviceId != null and deviceId != ''">device_id,</if>
|
||||
<if test="timestamp != null">timestamp,</if>
|
||||
<if test="relayStatus != null">relay_status,</if>
|
||||
<if test="onaaccStatus != null">onaacc_status,</if>
|
||||
<if test="resetCount != null">reset_count,</if>
|
||||
<if test="cycleCount != null">cycle_count,</if>
|
||||
<if test="sample25v != null">sample_25v,</if>
|
||||
<if test="sample5v != null">sample_5v,</if>
|
||||
<if test="cellCount != null">cell_count,</if>
|
||||
<if test="tempSensorCount != null">temp_sensor_count,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
<if test="updateBy != null">update_by,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="deviceId != null and deviceId != ''">#{deviceId},</if>
|
||||
<if test="timestamp != null">#{timestamp},</if>
|
||||
<if test="relayStatus != null">#{relayStatus},</if>
|
||||
<if test="onaaccStatus != null">#{onaaccStatus},</if>
|
||||
<if test="resetCount != null">#{resetCount},</if>
|
||||
<if test="cycleCount != null">#{cycleCount},</if>
|
||||
<if test="sample25v != null">#{sample25v},</if>
|
||||
<if test="sample5v != null">#{sample5v},</if>
|
||||
<if test="cellCount != null">#{cellCount},</if>
|
||||
<if test="tempSensorCount != null">#{tempSensorCount},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="updateBy != null">#{updateBy},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
</mapper>
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Loading…
Reference in New Issue
Block a user