diff --git a/data/init/sys_menu.json b/data/init/sys_menu.json index 68016034..891ff825 100644 --- a/data/init/sys_menu.json +++ b/data/init/sys_menu.json @@ -3518,4 +3518,70 @@ "icon" : "", "remark" : null, "children" : [ ] -} ] \ No newline at end of file +} , { + "createDept" : null, + "createBy" : null, + "createTime" : 1709365727999, + "updateBy" : null, + "updateTime" : 1709365772669, + "id" : 521131319332933, + "menuName" : "设备分组详情", + "parentId" : 2200, + "orderNum" : 17, + "path" : "deviceGroupDetail/:id", + "component" : "iot/equipment/devices/deviceGroupDetail", + "queryParam" : null, + "isFrame" : "1", + "isCache" : "1", + "menuType" : "C", + "visible" : "1", + "status" : "0", + "perms" : "iot:device:query", + "icon" : "", + "remark" : null, + "children" : [ ] +}, { + "createDept" : null, + "createBy" : null, + "createTime" : 1709365727999, + "updateBy" : null, + "updateTime" : 1709365772669, + "id" : 541767098171461, + "menuName" : "Modbus管理", + "parentId" : 0, + "orderNum" : 2, + "path" : "modbus", + "component" : "", + "queryParam" : null, + "isFrame" : "1", + "isCache" : "0", + "menuType" : "M", + "visible" : "0", + "status" : "0", + "perms" : "", + "icon" : "build", + "remark" : null, + "children" : [ ] +}, { + "createDept" : null, + "createBy" : null, + "createTime" : 1709365727999, + "updateBy" : null, + "updateTime" : 1709365772669, + "id" : 541767327625285, + "menuName" : "产品点位", + "parentId" : 541767098171461, + "orderNum" : 17, + "path" : "modbusinfo", + "component" : "iot/modbus/info/index", + "queryParam" : null, + "isFrame" : "1", + "isCache" : "0", + "menuType" : "C", + "visible" : "0", + "status" : "0", + "perms" : "iot:modbus:list", + "icon" : "radio", + "remark" : null, + "children" : [ ] +}] \ No newline at end of file diff --git a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/modbus/ModbusInfo.java b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/modbus/ModbusInfo.java new file mode 100644 index 00000000..21ec2088 --- /dev/null +++ b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/modbus/ModbusInfo.java @@ -0,0 +1,63 @@ +/* + * +---------------------------------------------------------------------- + * | Copyright (c) 奇特物联 2021-2022 All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed 未经许可不能去掉「奇特物联」相关版权 + * +---------------------------------------------------------------------- + * | Author: xw2sy@163.com + * +---------------------------------------------------------------------- + */ +package cc.iotkit.model.modbus; + +import cc.iotkit.model.Owned; +import cc.iotkit.model.TenantModel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @Description: modbus信息 + * @Author: ZOUZDC + * @Date: 2024/4/28 22:49 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ModbusInfo extends TenantModel implements Owned, Serializable { + + private Long id; + + /** + * 配置所属用户 + */ + private String uid; + + /** + * 产品名称 + */ + private String name; + + private String productKey; + + /** + * 说明 + */ + private String remark; + + /** + * 创建时间 + */ + private Long createAt; + + /** + * 更新时间 + */ + private Long updateAt; + + + +} diff --git a/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/modbus/ModbusThingModel.java b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/modbus/ModbusThingModel.java new file mode 100644 index 00000000..ee7eda86 --- /dev/null +++ b/iot-dao/iot-data-model/src/main/java/cc/iotkit/model/modbus/ModbusThingModel.java @@ -0,0 +1,153 @@ +/* + * +---------------------------------------------------------------------- + * | Copyright (c) 奇特物联 2021-2022 All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed 未经许可不能去掉「奇特物联」相关版权 + * +---------------------------------------------------------------------- + * | Author: xw2sy@163.com + * +---------------------------------------------------------------------- + */ +package cc.iotkit.model.modbus; + +import cc.iotkit.model.Id; +import cc.iotkit.model.TenantModel; +import cc.iotkit.model.product.ThingModel; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.*; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @Description: modbus点表物模型 + * @Author: ZOUZDC + * @Date: 2024/4/28 22:52 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ModbusThingModel extends TenantModel implements Id, Serializable { + private static final long serialVersionUID = 1L; + + private Long id; + + private String productKey; + + private ModbusThingModel.Model model; + + private Long updateAt; + + public ModbusThingModel(String productKey) { + this.productKey = productKey; + } + + @Data + public static class Model { + private List properties; + private List services; + private List events; + + public Map serviceMap() { + if (services == null) { + return new HashMap<>(); + } + return services.stream().collect(Collectors.toMap(ModbusThingModel.Service::getIdentifier, s -> s)); + } + } + + @Data + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Property { + private String name; + private String identifier; + // 描述 + private String description; + /** + * 寄存器类型 + * [{value:'01',label:'线圈状态(RW)',}, + * {value:'02',label:'离散输入(RO)',}, + * {value:'03',label:'保持寄存器(RW)',}, + * {value:'04',label:'输入寄存器(RO)',},] + */ + private String regType; + //寄存器地址 + private Integer regAddr; + //寄存器数量 + private Integer regNum; + /** + * 处理公式 + * [ + * { value: 'AB', }, + * { value: 'BA', }, + * { value: 'AB CD', }, + * { value: 'CD AB', }, + * { value: 'DC BA', }, + * { value: 'BA DC', }, + * ] + */ + private String processor; + //数据顺序 + private Integer sort; + + private ModbusThingModel.DataType dataType; + + private String accessMode = "rw"; + + // 单位 + private String unit; + } + + @Data + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Parameter { + private String identifier; + private ThingModel.DataType dataType; + private String name; + private Boolean required = false; + } + + @Data + public static class Service { + private String identifier; + private List inputData; + private List outputData; + private String name; + } + + @Data + public static class Event { + private String identifier; + private List outputData; + private String name; + } + + @Data + public static class DataType { + private String type; + private Object specs; + + public Object parse(T value) { + if (value == null) { + return null; + } + + String val = value.toString(); + type = type.toLowerCase(); + switch (type) { + case "bool": + case "enum": + return val; + case "int": + return Integer.parseInt(val); + default: + return val; + } + + } + } +} diff --git a/iot-module/iot-modbus/pom.xml b/iot-module/iot-modbus/pom.xml new file mode 100644 index 00000000..4f16913f --- /dev/null +++ b/iot-module/iot-modbus/pom.xml @@ -0,0 +1,114 @@ + + + + iot-module + cc.iotkit + 0.5.3 + + 4.0.0 + + iot-modbus + + + + + cc.iotkit + iot-common-core + + + + cc.iotkit + iot-common-web + + + + cc.iotkit + iot-common-log + + + + cc.iotkit + iot-common-excel + + + + cc.iotkit + iot-common-tenant + + + + cc.iotkit + iot-data-model + + + + + cc.iotkit + iot-common-doc + + + + + cc.iotkit + iot-data-serviceImpl-rdb + + + + cc.iotkit + iot-common-satoken + + + + + + io.github.linpeilie + mapstruct-plus-spring-boot-starter + + + + org.projectlombok + lombok + + + cc.iotkit + iot-manager + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${java.version} + ${java.version} + utf8 + + + org.projectlombok + lombok + ${lombok.version} + + + io.github.linpeilie + mapstruct-plus-processor + ${mapstruct-plus.version} + + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + + + + + + + + + diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/controller/ModbusController.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/controller/ModbusController.java new file mode 100644 index 00000000..37bb4f06 --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/controller/ModbusController.java @@ -0,0 +1,140 @@ +/* + * +---------------------------------------------------------------------- + * | Copyright (c) 奇特物联 2021-2022 All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed 未经许可不能去掉「奇特物联」相关版权 + * +---------------------------------------------------------------------- + * | Author: xw2sy@163.com + * +---------------------------------------------------------------------- + */ +package cc.iotkit.modbus.controller; + + +import cc.iotkit.common.api.PageRequest; +import cc.iotkit.common.api.Paging; +import cc.iotkit.common.api.Request; +import cc.iotkit.common.enums.ErrCode; +import cc.iotkit.common.excel.utils.ExcelUtil; +import cc.iotkit.common.exception.BizException; +import cc.iotkit.common.log.annotation.Log; +import cc.iotkit.common.log.enums.BusinessType; +import cc.iotkit.common.validate.AddGroup; +import cc.iotkit.common.validate.EditGroup; +import cc.iotkit.modbus.dto.bo.modbus.ModbusInfoBo; +import cc.iotkit.modbus.dto.bo.modbus.ModbusThingModelBo; +import cc.iotkit.modbus.dto.vo.modbus.ModbusInfoVo; +import cc.iotkit.modbus.dto.vo.modbus.ModbusThingModelImportVo; +import cc.iotkit.modbus.dto.vo.modbus.ModbusThingModelVo; +import cc.iotkit.modbus.service.IModbusInfoService; +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.util.StrUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; + +/** + * @Description: Modbus模版管理 + * @Author: ZOUZDC + * @Date: 2024/4/28 23:10 + */ +@Api(tags = {"modbus"}) +@Slf4j +@RestController +@RequestMapping("/modbus") +public class ModbusController { + + @Autowired + private IModbusInfoService modbusInfoService; + + + @ApiOperation(value = "ModbusInfo模版列表", notes = "设备列表", httpMethod = "POST") + @SaCheckPermission("iot:modbus:list") + @PostMapping("/list") + public Paging getDevices(@Validated @RequestBody PageRequest request) { + return modbusInfoService.selectPageList(request); + } + + + @ApiOperation("新建ModbusInfo") + @SaCheckPermission("iot:modbus:add") + @PostMapping(value = "/add") + @Log(title = "modbusInfo", businessType = BusinessType.INSERT) + public ModbusInfoVo create(@Validated(AddGroup.class) @RequestBody Request request) { + return modbusInfoService.addEntity(request.getData()); + } + + @ApiOperation(value = "编辑ModbusInfo") + @SaCheckPermission("iot:modbus:edit") + @PostMapping("/edit") + @Log(title = "modbusInfo", businessType = BusinessType.UPDATE) + public boolean edit(@Validated(EditGroup.class) @RequestBody Request request) { + return modbusInfoService.updateEntity(request.getData()); + } + + @ApiOperation("查看ModbusInfo详情") + @SaCheckPermission("iot:modbus:query") + @PostMapping(value = "/getDetail") + public ModbusInfoVo getDetail(@RequestBody @Validated Request request) { + return modbusInfoService.getDetail(request.getData()); + } + + @ApiOperation("删除ModbusInfo") + @SaCheckPermission("iot:modbus:remove") + @PostMapping(value = "/deleteModbus") + public boolean deleteProduct(@RequestBody @Validated Request request) { + return modbusInfoService.deleteModbus(request.getData()); + } + + /** + * 导入点位模型 + */ + @ApiOperation(value = "导入点位模型") + @SaCheckPermission("iot:modbus:add") + @PostMapping("/importData") + public String importData(@RequestPart("file") MultipartFile file, @RequestParam("productKey") String productKey) { + if(StrUtil.isBlank(productKey)){ + throw new BizException("缺少productKey"); + } + + return modbusInfoService.importData(file,productKey); + } + @ApiOperation("下载点位模版") + @SaCheckPermission("iot:modbus:query") + @PostMapping("/exportData") + public void exportDeviceTemplate(HttpServletResponse response) { + ExcelUtil.exportExcel(new ArrayList<>(), "点位模版", ModbusThingModelImportVo.class, response); + } + + + @ApiOperation("查看点位物模型") + @SaCheckPermission("iot:modbus:query") + @PostMapping("/getThingModelByProductKey") + public ModbusThingModelVo getThingModelByProductKey(@RequestBody @Validated Request request) { + return modbusInfoService.getThingModelByProductKey(request.getData()); + } + + @ApiOperation("保存点位物模型") + @SaCheckPermission("iot:modbus:edit") + @PostMapping("/thingModel/save") + public boolean saveThingModel(@Validated @RequestBody Request request) { + return modbusInfoService.saveThingModel(request.getData()); + } + + + @ApiOperation("同步点位物模型到产品") + @SaCheckPermission("iot:modbus:edit") + @PostMapping("/syncToProduct") + public boolean syncToProduct(@Validated @RequestBody Request request) { + return modbusInfoService.syncToProduct(request.getData()); + } + + + +} diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dao/ModbusInfoRepository.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dao/ModbusInfoRepository.java new file mode 100644 index 00000000..2fccf679 --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dao/ModbusInfoRepository.java @@ -0,0 +1,15 @@ +package cc.iotkit.modbus.dao; + +import cc.iotkit.modbus.model.TbModbusInfo; +import org.springframework.data.jpa.repository.JpaRepository; + +/** + * @Description: ModbusInfoRepository + * @Author: ZOUZDC + * @Date: 2024/4/29 0:11 + */ +public interface ModbusInfoRepository extends JpaRepository { + + + TbModbusInfo findByProductKey(String productKey); +} diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dao/ModbusThingModelRepository.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dao/ModbusThingModelRepository.java new file mode 100644 index 00000000..b6e938a2 --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dao/ModbusThingModelRepository.java @@ -0,0 +1,14 @@ +package cc.iotkit.modbus.dao; + +import cc.iotkit.modbus.model.TbModbusThingModel; +import org.springframework.data.jpa.repository.JpaRepository; + +/** + * @Description: ModbusInfoRepository + * @Author: ZOUZDC + * @Date: 2024/4/29 0:11 + */ +public interface ModbusThingModelRepository extends JpaRepository { + + TbModbusThingModel findByProductKey(String productKey); +} diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/data/IModbusInfoData.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/data/IModbusInfoData.java new file mode 100644 index 00000000..c76d4bb0 --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/data/IModbusInfoData.java @@ -0,0 +1,14 @@ +package cc.iotkit.modbus.data; + +import cc.iotkit.data.ICommonData; +import cc.iotkit.model.modbus.ModbusInfo; + + +/** + * @Description: ModbusInfo数据接口 + * @Author: ZOUZDC + * @Date: 2024/4/29 0:10 + */ +public interface IModbusInfoData extends ICommonData { + ModbusInfo findByProductKey(String productKey); +} diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/data/IModbusThingModelData.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/data/IModbusThingModelData.java new file mode 100644 index 00000000..74be98fc --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/data/IModbusThingModelData.java @@ -0,0 +1,17 @@ +package cc.iotkit.modbus.data; + +import cc.iotkit.data.ICommonData; +import cc.iotkit.model.modbus.ModbusThingModel; + + +/** + * @Description: ModbusThingModel数据接口 + * @Author: ZOUZDC + * @Date: 2024/5/9 23:36 + */ +public interface IModbusThingModelData extends ICommonData { + + ModbusThingModel findByProductKey(String productKey); + + ModbusThingModel save(ModbusThingModel thingModel); +} diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/data/Impl/ModbusInfoDataImpl.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/data/Impl/ModbusInfoDataImpl.java new file mode 100644 index 00000000..1dfe1c3e --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/data/Impl/ModbusInfoDataImpl.java @@ -0,0 +1,47 @@ +package cc.iotkit.modbus.data.Impl; + +import cc.iotkit.common.utils.MapstructUtils; +import cc.iotkit.data.dao.IJPACommData; +import cc.iotkit.modbus.dao.ModbusInfoRepository; +import cc.iotkit.modbus.data.IModbusInfoData; +import cc.iotkit.modbus.model.TbModbusInfo; +import cc.iotkit.model.modbus.ModbusInfo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Service; + +/** + * @Description: ModbusInfoDataImpl + * @Author: ZOUZDC + * @Date: 2024/4/29 0:11 + */ +@Primary +@Service +public class ModbusInfoDataImpl implements IModbusInfoData, IJPACommData { + + @Autowired + private ModbusInfoRepository modbusInfoRepository; + + + @Override + public JpaRepository getBaseRepository() { + return modbusInfoRepository; + } + + @Override + public Class getJpaRepositoryClass() { + return TbModbusInfo.class; + } + + @Override + public Class getTClass() { + return ModbusInfo.class; + } + + + @Override + public ModbusInfo findByProductKey(String productKey) { + return MapstructUtils.convert(modbusInfoRepository.findByProductKey(productKey), ModbusInfo.class); + } +} diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/data/Impl/ModbusThingModelDataImpl.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/data/Impl/ModbusThingModelDataImpl.java new file mode 100644 index 00000000..1c08867f --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/data/Impl/ModbusThingModelDataImpl.java @@ -0,0 +1,62 @@ +package cc.iotkit.modbus.data.Impl; + +import cc.iotkit.common.utils.JsonUtils; +import cc.iotkit.common.utils.MapstructUtils; +import cc.iotkit.data.dao.IJPACommData; +import cc.iotkit.modbus.dao.ModbusThingModelRepository; +import cc.iotkit.modbus.data.IModbusThingModelData; +import cc.iotkit.modbus.model.TbModbusThingModel; +import cc.iotkit.model.modbus.ModbusThingModel; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Service; + +/** + * @Description: ModbusInfoDataImpl + * @Author: ZOUZDC + * @Date: 2024/5/9 23:36 + */ +@Primary +@Service +public class ModbusThingModelDataImpl implements IModbusThingModelData, IJPACommData { + + @Autowired + private ModbusThingModelRepository modbusThingModelRepository; + + + @Override + public JpaRepository getBaseRepository() { + return modbusThingModelRepository; + } + + @Override + public Class getJpaRepositoryClass() { + return TbModbusThingModel.class; + } + + @Override + public Class getTClass() { + return ModbusThingModel.class; + } + + + @Override + public ModbusThingModel findByProductKey(String productKey) { + TbModbusThingModel tbThingModel = modbusThingModelRepository.findByProductKey(productKey); + ModbusThingModel convert = MapstructUtils.convert(tbThingModel, ModbusThingModel.class); + if (tbThingModel != null && convert != null) { + convert.setModel(JsonUtils.parseObject(tbThingModel.getModel(), ModbusThingModel.Model.class)); + } + return convert; + + } + + @Override + public ModbusThingModel save(ModbusThingModel data) { + TbModbusThingModel to = data.to(TbModbusThingModel.class); + to.setModel(JsonUtils.toJsonString(data.getModel())); + modbusThingModelRepository.save(to); + return data; + } +} diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dto/bo/modbus/ModbusInfoBo.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dto/bo/modbus/ModbusInfoBo.java new file mode 100644 index 00000000..591a043e --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dto/bo/modbus/ModbusInfoBo.java @@ -0,0 +1,34 @@ +package cc.iotkit.modbus.dto.bo.modbus; + +import cc.iotkit.common.api.BaseDto; +import cc.iotkit.model.modbus.ModbusInfo; +import io.github.linpeilie.annotations.AutoMapper; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +@ApiModel(value = "ModbusInfoBo") +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = ModbusInfo.class, reverseConvertGenerate = false) +public class ModbusInfoBo extends BaseDto { + + private static final long serialVersionUID = -1L; + + + @ApiModelProperty(value="id") + private Long id; + + @ApiModelProperty(value="产品名称") + private String name; + + @ApiModelProperty(value="产品Key") + private String productKey; + + @ApiModelProperty(value="说明") + private String remark; + + + } diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dto/bo/modbus/ModbusThingModelBo.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dto/bo/modbus/ModbusThingModelBo.java new file mode 100644 index 00000000..a7721585 --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dto/bo/modbus/ModbusThingModelBo.java @@ -0,0 +1,34 @@ +package cc.iotkit.modbus.dto.bo.modbus; + +import cc.iotkit.common.api.BaseDto; +import cc.iotkit.model.modbus.ModbusThingModel; +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.ReverseAutoMapping; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +@ApiModel(value = "ModbusThingModelBo") +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = ModbusThingModel.class, reverseConvertGenerate = false) +public class ModbusThingModelBo extends BaseDto { + private static final long serialVersionUID = -1L; + + @ApiModelProperty(value = "模型内容") + @Size(max = 65535, message = "模型内容长度不正确") + @AutoMapping(ignore = true) + @ReverseAutoMapping(ignore = true) + private String model; + + @NotBlank(message="产品Key不能为空") + @ApiModelProperty(value = "产品key") + @Size(min = 16, max = 16, message = "产品key长度不正确") + private String productKey; + +} diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dto/vo/modbus/ModbusInfoVo.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dto/vo/modbus/ModbusInfoVo.java new file mode 100644 index 00000000..e3c3d92f --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dto/vo/modbus/ModbusInfoVo.java @@ -0,0 +1,49 @@ +package cc.iotkit.modbus.dto.vo.modbus; + +import cc.iotkit.model.modbus.ModbusInfo; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + + +@ApiModel(value = "ModbusInfoVo") +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = ModbusInfo.class) +public class ModbusInfoVo implements Serializable { + + private static final long serialVersionUID = -1L; + + + @ApiModelProperty(value="id") + private Long id; + + + @ApiModelProperty(value="产品名称") + @ExcelProperty(value = "产品名称") + private String name; + + + @ApiModelProperty(value="产品Key") + @ExcelProperty(value = "产品Key") + private String productKey; + + + @ApiModelProperty(value="说明") + @ExcelProperty(value = "说明") + private String remark; + + @ApiModelProperty(value="创建时间") + @ExcelProperty(value = "创建时间") + private Long createAt; + + + @ApiModelProperty(value="修改时间") + @ExcelProperty(value = "修改时间") + private Long updateAt; +} diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dto/vo/modbus/ModbusThingModelImportVo.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dto/vo/modbus/ModbusThingModelImportVo.java new file mode 100644 index 00000000..46772c23 --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dto/vo/modbus/ModbusThingModelImportVo.java @@ -0,0 +1,60 @@ +package cc.iotkit.modbus.dto.vo.modbus; + +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +import java.io.Serializable; + + +@ApiModel(value = "ModbusThingModel.Property") +@Data +public class ModbusThingModelImportVo implements Serializable { + private static final long serialVersionUID = -1L; + + @ExcelProperty(value = "名称") + private String name; + + @ExcelProperty(value = "标识符") + private String identifier; + + @ExcelProperty(value = "描述") + private String description; + + @ExcelProperty(value = "寄存器类型") + private String regType; + //寄存器地址 + @ExcelProperty(value = "寄存器地址") + private Integer regAddr; + //寄存器数量 + @ExcelProperty(value = "寄存器数量") + private Integer regNum; + /** + * 处理公式 + * [ + * { value: 'AB', }, + * { value: 'BA', }, + * { value: 'AB CD', }, + * { value: 'CD AB', }, + * { value: 'DC BA', }, + * { value: 'BA DC', }, + * ] + */ + @ExcelProperty(value = "处理公式") + private String processor; + + + @ExcelProperty(value = "数据类型") + private String dataType; + + @ExcelProperty(value = "读写模式") + private String accessMode = "rw"; + + @ExcelProperty(value = "单位") + private String unit; + //数据顺序 + @ExcelProperty(value = "数据顺序") + private Integer sort; + + +} diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dto/vo/modbus/ModbusThingModelVo.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dto/vo/modbus/ModbusThingModelVo.java new file mode 100644 index 00000000..d9321c18 --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/dto/vo/modbus/ModbusThingModelVo.java @@ -0,0 +1,29 @@ +package cc.iotkit.modbus.dto.vo.modbus; + +import cc.iotkit.model.modbus.ModbusThingModel; +import io.github.linpeilie.annotations.AutoMapper; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + + +@ApiModel(value = "ModbusThingModelVo") +@Data +@AutoMapper(target = ModbusThingModel.class) +public class ModbusThingModelVo implements Serializable { + private static final long serialVersionUID = -1L; + + @ApiModelProperty(value = "主键") + private String id; + + @ApiModelProperty(value = "模型内容") + private ModbusThingModel.Model model; + + @ApiModelProperty(value = "产品key") + private String productKey; + + @ApiModelProperty(value = "更新时间") + private Long updateAt; +} diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/model/TbModbusInfo.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/model/TbModbusInfo.java new file mode 100644 index 00000000..038e2e8f --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/model/TbModbusInfo.java @@ -0,0 +1,61 @@ +package cc.iotkit.modbus.model; + +import cc.iotkit.model.modbus.ModbusInfo; +import io.github.linpeilie.annotations.AutoMapper; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * @Description: modbus点表信息 + * @Author: ZOUZDC + * @Date: 2024/4/29 0:11 + */ +@Data +@Entity +@Table(name = "modbus_info") +@ApiModel(value = "modbus点表信息") +@AutoMapper(target = ModbusInfo.class) +public class TbModbusInfo { + @Id + @GeneratedValue(generator = "SnowflakeIdGenerator") + @GenericGenerator(name = "SnowflakeIdGenerator", strategy = "cc.iotkit.data.config.id.SnowflakeIdGenerator") + @ApiModelProperty(value = "id") + private Long id; + + /** + * 配置所属用户 + */ + @ApiModelProperty(value = "配置所属用户") + private String uid; + + /** + * 产品名称 + */ + @ApiModelProperty(value = "产品名称") + private String name; + + @ApiModelProperty(value = "productKey") + private String productKey; + + /** + * 说明 + */ + @ApiModelProperty(value = "说明") + private String remark; + + @ApiModelProperty(value = "创建时间") + private Long createAt; + + /** + * 更新时间 + */ + @ApiModelProperty(value = "创建时间") + private Long updateAt; +} diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/model/TbModbusThingModel.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/model/TbModbusThingModel.java new file mode 100644 index 00000000..14b05d4f --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/model/TbModbusThingModel.java @@ -0,0 +1,52 @@ +/* + * +---------------------------------------------------------------------- + * | Copyright (c) 奇特物联 2021-2022 All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed 未经许可不能去掉「奇特物联」相关版权 + * +---------------------------------------------------------------------- + * | Author: xw2sy@163.com + * +---------------------------------------------------------------------- + */ +package cc.iotkit.modbus.model; + +import cc.iotkit.model.modbus.ModbusThingModel; +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.ReverseAutoMapping; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.*; + +/** + * @Description: modbus点表物模型 + * @Author: ZOUZDC + * @Date: 2024/4/28 22:52 + */ +@Data +@Entity +@Table(name = "modbus_thing_model") +@ApiModel(value = "modbus物模型") +@AutoMapper(target = ModbusThingModel.class) +public class TbModbusThingModel { + @Id + @GeneratedValue(generator = "SnowflakeIdGenerator") + @GenericGenerator(name = "SnowflakeIdGenerator", strategy = "cc.iotkit.data.config.id.SnowflakeIdGenerator") + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "产品key") + private String productKey; + + @ApiModelProperty(value = "模型内容") + @Column(columnDefinition = "text") + @AutoMapping(ignore = true) + @ReverseAutoMapping(ignore = true) + private String model; + + @ApiModelProperty(value = "更新时间") + private Long updateAt; + +} diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/service/IModbusInfoService.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/service/IModbusInfoService.java new file mode 100644 index 00000000..f43b04f3 --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/service/IModbusInfoService.java @@ -0,0 +1,34 @@ +package cc.iotkit.modbus.service; + +import cc.iotkit.common.api.PageRequest; +import cc.iotkit.common.api.Paging; +import cc.iotkit.modbus.dto.bo.modbus.ModbusInfoBo; +import cc.iotkit.modbus.dto.bo.modbus.ModbusThingModelBo; +import cc.iotkit.modbus.dto.vo.modbus.ModbusInfoVo; +import cc.iotkit.modbus.dto.vo.modbus.ModbusThingModelVo; +import org.springframework.web.multipart.MultipartFile; + +/** + * @Description: Modbus模版管理 + * @Author: ZOUZDC + * @Date: 2024/4/29 0:11 + */ +public interface IModbusInfoService { + Paging selectPageList(PageRequest request); + + ModbusInfoVo addEntity(ModbusInfoBo data); + + boolean updateEntity(ModbusInfoBo data); + + ModbusInfoVo getDetail(Long data); + + boolean deleteModbus(Long data); + + ModbusThingModelVo getThingModelByProductKey(String data); + + boolean saveThingModel(ModbusThingModelBo data); + + boolean syncToProduct(ModbusThingModelBo data); + + String importData(MultipartFile file, String productKey); +} diff --git a/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/service/impl/ModbusInfoServiceImpl.java b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/service/impl/ModbusInfoServiceImpl.java new file mode 100644 index 00000000..0a4aa54a --- /dev/null +++ b/iot-module/iot-modbus/src/main/java/cc/iotkit/modbus/service/impl/ModbusInfoServiceImpl.java @@ -0,0 +1,234 @@ +package cc.iotkit.modbus.service.impl; + +import cc.iotkit.common.api.PageRequest; +import cc.iotkit.common.api.Paging; +import cc.iotkit.common.enums.ErrCode; +import cc.iotkit.common.exception.BizException; +import cc.iotkit.common.satoken.utils.AuthUtil; +import cc.iotkit.common.utils.JsonUtils; +import cc.iotkit.common.utils.MapstructUtils; +import cc.iotkit.data.manager.IProductData; +import cc.iotkit.manager.dto.bo.product.ProductBo; +import cc.iotkit.manager.service.IProductService; +import cc.iotkit.modbus.data.IModbusInfoData; +import cc.iotkit.modbus.data.IModbusThingModelData; +import cc.iotkit.modbus.dto.bo.modbus.ModbusInfoBo; +import cc.iotkit.modbus.dto.bo.modbus.ModbusThingModelBo; +import cc.iotkit.modbus.dto.vo.modbus.ModbusInfoVo; +import cc.iotkit.modbus.dto.vo.modbus.ModbusThingModelImportVo; +import cc.iotkit.modbus.dto.vo.modbus.ModbusThingModelVo; +import cc.iotkit.modbus.service.IModbusInfoService; +import cc.iotkit.model.modbus.ModbusInfo; +import cc.iotkit.model.modbus.ModbusThingModel; +import cc.iotkit.model.product.Product; +import cn.hutool.core.collection.CollectionUtil; +import com.alibaba.excel.EasyExcel; +import com.github.yitter.idgen.YitIdHelper; +import lombok.SneakyThrows; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * @Description: Modbus模版管理 + * @Author: ZOUZDC + * @Date: 2024/4/29 0:12 + */ +@Service +public class ModbusInfoServiceImpl implements IModbusInfoService { + + + @Autowired + private IModbusInfoData modbusInfoData; + @Autowired + private IModbusThingModelData modbusThingModelData; + + /** + * 如果需要可以直接复写方法,不依赖iot-manager + */ + @Autowired + private IProductService productService; + + @Autowired + @Qualifier("productDataCache") + private IProductData productData; + @Override + public Paging selectPageList(PageRequest request) { + return modbusInfoData.findAll(request.to(ModbusInfo.class)).to(ModbusInfoVo.class); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public ModbusInfoVo addEntity(ModbusInfoBo data) { + ModbusInfo modbusInfo = data.to(ModbusInfo.class); + + ModbusInfo condition = new ModbusInfo(); + condition.setName(data.getName()); + //模板名称不可重复 + ModbusInfo old = modbusInfoData.findOneByCondition(condition); + if (old != null) { + throw new BizException(ErrCode.TEMPLATE_NAME_ALREADY); + } + //productKey在产品中不可重复 + Product oldProduct = productData.findByProductKey(data.getProductKey()); + if (oldProduct != null) { + throw new BizException(ErrCode.PRODUCT_KEY_EXIST); + } + //productKey在物模型中不可重复 + old = modbusInfoData.findByProductKey(data.getProductKey()); + if (old != null) { + throw new BizException(ErrCode.PRODUCT_KEY_EXIST); + } + + modbusInfo.setCreateAt(System.currentTimeMillis()); + modbusInfo.setUpdateAt(modbusInfo.getCreateAt()); + modbusInfo.setUid(AuthUtil.getUserId()); + + modbusInfoData.save(modbusInfo); + + + //生成对应的product + ProductBo productBo = new ProductBo(); + productBo.setProductKey(data.getProductKey()); + productBo.setName(data.getName()); + /** + * [{value:0,label:'网关设备',},{value:1,label:'网关子设备',},{value:2,label:'直连设备'},] + */ + productBo.setNodeType(1); + productBo.setTransparent(true); + productBo.setKeepAliveTime(0L); + productBo.setIsOpenLocate(false); + productService.addEntity(productBo); + + return MapstructUtils.convert(modbusInfo, ModbusInfoVo.class); + } + + @Override + public boolean updateEntity(ModbusInfoBo data) { + ModbusInfo modbusInfo = data.to(ModbusInfo.class); + + ModbusInfo condition = new ModbusInfo(); + condition.setName(data.getName()); + //模板名称不可重复 + ModbusInfo old = modbusInfoData.findOneByCondition(condition); + if (old != null && !Objects.equals(data.getId(), old.getId())) { + throw new BizException(ErrCode.TEMPLATE_NAME_ALREADY); + } + + modbusInfo.setUpdateAt(System.currentTimeMillis()); + + modbusInfoData.save(modbusInfo); + return true; + } + + @Override + public ModbusInfoVo getDetail(Long id) { + return MapstructUtils.convert(modbusInfoData.findById(id), ModbusInfoVo.class); + } + + @Override + public boolean deleteModbus(Long id) { + + ModbusInfo info = modbusInfoData.findById(id); + + Product oldProduct = productData.findByProductKey(info.getProductKey()); + if (oldProduct != null) { + //存在关联产品 + throw new BizException(ErrCode.RELATED_PRODUCTS_EXIST); + } + + modbusInfoData.deleteById(id); + return true; + } + + @Override + public ModbusThingModelVo getThingModelByProductKey(String productKey) { + ModbusThingModel thingModel = modbusThingModelData.findByProductKey(productKey); + return MapstructUtils.convert(thingModel, ModbusThingModelVo.class); + } + + @Override + public boolean saveThingModel(ModbusThingModelBo data) { + String productKey = data.getProductKey(); + + ModbusThingModel thingModel = new ModbusThingModel(YitIdHelper.nextId(), productKey, JsonUtils.parseObject(data.getModel(), ModbusThingModel.Model.class),System.currentTimeMillis()); + return saveThingModel(productKey,thingModel); + } + public boolean saveThingModel(String productKey, ModbusThingModel thingModel) { + + ModbusThingModel oldTm = modbusThingModelData.findByProductKey(productKey); + + //验证物模型合法性 + List properties = thingModel.getModel().getProperties(); + for (ModbusThingModel.Property property : properties) { + //属性标识符合法性校验 + String identifier = property.getIdentifier(); + if (StringUtils.isBlank(identifier)) { + throw new BizException("属性标识符不能为空"); + } + if (!identifier.matches("^[a-zA-Z].*")) { + throw new BizException("属性标识符【" + identifier + "】不合法"); + } + } + if(oldTm!=null){ + thingModel.setId(oldTm.getId()); + } + modbusThingModelData.save(thingModel); + return true; + } + + @Override + public boolean syncToProduct(ModbusThingModelBo data) { + String productKey = data.getProductKey(); + + Product product = productData.findByProductKey(productKey); + if (product == null) { + throw new BizException(ErrCode.PRODUCT_NOT_FOUND); + } + + //ModbusThingModel thingModel = modbusThingModelData.findByProductKey(productKey); + + //同步物模型 + //ThingModelBo tbspModel = new ThingModelBo(); + + //productService.saveThingModel(tbspModel); + + + return true; + } + + @SneakyThrows + @Override + public String importData(MultipartFile file, String productKey) { + + List objects = EasyExcel.read(file.getInputStream()).head(ModbusThingModelImportVo.class).sheet().doReadSync(); + if(CollectionUtil.isEmpty(objects)){ + throw new BizException(ErrCode.DATA_NOT_EXIST); + } + List modbusThingModelArrayList = new ArrayList<>(); + for (ModbusThingModelImportVo vo : objects) { + ModbusThingModel.Property convert = MapstructUtils.convert(vo, ModbusThingModel.Property.class); + modbusThingModelArrayList.add(convert); + } + + ModbusThingModel.Model model = new ModbusThingModel.Model(); + model.setProperties(modbusThingModelArrayList); + + ModbusThingModel modbusThingModel = new ModbusThingModel(); + modbusThingModel.setModel(model ); + + + return this.saveThingModel(productKey, modbusThingModel)?"导入成功":"导入失败"; + + + } + + +} diff --git a/iot-module/pom.xml b/iot-module/pom.xml index 29515c3a..a0b4d164 100644 --- a/iot-module/pom.xml +++ b/iot-module/pom.xml @@ -19,6 +19,7 @@ iot-openapi iot-plugin iot-manager + iot-modbus \ No newline at end of file diff --git a/iot-starter/pom.xml b/iot-starter/pom.xml index 3a25f421..c7128609 100644 --- a/iot-starter/pom.xml +++ b/iot-starter/pom.xml @@ -76,6 +76,11 @@ iot-data-serviceImpl-rdb + + cc.iotkit + iot-modbus + + cc.iotkit @@ -106,7 +111,11 @@ org.springframework.boot spring-boot-starter-web - + + com.mysql + mysql-connector-j + 8.0.33 + org.springframework.boot spring-boot-starter-logging diff --git a/pom.xml b/pom.xml index d2f33d54..39b40b60 100755 --- a/pom.xml +++ b/pom.xml @@ -370,6 +370,12 @@ ${iot-iita-core.version} + + cc.iotkit + iot-modbus + ${project.version} + + cc.iotkit iot-openapi