refactor 设备服务

V0.5.x
jay 2023-05-31 17:44:32 +08:00
parent dfbdf118db
commit f152e95010
18 changed files with 1275 additions and 297 deletions

View File

@ -1,6 +1,8 @@
package cc.iotkit.data.dao; package cc.iotkit.data.dao;
import cc.iotkit.data.model.TbDeviceInfo; import cc.iotkit.data.model.TbDeviceInfo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QuerydslPredicateExecutor; import org.springframework.data.querydsl.QuerydslPredicateExecutor;

View File

@ -153,7 +153,7 @@ public class DeviceInfoDataImpl implements IDeviceInfoData {
@Override @Override
public List<DeviceInfo> findByParentId(String parentId) { public List<DeviceInfo> findByParentId(String parentId) {
return parseVoToDto(deviceInfoRepository.findByParentId(parentId)); return parseVoToDto(deviceInfoRepository.findByParentId(parentId ));
} }
@Override @Override

View File

@ -9,24 +9,24 @@
*/ */
package cc.iotkit.manager.controller; package cc.iotkit.manager.controller;
import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Request;
import cc.iotkit.common.constant.Constants; import cc.iotkit.common.constant.Constants;
import cc.iotkit.common.enums.ErrCode; import cc.iotkit.common.enums.ErrCode;
import cc.iotkit.common.exception.BizException; import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.satoken.utils.AuthUtil; import cc.iotkit.common.satoken.utils.AuthUtil;
import cc.iotkit.common.utils.DeviceUtil;
import cc.iotkit.common.utils.ReflectUtil; import cc.iotkit.common.utils.ReflectUtil;
import cc.iotkit.common.utils.UniqueIdUtil; import cc.iotkit.common.utils.UniqueIdUtil;
import cc.iotkit.comps.service.DeviceBehaviourService; import cc.iotkit.manager.dto.bo.device.*;
import cc.iotkit.data.manager.IDeviceConfigData; import cc.iotkit.manager.dto.bo.deviceconfig.DeviceConfigAddBo;
import cc.iotkit.data.manager.IDeviceGroupData; import cc.iotkit.manager.dto.bo.devicegroup.DeviceAddGroupBo;
import cc.iotkit.data.manager.IDeviceInfoData; import cc.iotkit.manager.dto.bo.devicegroup.DeviceGroupBo;
import cc.iotkit.data.manager.IProductData; import cc.iotkit.manager.dto.bo.thingmodel.ThingModelMessageBo;
import cc.iotkit.manager.dto.vo.deviceconfig.DeviceConfigVo;
import cc.iotkit.manager.dto.vo.devicegroup.DeviceGroupVo;
import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoVo;
import cc.iotkit.manager.dto.vo.thingmodel.ThingModelVo; import cc.iotkit.manager.dto.vo.thingmodel.ThingModelVo;
import cc.iotkit.manager.model.query.DeviceQuery; import cc.iotkit.manager.service.*;
import cc.iotkit.manager.service.DataOwnerService;
import cc.iotkit.manager.service.DeferredDataConsumer;
import cc.iotkit.manager.service.DeviceService;
import cc.iotkit.manager.service.IProductService;
import cc.iotkit.model.InvokeResult; import cc.iotkit.model.InvokeResult;
import cc.iotkit.common.api.Paging; import cc.iotkit.common.api.Paging;
import cc.iotkit.model.device.DeviceConfig; import cc.iotkit.model.device.DeviceConfig;
@ -34,19 +34,11 @@ import cc.iotkit.model.device.DeviceGroup;
import cc.iotkit.model.device.DeviceInfo; import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.device.message.DeviceProperty; import cc.iotkit.model.device.message.DeviceProperty;
import cc.iotkit.model.device.message.ThingModelMessage; import cc.iotkit.model.device.message.ThingModelMessage;
import cc.iotkit.model.product.Product; import io.swagger.annotations.*;
import cc.iotkit.model.product.ThingModel;
import cc.iotkit.temporal.IDevicePropertyData;
import cc.iotkit.temporal.IThingModelMessageData;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.validation.annotation.Validated;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.context.request.async.DeferredResult;
@ -63,32 +55,12 @@ public class DeviceController {
@Autowired @Autowired
IProductService productService; IProductService productService;
@Autowired @Autowired
private DeviceService deviceService; private DeviceService deviceService;
@Autowired @Autowired
@Qualifier("deviceInfoDataCache") private IDeviceService deviceServiceImpl;
private IDeviceInfoData deviceInfoData;
@Autowired
@Qualifier("productDataCache")
private IProductData productData;
@Autowired
private DataOwnerService dataOwnerService;
@Autowired
private ProductController productController;
@Lazy
@Autowired
private IThingModelMessageData thingModelMessageData;
@Lazy
@Autowired
private IDevicePropertyData devicePropertyData;
@Autowired
private DeviceBehaviourService behaviourService;
@Autowired
DeferredDataConsumer deferredDataConsumer;
@Autowired
private IDeviceGroupData deviceGroupData;
@Autowired
private IDeviceConfigData deviceConfigData;
@ApiOperation(value = "服务调用", notes = "服务调用", httpMethod = "POST") @ApiOperation(value = "服务调用", notes = "服务调用", httpMethod = "POST")
@ApiImplicitParams({ @ApiImplicitParams({
@ -132,349 +104,195 @@ public class DeviceController {
} }
@ApiOperation(value = "设备列表", notes = "设备列表", httpMethod = "POST") @ApiOperation(value = "设备列表", notes = "设备列表", httpMethod = "POST")
@ApiImplicitParams({ @PostMapping("/list")
@ApiImplicitParam(name = "size", value = "长度", dataTypeClass = Integer.class, paramType = "path"), public Paging<DeviceInfo> getDevices(@Validated @RequestBody PageRequest<DeviceQueryBo> pageRequest) {
@ApiImplicitParam(name = "page", value = "页数", dataTypeClass = Integer.class, paramType = "path")
})
@PostMapping("/list/{size}/{page}")
public Paging<DeviceInfo> getDevices(
@PathVariable("size") int size,
@PathVariable("page") int page,
@RequestBody DeviceQuery query) {
String uid = "";
String subUid = "";
if (!AuthUtil.isAdmin()) {
//客户端用户使用绑定子用户查询
if (AuthUtil.isClientUser()) {
subUid = AuthUtil.getUserId();
} else {
uid = AuthUtil.getUserId();
}
}
String pk = query.getProductKey(); return deviceServiceImpl.getDevices(pageRequest);
//关键字查询
String keyword = query.getKeyword();
String group = query.getGroup();
String state = query.getState();
return deviceInfoData.findByConditions(uid, subUid, pk, group,
state, keyword, page, size);
} }
@ApiOperation(value = "创建设备", notes = "创建设备", httpMethod = "POST") @ApiOperation(value = "创建设备")
@ApiImplicitParams({ @PostMapping("/add")
@ApiImplicitParam(name = "productKey", value = "产品key", dataTypeClass = String.class, paramType = "form"), public boolean createDevice(@RequestBody @Validated Request<DeviceInfoBo> bo) {
@ApiImplicitParam(name = "deviceName", value = "设备名称", dataTypeClass = String.class, paramType = "form"), return deviceServiceImpl.addDevice(bo.getData());
@ApiImplicitParam(name = "parentId", value = "父设备ID", dataTypeClass = String.class, paramType = "form")
})
@PostMapping("/create")
public void createDevice(String productKey, String deviceName, String parentId) {
Product product = productData.findById(productKey);
if (product == null) {
throw new BizException(ErrCode.PRODUCT_NOT_FOUND);
}
//生成设备密钥
String chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
int maxPos = chars.length();
StringBuilder secret = new StringBuilder();
for (var i = 0; i < 16; i++) {
secret.append(chars.charAt((int) Math.floor(Math.random() * maxPos)));
}
DeviceInfo device = new DeviceInfo();
device.setId(DeviceUtil.newDeviceId(deviceName));
device.setUid(product.getUid());
device.setDeviceId(device.getId());
device.setProductKey(productKey);
device.setDeviceName(deviceName);
device.setSecret(secret.toString());
device.setState(new DeviceInfo.State(false, null, null));
device.setCreateAt(System.currentTimeMillis());
if (StringUtils.isNotBlank(parentId)) {
device.setParentId(parentId);
}
deviceInfoData.save(device);
} }
@ApiOperation(value = "获取子设备", notes = "获取子设备", httpMethod = "GET") @ApiOperation(value = "获取子设备", notes = "获取子设备", httpMethod = "GET")
@ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class, paramType = "form") @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class, paramType = "form")
@GetMapping("/{deviceId}/children") @PostMapping("/children/list")
public List<DeviceInfo> getChildren(@PathVariable("deviceId") String deviceId) { public List<DeviceInfoVo> getChildren(@Validated @RequestBody PageRequest<String> request) {
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId); String deviceId = request.getData();
if (deviceInfo == null) {
throw new BizException(ErrCode.DEVICE_NOT_FOUND);
}
dataOwnerService.checkOwner(deviceInfo); return deviceServiceImpl.selectChildrenPageList(deviceId);
return deviceInfoData.findByParentId(deviceId);
} }
@GetMapping("/parentDevices") @ApiOperation("获取网关")
@PostMapping("/parentDevices")
public List<Map<String, Object>> getParentDevices() { public List<Map<String, Object>> getParentDevices() {
String uid = ""; return deviceServiceImpl.getParentDevices();
if (!AuthUtil.isAdmin()) {
uid = AuthUtil.getUserId();
}
return deviceInfoData.findByProductNodeType(uid);
} }
@GetMapping(Constants.API_DEVICE.DETAIL) @ApiOperation("获取设备详情")
@PostMapping(Constants.API_DEVICE.DETAIL)
public DeviceInfo getDetail(@PathVariable("deviceId") String deviceId) { public DeviceInfo getDetail(@PathVariable("deviceId") String deviceId) {
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId); return deviceServiceImpl.getDetail(deviceId);
dataOwnerService.checkOwner(deviceInfo);
deviceInfo.setProperty(deviceInfoData.getProperties(deviceId));
return deviceInfo;
} }
@GetMapping("/{pk}/{dn}") @ApiOperation("获取设备详情")
@PostMapping("/{pk}/{dn}")
public DeviceInfo getByPkDn(@PathVariable("pk") String pk, public DeviceInfo getByPkDn(@PathVariable("pk") String pk,
@PathVariable("dn") String dn) { @PathVariable("dn") String dn) {
return dataOwnerService.checkOwner( return deviceServiceImpl.getByPkDn(pk, dn);
deviceInfoData.findByProductKeyAndDeviceName(pk, dn));
} }
@PostMapping("/{deviceId}/delete") @ApiOperation("删除设备")
public void deleteDevice(@PathVariable("deviceId") String deviceId) { @PostMapping("/delete")
deviceId = getDetail(deviceId).getDeviceId(); public boolean deleteDevice(@Validated @RequestBody Request<String> request) {
deviceInfoData.deleteById(deviceId); return deviceServiceImpl.deleteDevice(request.getData());
} }
@PostMapping("/{deviceId}/logs/{size}/{page}") @ApiOperation("设备物模型日志")
public Paging<ThingModelMessage> logs( @PostMapping("/deviceLogs/list")
@PathVariable("deviceId") String deviceId, public Paging<ThingModelMessage> logs(@Validated @RequestBody PageRequest<DeviceLogQueryBo> request) {
@PathVariable("size") int size, return deviceServiceImpl.logs(request);
@PathVariable("page") int page,
String type, String identifier) {
return thingModelMessageData.findByTypeAndIdentifier(deviceId, type, identifier, page, size);
} }
@GetMapping("/{deviceId}/property/{name}/{start}/{end}") @ApiOperation("设备属性日志")
public List<DeviceProperty> getPropertyHistory( @PostMapping("/deviceProperty/log/list")
@PathVariable("deviceId") String deviceId, public List<DeviceProperty> getPropertyHistory(@Validated @RequestBody
@PathVariable("name") String name, Request<DevicePropertyLogQueryBo> query) {
@PathVariable("start") long start, DevicePropertyLogQueryBo data = query.getData();
@PathVariable("end") long end) { String deviceId = data.getDeviceId();
return devicePropertyData.findDevicePropertyHistory(deviceId, name, start, end); String name = data.getName();
long start = data.getStart();
long end = data.getEnd();
return deviceServiceImpl.getPropertyHistory(deviceId, name, start, end);
} }
@PostMapping("/{deviceId}/unbind") @ApiOperation("设备解绑")
public void unbindDevice(@PathVariable("deviceId") String deviceId) { @PostMapping("/unbind")
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId); public boolean unbindDevice(@Validated @RequestBody Request<String> request) {
dataOwnerService.checkOwner(deviceInfo); return deviceServiceImpl.unbindDevice(request.getData());
deviceService.unbindDevice(deviceId);
} }
@GetMapping("/{deviceId}/thingModel") @ApiOperation("获取设备物模型")
public ThingModelVo getThingModel(@PathVariable("deviceId") String deviceId) { @PostMapping("/getThingModel")
public ThingModelVo getThingModel(@Validated @RequestBody Request<String> request) {
String deviceId = request.getData();
DeviceInfo deviceInfo = getDetail(deviceId); DeviceInfo deviceInfo = getDetail(deviceId);
return productService.getThingModelByProductKey(deviceInfo.getProductKey()); return productService.getThingModelByProductKey(deviceInfo.getProductKey());
} }
@PostMapping("/{deviceId}/tag/add") @PostMapping("/tag/add")
public void addTag(@PathVariable("deviceId") String deviceId, public boolean addTag(@Validated @RequestBody Request<DeviceTagAddBo> bo) {
DeviceInfo.Tag tag) { return deviceServiceImpl.addTag(bo.getData());
DeviceInfo device = deviceInfoData.findByDeviceId(deviceId);
dataOwnerService.checkOwner(device);
deviceInfoData.updateTag(deviceId, tag);
} }
@PostMapping("/{deviceId}/simulateSend") @ApiOperation("模拟设备上报")
public void simulateSend( @PostMapping("/simulateSend")
@PathVariable("deviceId") String deviceId, public boolean simulateSend(
@RequestBody ThingModelMessage message) { @Validated @RequestBody Request<ThingModelMessageBo> bo) {
DeviceInfo device = deviceInfoData.findByDeviceId(deviceId); ThingModelMessage message = bo.getData().to(ThingModelMessage.class);
dataOwnerService.checkOwner(device); return deviceServiceImpl.simulateSend(message);
message.setMid(UniqueIdUtil.newRequestId());
message.setOccurred(System.currentTimeMillis());
message.setTime(System.currentTimeMillis());
behaviourService.reportMessage(message);
} }
/** /**
* *
*/ */
@GetMapping("/{deviceId}/consumer/{clientId}") @PostMapping("/{deviceId}/consumer/{clientId}")
public DeferredResult<ThingModelMessage> consumerDeviceInfo( public DeferredResult<ThingModelMessage> consumerDeviceInfo(
@PathVariable("deviceId") String deviceId, @PathVariable("deviceId") String deviceId,
@PathVariable("clientId") String clientId @PathVariable("clientId") String clientId
) { ) {
String uid = AuthUtil.getUserId();
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId);
dataOwnerService.checkOwner(deviceInfo);
//按用户+客户端ID订阅 return deviceServiceImpl.addConsumer(deviceId, clientId);
return deferredDataConsumer.newConsumer(uid + clientId,
Constants.HTTP_CONSUMER_DEVICE_INFO_TOPIC + deviceId);
} }
/** /**
* *
*/ */
@PostMapping("/groups/{size}/{page}") @PostMapping("/groups/list")
public Paging<DeviceGroup> getDevices( public Paging<DeviceGroupVo> getDeviceGroups(
@PathVariable("size") int size, @Validated @RequestBody PageRequest<DeviceGroupBo> pageRequest) {
@PathVariable("page") int page, return deviceServiceImpl.selectGroupPageList(pageRequest);
String name
) {
return deviceGroupData.findByNameLike(name, page, size);
} }
/** /**
* *
*/ */
@ApiOperation(value = "添加设备分组")
@PostMapping("/group/add") @PostMapping("/group/add")
public void addGroup(DeviceGroup group) { public boolean addGroup(@Validated @RequestBody Request<DeviceGroupBo> group) {
group.setUid(AuthUtil.getUserId()); return deviceServiceImpl.addGroup(group.getData().to(DeviceGroup.class));
if (deviceGroupData.findById(group.getId()) != null) {
throw new BizException(ErrCode.GROUP_ALREADY);
}
deviceGroupData.save(group);
} }
/** /**
* *
*/ */
@PostMapping("/group/save") @ApiOperation(value = "修改设备分组")
public void saveGroup(DeviceGroup group) { @PostMapping("/group/edit")
DeviceGroup dbGroup = deviceGroupData.findById(group.getId()); public boolean editGroup(@RequestBody @Validated Request<DeviceGroupBo> bo) {
if (dbGroup == null) { return deviceServiceImpl.updateGroup(bo.getData());
throw new BizException(ErrCode.GROUP_NOT_FOUND);
}
dataOwnerService.checkOwner(dbGroup);
ReflectUtil.copyNoNulls(group, dbGroup);
deviceGroupData.save(dbGroup);
//更新设备中的组信息
deviceInfoData.updateGroup(dbGroup.getId(), new DeviceInfo.Group(dbGroup.getId(), dbGroup.getName()));
} }
/** /**
* *
*/ */
@DeleteMapping("/group/delete/{id}") @ApiOperation(value = "删除分组")
public void deleteGroup(@PathVariable("id") String id) { @DeleteMapping("/group/delete")
DeviceGroup group = deviceGroupData.findById(id); public boolean deleteGroup(@Validated @RequestBody Request<String> request) {
if (group == null) { String id = request.getData();
throw new BizException(ErrCode.GROUP_NOT_FOUND); return deviceServiceImpl.deleteGroup(id);
}
dataOwnerService.checkOwner(group);
//删除分组
deviceGroupData.deleteById(id);
//移除设备信息中的分组
deviceInfoData.removeGroup(group.getId());
} }
/** /**
* *
*/ */
@PostMapping("/group/clear/{id}") @ApiOperation(value = "清空组下所有设备")
public void clearGroup(@PathVariable("id") String id) { @PostMapping("/group/clear")
DeviceGroup group = deviceGroupData.findById(id); public boolean clearGroup(@Validated @RequestBody Request<String> request) {
if (group == null) { String id = request.getData();
throw new BizException(ErrCode.GROUP_NOT_FOUND); return deviceServiceImpl.clearGroup(id);
}
dataOwnerService.checkOwner(group);
//设备数量清零
group.setDeviceQty(0);
deviceGroupData.save(group);
//移除设备信息中的分组
deviceInfoData.removeGroup(group.getId());
} }
/** /**
* *
*/ */
@PostMapping("/group/addDevices/{group}") @ApiOperation(value = "添加设备到组")
public void addToGroup(@PathVariable("group") String group, @RequestBody List<String> devices) { @PostMapping("/group/addDevices")
DeviceGroup deviceGroup = deviceGroupData.findById(group); public boolean addToGroup(@Validated @RequestBody Request<DeviceAddGroupBo> bo) {
if (deviceGroup == null) { return deviceServiceImpl.addDevice2Group(bo.getData());
throw new BizException(ErrCode.GROUP_NOT_FOUND);
}
dataOwnerService.checkOwner(deviceGroup);
for (String device : devices) {
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(device);
if (deviceInfo == null) {
continue;
}
dataOwnerService.checkOwner(deviceInfo);
//添加设备到组
deviceInfoData.addToGroup(device, new DeviceInfo.Group(group, deviceGroup.getName()));
}
//统计组下设备数量
long qty = deviceInfoData.countByGroupId(group);
//更新组信息
deviceGroup.setDeviceQty((int) qty);
deviceGroupData.save(deviceGroup);
} }
/** /**
* *
*/ */
@PostMapping("/group/removeDevices/{group}") @ApiOperation(value = "将设备从组中移除")
public void removeDevices(@PathVariable("group") String group, @RequestBody List<String> devices) { @PostMapping("/group/removeDevices")
DeviceGroup deviceGroup = deviceGroupData.findById(group); public boolean removeDevices(@Validated @RequestBody Request<DeviceAddGroupBo> bo) {
if (deviceGroup == null) { DeviceAddGroupBo data = bo.getData();
throw new BizException(ErrCode.GROUP_NOT_FOUND); return deviceServiceImpl.removeDevices(data.getGroup(), data.getDevices());
}
dataOwnerService.checkOwner(deviceGroup);
for (String device : devices) {
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(device);
if (deviceInfo == null) {
continue;
}
dataOwnerService.checkOwner(deviceInfo);
//删除设备所在组
deviceInfoData.removeGroup(device, group);
}
//统计组下设备数量
long qty = deviceInfoData.countByGroupId(group);
//更新组信息
deviceGroup.setDeviceQty((int) qty);
deviceGroupData.save(deviceGroup);
} }
/** /**
* *
*/ */
@PostMapping("/config/{deviceId}/save") @ApiOperation(value = "保存设备配置")
public void saveConfig(@PathVariable("deviceId") String deviceId, String config) { @PostMapping("/config/save")
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId); public boolean saveConfig(@Validated @RequestBody Request<DeviceConfigAddBo> request) {
dataOwnerService.checkOwner(deviceInfo); DeviceConfig data = request.getData().to(DeviceConfig.class);
return deviceServiceImpl.saveConfig(data);
DeviceConfig deviceConfig = deviceConfigData.findByDeviceId(deviceId);
if (deviceConfig == null) {
deviceConfig = DeviceConfig.builder()
.deviceId(deviceId)
.deviceName(deviceInfo.getDeviceName())
.productKey(deviceInfo.getProductKey())
.config(config)
.createAt(System.currentTimeMillis())
.build();
} else {
deviceConfig.setConfig(config);
}
deviceConfigData.save(deviceConfig);
} }
/** /**
* *
*/ */
@GetMapping("/config/{deviceId}/get") @ApiOperation(value = "获取设备配置")
public DeviceConfig getConfig(@PathVariable("deviceId") String deviceId) { @PostMapping("/config/get")
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId); public DeviceConfigVo getConfig(@Validated @RequestBody Request<String> request) {
dataOwnerService.checkOwner(deviceInfo); String deviceId = request.getData();
return deviceConfigData.findByDeviceId(deviceId); return deviceServiceImpl.getConfig(deviceId);
} }
/** /**

View File

@ -0,0 +1,74 @@
package cc.iotkit.manager.dto.bo.device;
import cc.iotkit.model.device.DeviceInfo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.Size;
import org.springframework.format.annotation.DateTimeFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
import cc.iotkit.common.api.BaseDto;
import cc.iotkit.common.validate.AddGroup;
import cc.iotkit.common.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ApiModel(value = "DeviceInfoBo")
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = DeviceInfo.class, reverseConvertGenerate = false)
public class DeviceInfoBo extends BaseDto {
private static final long serialVersionUID = -1L;
@ApiModelProperty(value="创建时间")
private Long createAt;
@ApiModelProperty(value="设备id")
@Size(max = 255, message = "设备id长度不正确")
private String deviceId;
@ApiModelProperty(value="设备名称")
@Size(max = 255, message = "设备名称长度不正确")
private String deviceName;
@ApiModelProperty(value="设备类型")
@Size(max = 255, message = "设备类型长度不正确")
private String model;
@ApiModelProperty(value="设备离线时间")
private Long offlineTime;
@ApiModelProperty(value="设备在线时间")
private Long onlineTime;
@ApiModelProperty(value="父级id")
@Size(max = 255, message = "父级id长度不正确")
private String parentId;
@ApiModelProperty(value="产品key")
@Size(max = 255, message = "产品key长度不正确")
private String productKey;
@ApiModelProperty(value="设备描述")
@Size(max = 255, message = "设备描述长度不正确")
private String secret;
@ApiModelProperty(value="设备状态")
@Size(max = 255, message = "设备状态长度不正确")
private String state;
@ApiModelProperty(value="用户id")
@Size(max = 255, message = "用户id长度不正确")
private String uid;
}

View File

@ -0,0 +1,37 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.manager.dto.bo.device;
import cc.iotkit.common.api.BaseDto;
import cc.iotkit.manager.model.vo.DeviceLog;
import cc.iotkit.model.device.DeviceInfo;
import io.github.linpeilie.annotations.AutoMapper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.web.bind.annotation.PathVariable;
@ApiModel(value = "DeviceLogQueryBo")
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = DeviceLog.class, reverseConvertGenerate = false)
public class DeviceLogQueryBo extends BaseDto {
@ApiModelProperty(value="设备id")
private String deviceId;
@ApiModelProperty(value="类型")
private String type;
@ApiModelProperty(value="属性名")
private String identifier;
}

View File

@ -0,0 +1,32 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.manager.dto.bo.device;
import cc.iotkit.common.api.BaseDto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ApiModel(value = "DevicePropertiesLogQueryBo")
@Data
@EqualsAndHashCode(callSuper = true)
public class DevicePropertyLogQueryBo extends BaseDto {
@ApiModelProperty(value="设备id")
private String deviceId;
@ApiModelProperty(value="属性名称")
private String name;
@ApiModelProperty(value="开始时间")
private long start;
@ApiModelProperty(value="结束时间")
private long end;
}

View File

@ -0,0 +1,64 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.manager.dto.bo.device;
import cc.iotkit.common.api.BaseDto;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.product.Category;
import io.github.linpeilie.annotations.AutoMapper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ApiModel(value = "DeviceQueryBo")
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = DeviceInfo.class, reverseConvertGenerate = false)
public class DeviceQueryBo extends BaseDto {
@ApiModelProperty(value="关键字")
private String keyword;
@ApiModelProperty(value="分组")
private String group;
@ApiModelProperty(value="设备id")
@Size(max = 255, message = "设备id长度不正确")
private String deviceId;
@ApiModelProperty(value="设备名称")
@Size(max = 255, message = "设备名称长度不正确")
private String deviceName;
@ApiModelProperty(value="设备类型")
@Size(max = 255, message = "设备类型长度不正确")
private String model;
@ApiModelProperty(value="父级id")
@Size(max = 255, message = "父级id长度不正确")
private String parentId;
@ApiModelProperty(value="产品key")
@Size(max = 255, message = "产品key长度不正确")
private String productKey;
@ApiModelProperty(value="设备状态")
@Size(max = 255, message = "设备状态长度不正确")
private String state;
@ApiModelProperty(value="用户id")
@Size(max = 255, message = "用户id长度不正确")
private String uid;
}

View File

@ -0,0 +1,40 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.manager.dto.bo.device;
import cc.iotkit.common.api.BaseDto;
import cc.iotkit.model.device.DeviceInfo;
import io.github.linpeilie.annotations.AutoMapper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ApiModel(value = "DeviceTagAddBo")
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = DeviceInfo.Tag.class, reverseConvertGenerate = false)
public class DeviceTagAddBo extends BaseDto {
@ApiModelProperty(value="设备")
private String deviceId;
@ApiModelProperty(value="tag id")
private String id;
@ApiModelProperty(value="tag名称")
private String name;
@ApiModelProperty(value="tag值")
private String value;
}

View File

@ -0,0 +1,31 @@
package cc.iotkit.manager.dto.bo.deviceconfig;
import cc.iotkit.common.api.BaseDto;
import cc.iotkit.model.device.DeviceConfig;
import io.github.linpeilie.annotations.AutoMapper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ApiModel(value = "DeviceConfigAddBo")
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = DeviceConfig.class, reverseConvertGenerate = false)
public class DeviceConfigAddBo extends BaseDto {
private static final long serialVersionUID = -1L;
@ApiModelProperty(value = "设备配置json内容")
@Size(max = 65535, message = "设备配置json内容长度不正确")
private String config;
@ApiModelProperty(value = "设备id")
@Size(max = 255, message = "设备id长度不正确")
private String deviceId;
}

View File

@ -0,0 +1,53 @@
package cc.iotkit.manager.dto.bo.deviceconfig;
import cc.iotkit.model.device.DeviceConfig;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import jakarta.validation.constraints.Size;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
import cc.iotkit.common.api.BaseDto;
import cc.iotkit.common.validate.AddGroup;
import cc.iotkit.common.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ApiModel(value = "DeviceConfigBo")
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = DeviceConfig.class, reverseConvertGenerate = false)
public class DeviceConfigBo extends BaseDto {
private static final long serialVersionUID = -1L;
@ApiModelProperty(value = "设备配置json内容")
@Size(max = 65535, message = "设备配置json内容长度不正确")
private String config;
@ApiModelProperty(value = "创建时间")
private Long createAt;
@ApiModelProperty(value = "设备id")
@Size(max = 255, message = "设备id长度不正确")
private String deviceId;
@ApiModelProperty(value = "设备名称")
@Size(max = 255, message = "设备名称长度不正确")
private String deviceName;
@ApiModelProperty(value = "产品key")
@Size(max = 255, message = "产品key长度不正确")
private String productKey;
}

View File

@ -0,0 +1,30 @@
package cc.iotkit.manager.dto.bo.devicegroup;
import cc.iotkit.common.api.BaseDto;
import cc.iotkit.model.device.DeviceGroup;
import io.github.linpeilie.annotations.AutoMapper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
@ApiModel(value = "DeviceAddGroupBo")
@Data
@EqualsAndHashCode(callSuper = true)
public class DeviceAddGroupBo extends BaseDto {
private static final long serialVersionUID = -1L;
@ApiModelProperty("组id")
private String group;
@ApiModelProperty("设备列表")
private List<String> devices;
}

View File

@ -0,0 +1,55 @@
package cc.iotkit.manager.dto.bo.devicegroup;
import cc.iotkit.model.device.DeviceGroup;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.NotNull;
import org.springframework.format.annotation.DateTimeFormat;
import jakarta.validation.constraints.Size;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
import cc.iotkit.common.api.BaseDto;
import cc.iotkit.common.validate.AddGroup;
import cc.iotkit.common.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ApiModel(value = "DeviceGroupBo")
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = DeviceGroup.class, reverseConvertGenerate = false)
public class DeviceGroupBo extends BaseDto {
private static final long serialVersionUID = -1L;
@ApiModelProperty(value = "创建时间")
@NotNull(message = "创建时间不能为空")
private Long createAt;
@ApiModelProperty(value = "设备数量")
@NotNull(message = "设备数量不能为空")
private Integer deviceQty;
@ApiModelProperty(value = "设备组名称")
@Size(max = 255, message = "设备组名称长度不正确")
private String name;
@ApiModelProperty(value = "分组说明")
@Size(max = 255, message = "分组说明长度不正确")
private String remark;
@ApiModelProperty(value = "所属用户")
@Size(max = 255, message = "所属用户长度不正确")
private String uid;
}

View File

@ -0,0 +1,88 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.manager.dto.bo.thingmodel;
import cc.iotkit.common.api.BaseDto;
import cc.iotkit.model.device.message.ThingModelMessage;
import cc.iotkit.model.product.ThingModel;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.HashMap;
import java.util.Map;
/**
*
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@AutoMapper(target = ThingModelMessage.class, reverseConvertGenerate = false)
public class ThingModelMessageBo extends BaseDto {
private String id;
private String mid;
@NotNull(message = "设备ID不能为空")
private String deviceId;
private String productKey;
private String deviceName;
/**
* ID
*/
private String uid;
/**
*
* lifetime:
* state:
* property:
* event:
* service:
*/
private String type;
private String identifier;
/**
*
*/
private int code;
private Object data;
/**
*
*/
private Long occurred;
/**
*
*/
private Long time;
public Map<String, Object> dataToMap() {
Map<String, Object> mapData = new HashMap<>();
if (data instanceof Map) {
((Map<?, ?>) data).forEach((key, value) -> mapData.put(key.toString(), value));
}
return mapData;
}
}

View File

@ -0,0 +1,53 @@
package cc.iotkit.manager.dto.vo.deviceconfig;
import cc.iotkit.model.device.DeviceConfig;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
import java.util.Date;
import java.io.Serializable;
import java.math.BigDecimal;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
@ApiModel(value = "DeviceConfigVo")
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = DeviceConfig.class)
public class DeviceConfigVo implements Serializable {
private static final long serialVersionUID = -1L;
@ApiModelProperty(value = "设备配置id")
@ExcelProperty(value = "设备配置id")
private String id;
@ApiModelProperty(value = "设备配置json内容")
@ExcelProperty(value = "设备配置json内容")
private String config;
@ApiModelProperty(value = "创建时间")
@ExcelProperty(value = "创建时间")
private Long createAt;
@ApiModelProperty(value = "设备id")
@ExcelProperty(value = "设备id")
private String deviceId;
@ApiModelProperty(value = "设备名称")
@ExcelProperty(value = "设备名称")
private String deviceName;
@ApiModelProperty(value = "产品key")
@ExcelProperty(value = "产品key")
private String productKey;
}

View File

@ -0,0 +1,53 @@
package cc.iotkit.manager.dto.vo.devicegroup;
import cc.iotkit.model.device.DeviceGroup;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
import java.util.Date;
import java.io.Serializable;
import java.math.BigDecimal;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
@ApiModel(value = "DeviceGroupVo")
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = DeviceGroup.class)
public class DeviceGroupVo implements Serializable {
private static final long serialVersionUID = -1L;
@ApiModelProperty(value = "设备组id")
@ExcelProperty(value = "设备组id")
private String id;
@ApiModelProperty(value = "创建时间")
@ExcelProperty(value = "创建时间")
private Long createAt;
@ApiModelProperty(value = "设备数量")
@ExcelProperty(value = "设备数量")
private Integer deviceQty;
@ApiModelProperty(value = "设备组名称")
@ExcelProperty(value = "设备组名称")
private String name;
@ApiModelProperty(value = "分组说明")
@ExcelProperty(value = "分组说明")
private String remark;
@ApiModelProperty(value = "所属用户")
@ExcelProperty(value = "所属用户")
private String uid;
}

View File

@ -0,0 +1,77 @@
package cc.iotkit.manager.dto.vo.deviceinfo;
import cc.iotkit.model.device.DeviceInfo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
import java.util.Date;
import java.io.Serializable;
import java.math.BigDecimal;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
@ApiModel(value = "DeviceInfoVo")
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = DeviceInfo.class)
public class DeviceInfoVo implements Serializable {
private static final long serialVersionUID = -1L;
@ApiModelProperty(value = "")
@ExcelProperty(value = "")
private String id;
@ApiModelProperty(value = "创建时间")
@ExcelProperty(value = "创建时间")
private Long createAt;
@ApiModelProperty(value = "设备id")
@ExcelProperty(value = "设备id")
private String deviceId;
@ApiModelProperty(value = "设备名称")
@ExcelProperty(value = "设备名称")
private String deviceName;
@ApiModelProperty(value = "设备类型")
@ExcelProperty(value = "设备类型")
private String model;
@ApiModelProperty(value = "设备离线时间")
@ExcelProperty(value = "设备离线时间")
private Long offlineTime;
@ApiModelProperty(value = "设备在线时间")
@ExcelProperty(value = "设备在线时间")
private Long onlineTime;
@ApiModelProperty(value = "父级id")
@ExcelProperty(value = "父级id")
private String parentId;
@ApiModelProperty(value = "产品key")
@ExcelProperty(value = "产品key")
private String productKey;
@ApiModelProperty(value = "设备描述")
@ExcelProperty(value = "设备描述")
private String secret;
@ApiModelProperty(value = "设备状态")
@ExcelProperty(value = "设备状态")
private String state;
@ApiModelProperty(value = "用户id")
@ExcelProperty(value = "用户id")
private String uid;
}

View File

@ -0,0 +1,74 @@
package cc.iotkit.manager.service;
import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.manager.dto.bo.device.DeviceInfoBo;
import cc.iotkit.manager.dto.bo.device.DeviceLogQueryBo;
import cc.iotkit.manager.dto.bo.device.DeviceQueryBo;
import cc.iotkit.manager.dto.bo.device.DeviceTagAddBo;
import cc.iotkit.manager.dto.bo.devicegroup.DeviceAddGroupBo;
import cc.iotkit.manager.dto.bo.devicegroup.DeviceGroupBo;
import cc.iotkit.manager.dto.vo.deviceconfig.DeviceConfigVo;
import cc.iotkit.manager.dto.vo.devicegroup.DeviceGroupVo;
import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoVo;
import cc.iotkit.model.device.DeviceConfig;
import cc.iotkit.model.device.DeviceGroup;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.device.message.DeviceProperty;
import cc.iotkit.model.device.message.ThingModelMessage;
import org.springframework.web.context.request.async.DeferredResult;
import java.util.List;
import java.util.Map;
/**
* @Author: jay
* @Date: 2023/5/31 11:05
* @Version: V1.0
* @Description:
*/
public interface IDeviceService {
Paging<DeviceInfo> getDevices(PageRequest<DeviceQueryBo> pageRequest);
boolean addDevice(DeviceInfoBo data);
List<DeviceInfoVo> selectChildrenPageList(String deviceId);
List<Map<String, Object>> getParentDevices();
DeviceInfo getDetail(String deviceId);
DeviceInfo getByPkDn(String pk, String dn);
boolean deleteDevice(String data);
Paging<ThingModelMessage> logs(PageRequest<DeviceLogQueryBo> request);
List<DeviceProperty> getPropertyHistory(String deviceId, String name, long start, long end);
boolean unbindDevice(String data);
boolean addTag(DeviceTagAddBo bo);
boolean simulateSend(ThingModelMessage message);
DeferredResult addConsumer(String deviceId, String clientId);
Paging<DeviceGroupVo> selectGroupPageList(PageRequest<DeviceGroupBo> pageRequest);
boolean addGroup(DeviceGroup group);
boolean updateGroup(DeviceGroupBo data);
boolean deleteGroup(String id);
boolean clearGroup(String id);
boolean addDevice2Group(DeviceAddGroupBo data);
boolean removeDevices(String group, List<String> devices);
boolean saveConfig(DeviceConfig data);
DeviceConfigVo getConfig(String deviceId);
}

View File

@ -0,0 +1,397 @@
package cc.iotkit.manager.service.impl;
import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.common.constant.Constants;
import cc.iotkit.common.enums.ErrCode;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.satoken.utils.AuthUtil;
import cc.iotkit.common.utils.DeviceUtil;
import cc.iotkit.common.utils.MapstructUtils;
import cc.iotkit.common.utils.ReflectUtil;
import cc.iotkit.common.utils.UniqueIdUtil;
import cc.iotkit.comps.service.DeviceBehaviourService;
import cc.iotkit.data.manager.IDeviceConfigData;
import cc.iotkit.data.manager.IDeviceGroupData;
import cc.iotkit.data.manager.IDeviceInfoData;
import cc.iotkit.data.manager.IProductData;
import cc.iotkit.manager.dto.bo.device.DeviceInfoBo;
import cc.iotkit.manager.dto.bo.device.DeviceLogQueryBo;
import cc.iotkit.manager.dto.bo.device.DeviceQueryBo;
import cc.iotkit.manager.dto.bo.device.DeviceTagAddBo;
import cc.iotkit.manager.dto.bo.devicegroup.DeviceAddGroupBo;
import cc.iotkit.manager.dto.bo.devicegroup.DeviceGroupBo;
import cc.iotkit.manager.dto.vo.deviceconfig.DeviceConfigVo;
import cc.iotkit.manager.dto.vo.devicegroup.DeviceGroupVo;
import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoVo;
import cc.iotkit.manager.service.DataOwnerService;
import cc.iotkit.manager.service.DeferredDataConsumer;
import cc.iotkit.manager.service.DeviceService;
import cc.iotkit.manager.service.IDeviceService;
import cc.iotkit.model.device.DeviceConfig;
import cc.iotkit.model.device.DeviceGroup;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.device.message.DeviceProperty;
import cc.iotkit.model.device.message.ThingModelMessage;
import cc.iotkit.model.product.Product;
import cc.iotkit.temporal.IDevicePropertyData;
import cc.iotkit.temporal.IThingModelMessageData;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.async.DeferredResult;
import java.util.List;
import java.util.Map;
/**
* @Author: jay
* @Date: 2023/5/31 11:06
* @Version: V1.0
* @Description:
*/
@Service
public class DeviceServiceImpl implements IDeviceService {
@Autowired
private DeviceService deviceService;
@Autowired
@Qualifier("deviceInfoDataCache")
private IDeviceInfoData deviceInfoData;
@Autowired
@Qualifier("productDataCache")
private IProductData productData;
@Autowired
private DataOwnerService dataOwnerService;
@Lazy
@Autowired
private IThingModelMessageData thingModelMessageData;
@Lazy
@Autowired
private IDevicePropertyData devicePropertyData;
@Autowired
private DeviceBehaviourService behaviourService;
@Autowired
DeferredDataConsumer deferredDataConsumer;
@Autowired
private IDeviceGroupData deviceGroupData;
@Autowired
private IDeviceConfigData deviceConfigData;
@Override
public Paging<DeviceInfo> getDevices(PageRequest<DeviceQueryBo> pageRequest) {
DeviceQueryBo query = pageRequest.getData();
String uid = "";
String subUid = "";
if (!AuthUtil.isAdmin()) {
//客户端用户使用绑定子用户查询
if (AuthUtil.isClientUser()) {
subUid = AuthUtil.getUserId();
} else {
uid = AuthUtil.getUserId();
}
}
String pk = query.getProductKey();
//关键字查询
String keyword = query.getKeyword();
String group = query.getGroup();
String state = query.getState();
return deviceInfoData.findByConditions(uid, subUid, pk, group,
state, keyword, pageRequest.getPageNum(), pageRequest.getPageSize());
}
@Override
public boolean addDevice(DeviceInfoBo deviceInfo) {
String productKey = deviceInfo.getProductKey();
String deviceName = deviceInfo.getDeviceName();
String parentId = deviceInfo.getParentId();
Product product = productData.findById(productKey);
if (product == null) {
throw new BizException(ErrCode.PRODUCT_NOT_FOUND);
}
//生成设备密钥
String chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
int maxPos = chars.length();
StringBuilder secret = new StringBuilder();
for (var i = 0; i < 16; i++) {
secret.append(chars.charAt((int) Math.floor(Math.random() * maxPos)));
}
DeviceInfo device = new DeviceInfo();
device.setId(DeviceUtil.newDeviceId(deviceName));
device.setUid(product.getUid());
device.setDeviceId(device.getId());
device.setProductKey(productKey);
device.setDeviceName(deviceName);
device.setSecret(secret.toString());
device.setState(new DeviceInfo.State(false, null, null));
device.setCreateAt(System.currentTimeMillis());
if (StringUtils.isNotBlank(parentId)) {
device.setParentId(parentId);
}
deviceInfoData.save(device);
return true;
}
@Override
public List<DeviceInfoVo> selectChildrenPageList(String deviceId) {
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId);
if (deviceInfo == null) {
throw new BizException(ErrCode.DEVICE_NOT_FOUND);
}
dataOwnerService.checkOwner(deviceInfo);
return MapstructUtils.convert(deviceInfoData.findByParentId(deviceId), DeviceInfoVo.class);
}
@Override
public List<Map<String, Object>> getParentDevices() {
String uid = "";
if (!AuthUtil.isAdmin()) {
uid = AuthUtil.getUserId();
}
return deviceInfoData.findByProductNodeType(uid);
}
@Override
public DeviceInfo getDetail(String deviceId) {
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId);
dataOwnerService.checkOwner(deviceInfo);
deviceInfo.setProperty(deviceInfoData.getProperties(deviceId));
return deviceInfo;
}
@Override
public DeviceInfo getByPkDn(String pk, String dn) {
return dataOwnerService.checkOwner(
deviceInfoData.findByProductKeyAndDeviceName(pk, dn));
}
@Override
public boolean deleteDevice(String deviceId) {
deviceId = getDetail(deviceId).getDeviceId();
deviceInfoData.deleteById(deviceId);
return true;
}
@Override
public Paging<ThingModelMessage> logs(PageRequest<DeviceLogQueryBo> request) {
DeviceLogQueryBo data = request.getData();
return thingModelMessageData.findByTypeAndIdentifier(data.getDeviceId(), data.getType(), data.getIdentifier(), request.getPageNum(), request.getPageSize());
}
@Override
public List<DeviceProperty> getPropertyHistory(String deviceId, String name, long start, long end) {
return devicePropertyData.findDevicePropertyHistory(deviceId, name, start, end);
}
@Override
public boolean unbindDevice(String deviceId) {
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId);
dataOwnerService.checkOwner(deviceInfo);
deviceService.unbindDevice(deviceId);
return false;
}
@Override
public boolean addTag(DeviceTagAddBo bo) {
String deviceId = bo.getDeviceId();
DeviceInfo device = deviceInfoData.findByDeviceId(deviceId);
dataOwnerService.checkOwner(device);
deviceInfoData.updateTag(deviceId, bo.to(DeviceInfo.Tag.class));
return false;
}
@Override
public boolean simulateSend(ThingModelMessage message) {
DeviceInfo device = deviceInfoData.findByDeviceId(message.getDeviceId());
dataOwnerService.checkOwner(device);
message.setMid(UniqueIdUtil.newRequestId());
message.setOccurred(System.currentTimeMillis());
message.setTime(System.currentTimeMillis());
behaviourService.reportMessage(message);
return false;
}
@Override
public DeferredResult addConsumer(String deviceId, String clientId) {
DeferredResult<ThingModelMessage> result = new DeferredResult<>(0L);
String uid = AuthUtil.getUserId();
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId);
dataOwnerService.checkOwner(deviceInfo);
//按用户+客户端ID订阅
return deferredDataConsumer.newConsumer(uid + clientId,
Constants.HTTP_CONSUMER_DEVICE_INFO_TOPIC + deviceId);
}
@Override
public Paging<DeviceGroupVo> selectGroupPageList(PageRequest<DeviceGroupBo> pageRequest) {
DeviceGroupBo data = pageRequest.getData();
return deviceGroupData.findByNameLike(data.getName(), pageRequest.getPageNum(), pageRequest.getPageSize()).to(DeviceGroupVo.class);
}
@Override
public boolean addGroup(DeviceGroup group) {
group.setUid(AuthUtil.getUserId());
if (deviceGroupData.findById(group.getId()) != null) {
throw new BizException(ErrCode.GROUP_ALREADY);
}
deviceGroupData.save(group);
return true;
}
@Override
public boolean updateGroup(DeviceGroupBo bo) {
DeviceGroup group = bo.to(DeviceGroup.class);
DeviceGroup dbGroup = deviceGroupData.findById(group.getId());
if (dbGroup == null) {
throw new BizException(ErrCode.GROUP_NOT_FOUND);
}
dataOwnerService.checkOwner(dbGroup);
ReflectUtil.copyNoNulls(group, dbGroup);
deviceGroupData.save(dbGroup);
//更新设备中的组信息
deviceInfoData.updateGroup(dbGroup.getId(), new DeviceInfo.Group(dbGroup.getId(), dbGroup.getName()));
return true;
}
@Override
public boolean deleteGroup(String id) {
DeviceGroup group = deviceGroupData.findById(id);
if (group == null) {
throw new BizException(ErrCode.GROUP_NOT_FOUND);
}
dataOwnerService.checkOwner(group);
//删除分组
deviceGroupData.deleteById(id);
//移除设备信息中的分组
deviceInfoData.removeGroup(group.getId());
return true;
}
@Override
public boolean clearGroup(String id) {
DeviceGroup group = deviceGroupData.findById(id);
if (group == null) {
throw new BizException(ErrCode.GROUP_NOT_FOUND);
}
dataOwnerService.checkOwner(group);
//设备数量清零
group.setDeviceQty(0);
deviceGroupData.save(group);
//移除设备信息中的分组
deviceInfoData.removeGroup(group.getId());
return true;
}
@Override
public boolean addDevice2Group(DeviceAddGroupBo data) {
String group = data.getGroup();
List<String> devices = data.getDevices();
DeviceGroup deviceGroup = deviceGroupData.findById(group);
if (deviceGroup == null) {
throw new BizException(ErrCode.GROUP_NOT_FOUND);
}
dataOwnerService.checkOwner(deviceGroup);
for (String device : devices) {
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(device);
if (deviceInfo == null) {
continue;
}
dataOwnerService.checkOwner(deviceInfo);
//添加设备到组
deviceInfoData.addToGroup(device, new DeviceInfo.Group(group, deviceGroup.getName()));
}
//统计组下设备数量
long qty = deviceInfoData.countByGroupId(group);
//更新组信息
deviceGroup.setDeviceQty((int) qty);
deviceGroupData.save(deviceGroup);
return true;
}
@Override
public boolean removeDevices(String group, List<String> devices) {
DeviceGroup deviceGroup = deviceGroupData.findById(group);
if (deviceGroup == null) {
throw new BizException(ErrCode.GROUP_NOT_FOUND);
}
dataOwnerService.checkOwner(deviceGroup);
for (String device : devices) {
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(device);
if (deviceInfo == null) {
continue;
}
dataOwnerService.checkOwner(deviceInfo);
//删除设备所在组
deviceInfoData.removeGroup(device, group);
}
//统计组下设备数量
long qty = deviceInfoData.countByGroupId(group);
//更新组信息
deviceGroup.setDeviceQty((int) qty);
deviceGroupData.save(deviceGroup);
return true;
}
@Override
public boolean saveConfig(DeviceConfig data) {
String deviceId = data.getDeviceId();
String config = data.getConfig();
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId);
dataOwnerService.checkOwner(deviceInfo);
DeviceConfig deviceConfig = deviceConfigData.findByDeviceId(deviceId);
if (deviceConfig == null) {
deviceConfig = DeviceConfig.builder()
.deviceId(deviceId)
.deviceName(deviceInfo.getDeviceName())
.productKey(deviceInfo.getProductKey())
.config(config)
.createAt(System.currentTimeMillis())
.build();
} else {
deviceConfig.setConfig(config);
}
deviceConfigData.save(deviceConfig);
return false;
}
@Override
public DeviceConfigVo getConfig(String deviceId) {
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId);
dataOwnerService.checkOwner(deviceInfo);
return MapstructUtils.convert(deviceConfigData.findByDeviceId(deviceId), DeviceConfigVo.class);
}
}