Commit 809cb452923c862e6223613fd3687360262e036c

Authored by YunaiV
1 parent 3bc1bfe1

feat:【iot】modbus-tcp 协议接入 100%:和管理后台对接,并修复少量 bug

yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/api/device/IoTDeviceApiImpl.java
... ... @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
4 4 import cn.iocoder.yudao.framework.common.enums.RpcConstants;
5 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
6 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
7 8 import cn.iocoder.yudao.module.iot.core.biz.IotDeviceCommonApi;
8 9 import cn.iocoder.yudao.module.iot.core.biz.dto.*;
9 10 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
... ... @@ -22,7 +23,6 @@ import org.springframework.web.bind.annotation.PostMapping;
22 23 import org.springframework.web.bind.annotation.RequestBody;
23 24 import org.springframework.web.bind.annotation.RestController;
24 25  
25   -import java.math.BigDecimal;
26 26 import java.util.ArrayList;
27 27 import java.util.List;
28 28 import java.util.Map;
... ... @@ -74,12 +74,8 @@ public class IoTDeviceApiImpl implements IotDeviceCommonApi {
74 74 @Override
75 75 @PostMapping(RpcConstants.RPC_API_PREFIX + "/iot/modbus/enabled-configs")
76 76 @PermitAll
  77 + @TenantIgnore
77 78 public CommonResult<List<IotModbusDeviceConfigRespDTO>> getEnabledModbusDeviceConfigs() {
78   - // TODO @芋艿:临时 mock 数据,用于测试 ModbusTcpSlaveSimulator
79   - if (true) {
80   - return success(buildMockModbusConfigs());
81   - }
82   -
83 79 // 1. 获取所有启用的 Modbus 连接配置
84 80 List<IotDeviceModbusConfigDO> configList = modbusConfigService.getEnabledDeviceModbusConfigList();
85 81 if (CollUtil.isEmpty(configList)) {
... ... @@ -111,74 +107,4 @@ public class IoTDeviceApiImpl implements IotDeviceCommonApi {
111 107 return success(result);
112 108 }
113 109  
114   - /**
115   - * 构建 Mock Modbus 配置,对接 ModbusTcpSlaveSimulator
116   - *
117   - * 设备:productKey=4aymZgOTOOCrDKRT, deviceName=small
118   - * 物模型字段:width, height, oneThree
119   - */
120   - private List<IotModbusDeviceConfigRespDTO> buildMockModbusConfigs() {
121   - List<IotModbusDeviceConfigRespDTO> configs = new ArrayList<>();
122   -
123   - // 设备配置
124   - IotModbusDeviceConfigRespDTO config = new IotModbusDeviceConfigRespDTO();
125   - config.setDeviceId(1L);
126   - config.setProductKey("4aymZgOTOOCrDKRT");
127   - config.setDeviceName("small");
128   - config.setIp("127.0.0.1");
129   - config.setPort(5020); // 对应 ModbusTcpSlaveSimulator 的端口
130   - config.setSlaveId(1);
131   - config.setTimeout(3000);
132   - config.setRetryInterval(5000);
133   -
134   - // 点位配置(对应物模型字段:width, height, oneThree)
135   - List<IotModbusPointRespDTO> points = new ArrayList<>();
136   -
137   - // 点位 1:width - 读取保持寄存器地址 0(功能码 03)
138   - IotModbusPointRespDTO point1 = new IotModbusPointRespDTO();
139   - point1.setId(1L);
140   - point1.setIdentifier("width");
141   - point1.setName("宽度");
142   - point1.setFunctionCode(3); // 读保持寄存器
143   - point1.setRegisterAddress(0);
144   - point1.setRegisterCount(1);
145   - point1.setByteOrder("AB");
146   - point1.setRawDataType("INT16");
147   - point1.setScale(BigDecimal.ONE);
148   - point1.setPollInterval(3000); // 3 秒轮询
149   - points.add(point1);
150   -
151   - // 点位 2:height - 读取保持寄存器地址 1(功能码 03)
152   - IotModbusPointRespDTO point2 = new IotModbusPointRespDTO();
153   - point2.setId(2L);
154   - point2.setIdentifier("height");
155   - point2.setName("高度");
156   - point2.setFunctionCode(3); // 读保持寄存器
157   - point2.setRegisterAddress(1);
158   - point2.setRegisterCount(1);
159   - point2.setByteOrder("AB");
160   - point2.setRawDataType("INT16");
161   - point2.setScale(BigDecimal.ONE);
162   - point2.setPollInterval(3000); // 3 秒轮询
163   - points.add(point2);
164   -
165   - // 点位 3:oneThree - 读取保持寄存器地址 2(功能码 03)
166   - IotModbusPointRespDTO point3 = new IotModbusPointRespDTO();
167   - point3.setId(3L);
168   - point3.setIdentifier("oneThree");
169   - point3.setName("一三");
170   - point3.setFunctionCode(3); // 读保持寄存器
171   - point3.setRegisterAddress(2);
172   - point3.setRegisterCount(1);
173   - point3.setByteOrder("AB");
174   - point3.setRawDataType("INT16");
175   - point3.setScale(BigDecimal.ONE);
176   - point3.setPollInterval(3000); // 3 秒轮询
177   - points.add(point3);
178   -
179   - config.setPoints(points);
180   - configs.add(config);
181   - return configs;
182   - }
183   -
184 110 }
185 111 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceModbusConfigController.java
... ... @@ -28,26 +28,17 @@ public class IotDeviceModbusConfigController {
28 28  
29 29 @PostMapping("/save")
30 30 @Operation(summary = "保存设备 Modbus 连接配置")
31   - @PreAuthorize("@ss.hasPermission('iot:device-modbus-config:create')")
  31 + @PreAuthorize("@ss.hasPermission('iot:device:update')")
32 32 public CommonResult<Boolean> saveDeviceModbusConfig(@Valid @RequestBody IotDeviceModbusConfigSaveReqVO saveReqVO) {
33 33 modbusConfigService.saveDeviceModbusConfig(saveReqVO);
34 34 return success(true);
35 35 }
36 36  
37   - @DeleteMapping("/delete")
38   - @Operation(summary = "删除设备 Modbus 连接配置")
39   - @Parameter(name = "id", description = "编号", required = true)
40   - @PreAuthorize("@ss.hasPermission('iot:device-modbus-config:delete')")
41   - public CommonResult<Boolean> deleteDeviceModbusConfig(@RequestParam("id") Long id) {
42   - modbusConfigService.deleteDeviceModbusConfig(id);
43   - return success(true);
44   - }
45   -
46 37 @GetMapping("/get")
47 38 @Operation(summary = "获得设备 Modbus 连接配置")
48 39 @Parameter(name = "id", description = "编号", example = "1024")
49 40 @Parameter(name = "deviceId", description = "设备编号", example = "2048")
50   - @PreAuthorize("@ss.hasPermission('iot:device-modbus-config:query')")
  41 + @PreAuthorize("@ss.hasPermission('iot:device:query')")
51 42 public CommonResult<IotDeviceModbusConfigRespVO> getDeviceModbusConfig(
52 43 @RequestParam(value = "id", required = false) Long id,
53 44 @RequestParam(value = "deviceId", required = false) Long deviceId) {
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/IotDeviceModbusPointController.java
... ... @@ -30,14 +30,14 @@ public class IotDeviceModbusPointController {
30 30  
31 31 @PostMapping("/create")
32 32 @Operation(summary = "创建设备 Modbus 点位配置")
33   - @PreAuthorize("@ss.hasPermission('iot:device-modbus-point:create')")
  33 + @PreAuthorize("@ss.hasPermission('iot:device:update')")
34 34 public CommonResult<Long> createDeviceModbusPoint(@Valid @RequestBody IotDeviceModbusPointSaveReqVO createReqVO) {
35 35 return success(modbusPointService.createDeviceModbusPoint(createReqVO));
36 36 }
37 37  
38 38 @PutMapping("/update")
39 39 @Operation(summary = "更新设备 Modbus 点位配置")
40   - @PreAuthorize("@ss.hasPermission('iot:device-modbus-point:update')")
  40 + @PreAuthorize("@ss.hasPermission('iot:device:update')")
41 41 public CommonResult<Boolean> updateDeviceModbusPoint(@Valid @RequestBody IotDeviceModbusPointSaveReqVO updateReqVO) {
42 42 modbusPointService.updateDeviceModbusPoint(updateReqVO);
43 43 return success(true);
... ... @@ -46,7 +46,7 @@ public class IotDeviceModbusPointController {
46 46 @DeleteMapping("/delete")
47 47 @Operation(summary = "删除设备 Modbus 点位配置")
48 48 @Parameter(name = "id", description = "编号", required = true)
49   - @PreAuthorize("@ss.hasPermission('iot:device-modbus-point:delete')")
  49 + @PreAuthorize("@ss.hasPermission('iot:device:update')")
50 50 public CommonResult<Boolean> deleteDeviceModbusPoint(@RequestParam("id") Long id) {
51 51 modbusPointService.deleteDeviceModbusPoint(id);
52 52 return success(true);
... ... @@ -55,7 +55,7 @@ public class IotDeviceModbusPointController {
55 55 @GetMapping("/get")
56 56 @Operation(summary = "获得设备 Modbus 点位配置")
57 57 @Parameter(name = "id", description = "编号", required = true, example = "1024")
58   - @PreAuthorize("@ss.hasPermission('iot:device-modbus-point:query')")
  58 + @PreAuthorize("@ss.hasPermission('iot:device:query')")
59 59 public CommonResult<IotDeviceModbusPointRespVO> getDeviceModbusPoint(@RequestParam("id") Long id) {
60 60 IotDeviceModbusPointDO modbusPoint = modbusPointService.getDeviceModbusPoint(id);
61 61 return success(BeanUtils.toBean(modbusPoint, IotDeviceModbusPointRespVO.class));
... ... @@ -63,7 +63,7 @@ public class IotDeviceModbusPointController {
63 63  
64 64 @GetMapping("/page")
65 65 @Operation(summary = "获得设备 Modbus 点位配置分页")
66   - @PreAuthorize("@ss.hasPermission('iot:device-modbus-point:query')")
  66 + @PreAuthorize("@ss.hasPermission('iot:device:query')")
67 67 public CommonResult<PageResult<IotDeviceModbusPointRespVO>> getDeviceModbusPointPage(@Valid IotDeviceModbusPointPageReqVO pageReqVO) {
68 68 PageResult<IotDeviceModbusPointDO> pageResult = modbusPointService.getDeviceModbusPointPage(pageReqVO);
69 69 return success(BeanUtils.toBean(pageResult, IotDeviceModbusPointRespVO.class));
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceModbusConfigService.java
... ... @@ -21,13 +21,6 @@ public interface IotDeviceModbusConfigService {
21 21 void saveDeviceModbusConfig(@Valid IotDeviceModbusConfigSaveReqVO saveReqVO);
22 22  
23 23 /**
24   - * 删除设备 Modbus 连接配置
25   - *
26   - * @param id 编号
27   - */
28   - void deleteDeviceModbusConfig(Long id);
29   -
30   - /**
31 24 * 获得设备 Modbus 连接配置
32 25 *
33 26 * @param id 编号
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceModbusConfigServiceImpl.java
... ... @@ -11,9 +11,6 @@ import org.springframework.validation.annotation.Validated;
11 11  
12 12 import java.util.List;
13 13  
14   -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
15   -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DEVICE_MODBUS_CONFIG_NOT_EXISTS;
16   -
17 14 /**
18 15 * IoT 设备 Modbus 连接配置 Service 实现类
19 16 *
... ... @@ -47,20 +44,6 @@ public class IotDeviceModbusConfigServiceImpl implements IotDeviceModbusConfigSe
47 44 }
48 45  
49 46 @Override
50   - public void deleteDeviceModbusConfig(Long id) {
51   - // 校验存在
52   - validateDeviceModbusConfigExists(id);
53   - // 删除
54   - modbusConfigMapper.deleteById(id);
55   - }
56   -
57   - private void validateDeviceModbusConfigExists(Long id) {
58   - if (modbusConfigMapper.selectById(id) == null) {
59   - throw exception(DEVICE_MODBUS_CONFIG_NOT_EXISTS);
60   - }
61   - }
62   -
63   - @Override
64 47 public IotDeviceModbusConfigDO getDeviceModbusConfig(Long id) {
65 48 return modbusConfigMapper.selectById(id);
66 49 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceModbusPointServiceImpl.java
... ... @@ -70,7 +70,8 @@ public class IotDeviceModbusPointServiceImpl implements IotDeviceModbusPointServ
70 70 validateDeviceModbusPointUnique(updateReqVO.getDeviceId(), thingModel.getIdentifier(), updateReqVO.getId());
71 71  
72 72 // 2. 更新
73   - IotDeviceModbusPointDO updateObj = BeanUtils.toBean(updateReqVO, IotDeviceModbusPointDO.class);
  73 + IotDeviceModbusPointDO updateObj = BeanUtils.toBean(updateReqVO, IotDeviceModbusPointDO.class,
  74 + o -> o.setIdentifier(thingModel.getIdentifier()).setName(thingModel.getName()));
74 75 modbusPointMapper.updateById(updateObj);
75 76 }
76 77  
... ...
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/codec/tcp/IotTcpBinaryDeviceMessageCodec.java
... ... @@ -41,7 +41,7 @@ import java.nio.charset.StandardCharsets;
41 41 @Component
42 42 public class IotTcpBinaryDeviceMessageCodec implements IotDeviceMessageCodec {
43 43  
44   - public static final String TYPE = "TCP_BINARY";
  44 + public static final String TYPE = "TcpBinary";
45 45  
46 46 /**
47 47 * 协议魔术字,用于协议识别
... ...
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/codec/tcp/IotTcpJsonDeviceMessageCodec.java
... ... @@ -29,7 +29,7 @@ import org.springframework.stereotype.Component;
29 29 @Component
30 30 public class IotTcpJsonDeviceMessageCodec implements IotDeviceMessageCodec {
31 31  
32   - public static final String TYPE = "TCP_JSON";
  32 + public static final String TYPE = "TcpJson";
33 33  
34 34 @Data
35 35 @NoArgsConstructor
... ...
yudao-module-iot/yudao-module-iot-gateway/src/test/resources/tcp-binary-packet-examples.md
... ... @@ -162,7 +162,7 @@ E8 AF 81 E6 88 90 E5 8A 9F 22
162 162 ## 4. 编解码器标识
163 163  
164 164 ```java
165   -public static final String TYPE = "TCP_BINARY";
  165 +public static final String TYPE = "TcpBinary";
166 166 ```
167 167  
168 168 ## 5. 协议优势
... ...
yudao-module-iot/yudao-module-iot-gateway/src/test/resources/tcp-json-packet-examples.md
... ... @@ -161,7 +161,7 @@ TCP JSON æ ¼å¼å议采用纯 JSON æ ¼å¼è¿›è¡Œæ•°æ®ä¼ è¾“,具有以下特ç‚
161 161 ## 4. ç¼–è§£ç å™¨æ ‡è¯†
162 162  
163 163 ```java
164   -public static final String TYPE = "TCP_JSON";
  164 +public static final String TYPE = "TcpJson";
165 165 ```
166 166  
167 167 ## 5. å议优势
... ...