Merge remote-tracking branch 'origin/V0.5.x-feature-modbus' into V0.5.x

# Conflicts:
#	iot-dao/iot-data-model/src/main/java/cc/iotkit/model/product/ThingModel.java
V0.5.x
jay 2024-05-18 14:39:27 +08:00
commit 2045b802ba
24 changed files with 1349 additions and 2 deletions

View File

@ -3518,4 +3518,48 @@
"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" : [ ]
}]

View File

@ -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<Long>, Serializable {
private Long id;
/**
*
*/
private String uid;
/**
*
*/
private String name;
private String productKey;
/**
*
*/
private String remark;
/**
*
*/
private Long createAt;
/**
*
*/
private Long updateAt;
}

View File

@ -0,0 +1,186 @@
/*
* +----------------------------------------------------------------------
* | 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<Long>, 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<ModbusThingModel.Property> properties;
private List<ModbusThingModel.Service> services;
private List<ModbusThingModel.Event> events;
public Map<String, ModbusThingModel.Service> 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;
// * 处理公式
private String processor;
//数据顺序
/**
* [
* { value: 'AB', },
* { value: 'BA', },
* { value: 'AB CD', },
* { value: 'CD AB', },
* { value: 'DC BA', },
* { value: 'BA DC', },
* ]
*/
private String sort;
private ModbusThingModel.DataType dataType;
private String accessMode = "rw";
// 单位
private String unit;
}
@Data
public static class ProData {
/**
*
* [{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;
// * 处理公式
private String processor;
//数据顺序
/**
* [
* { value: 'AB', },
* { value: 'BA', },
* { value: 'AB CD', },
* { value: 'CD AB', },
* { value: 'DC BA', },
* { value: 'BA DC', },
* ]
*/
private String sort;
}
@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<ModbusThingModel.Parameter> inputData;
private List<ModbusThingModel.Parameter> outputData;
private String name;
}
@Data
public static class Event {
private String identifier;
private List<ModbusThingModel.Parameter> outputData;
private String name;
}
@Data
public static class DataType {
private String type;
private Object specs;
public <T> 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;
}
}
}
}

View File

@ -85,6 +85,7 @@ public class ThingModel extends TenantModel implements Id<Long>, Serializable {
private Long iconId;
// 图标信息
private Icon icon;
private String proData;
}
@Data

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>iot-module</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.5.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>iot-modbus</artifactId>
<dependencies>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-core</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-web</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-log</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-excel</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-tenant</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-data-model</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-doc</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-data-serviceImpl-rdb</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-satoken</artifactId>
</dependency>
<!--====================第三方库===================-->
<dependency>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-manager</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source> <!-- depending on your project -->
<target>${java.version}</target> <!-- depending on your project -->
<encoding>utf8</encoding>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-processor</artifactId>
<version>${mapstruct-plus.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
<!-- other annotation processors -->
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -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<ModbusInfoVo> getDevices(@Validated @RequestBody PageRequest<ModbusInfoBo> 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<ModbusInfoBo> 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<ModbusInfoBo> request) {
return modbusInfoService.updateEntity(request.getData());
}
@ApiOperation("查看ModbusInfo详情")
@SaCheckPermission("iot:modbus:query")
@PostMapping(value = "/getDetail")
public ModbusInfoVo getDetail(@RequestBody @Validated Request<Long> request) {
return modbusInfoService.getDetail(request.getData());
}
@ApiOperation("删除ModbusInfo")
@SaCheckPermission("iot:modbus:remove")
@PostMapping(value = "/deleteModbus")
public boolean deleteProduct(@RequestBody @Validated Request<Long> 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<String> request) {
return modbusInfoService.getThingModelByProductKey(request.getData());
}
@ApiOperation("保存点位物模型")
@SaCheckPermission("iot:modbus:edit")
@PostMapping("/thingModel/save")
public boolean saveThingModel(@Validated @RequestBody Request<ModbusThingModelBo> request) {
return modbusInfoService.saveThingModel(request.getData());
}
@ApiOperation("同步点位物模型到产品")
@SaCheckPermission("iot:modbus:edit")
@PostMapping("/syncToProduct")
public boolean syncToProduct(@Validated @RequestBody Request<ModbusThingModelBo> request) {
return modbusInfoService.syncToProduct(request.getData());
}
}

View File

@ -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, Long> {
TbModbusInfo findByProductKey(String productKey);
}

View File

@ -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, Long> {
TbModbusThingModel findByProductKey(String productKey);
}

View File

@ -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, Long> {
ModbusInfo findByProductKey(String productKey);
}

View File

@ -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, Long> {
ModbusThingModel findByProductKey(String productKey);
ModbusThingModel save(ModbusThingModel thingModel);
}

View File

@ -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<ModbusInfo, Long> {
@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);
}
}

View File

@ -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<ModbusThingModel, Long> {
@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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 String sort;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<ModbusInfoVo> selectPageList(PageRequest<ModbusInfoBo> 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);
}

View File

@ -0,0 +1,261 @@
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.dto.bo.thingmodel.ThingModelBo;
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 cc.iotkit.model.product.ThingModel;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
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;
import java.util.stream.Collectors;
/**
* @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<ModbusInfoVo> selectPageList(PageRequest<ModbusInfoBo> request) {
return modbusInfoData.findAll(request.to(ModbusInfo.class)).to(ModbusInfoVo.class);
}
@Override
@Transactional
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
@Transactional
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<ModbusThingModel.Property> 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 modbusThingModel = modbusThingModelData.findByProductKey(productKey);
ThingModel.Model model = new ThingModel.Model();
//将Property私有属性封装到proData中
List<ThingModel.Property> properties=new ArrayList<>();
if(CollectionUtil.isNotEmpty(modbusThingModel.getModel().getProperties())){
properties = modbusThingModel.getModel().getProperties().stream().map(p -> {
ThingModel.Property property = BeanUtil.copyProperties(p, ThingModel.Property.class);
property.setProData(JSONUtil.toJsonStr(BeanUtil.copyProperties(p, ModbusThingModel.ProData.class)));
return property;
}).collect(Collectors.toList());
}
model.setProperties(properties);
//services events 数据封装
ThingModelBo tbspModel = new ThingModelBo();
tbspModel.setProductKey(productKey);
tbspModel.setModel(JSONUtil.toJsonStr(model));
productService.saveThingModel(tbspModel);
return true;
}
@SneakyThrows
@Override
public String importData(MultipartFile file, String productKey) {
List<ModbusThingModelImportVo> objects = EasyExcel.read(file.getInputStream()).head(ModbusThingModelImportVo.class).sheet().doReadSync();
if(CollectionUtil.isEmpty(objects)){
throw new BizException(ErrCode.DATA_NOT_EXIST);
}
List<ModbusThingModel.Property> 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)?"导入成功":"导入失败";
}
}

View File

@ -19,6 +19,7 @@
<module>iot-openapi</module>
<module>iot-plugin</module>
<module>iot-manager</module>
<module>iot-modbus</module>
</modules>
</project>

View File

@ -76,6 +76,11 @@
<artifactId>iot-data-serviceImpl-rdb</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-modbus</artifactId>
</dependency>
<!--打开注释 启用es数据库-->
<dependency>
<groupId>cc.iotkit</groupId>
@ -106,7 +111,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>

View File

@ -370,6 +370,12 @@
<version>${iot-iita-core.version}</version>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-modbus</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-openapi</artifactId>