合并feature

V0.5.x
xiwa 2022-08-02 17:24:17 +08:00
commit 4866c27ed9
483 changed files with 7715 additions and 3507 deletions

BIN
.DS_Store vendored

Binary file not shown.

1
.gitignore vendored
View File

@ -26,3 +26,4 @@ target
log
data/elasticsearch
.init
*.db

0
.workflow/BranchPipeline.yml Normal file → Executable file
View File

0
.workflow/MasterPipeline.yml Normal file → Executable file
View File

0
.workflow/PRPipeline.yml Normal file → Executable file
View File

View File

@ -1,6 +1,8 @@
FROM openjdk:11-jre-slim
WORKDIR /app
ADD iot-standalone/target/iot-standalone-0.3.2-SNAPSHOT.tar /app/
ADD /data /app/data/
ADD iot-standalone/target/iot-standalone-0.4.0-SNAPSHOT.tar /app
ADD data/init /app/data/init
ADD data/components /app/data/components
ADD data/converters /app/data/converters
EXPOSE 8086
ENTRYPOINT ["java", "-classpath", ".:lib/*","cc.iotkit.manager.Application"]
ENTRYPOINT ["java", "-classpath", ".:lib/*","cc.iotkit.Application"]

View File

0
data/converters/6260396d67aced2696184053/converter.js Normal file → Executable file
View File

0
data/init/category.json Normal file → Executable file
View File

0
data/init/deviceGroup.json Normal file → Executable file
View File

18
data/init/deviceInfo.json Normal file → Executable file
View File

@ -1293,24 +1293,6 @@
},
"createAt": 1650171261224
},
{
"id": "164951142660200010000000000000034",
"deviceId": "164951142660200010000000000000034",
"productKey": "KdJYpTp5ywNhmrmC",
"deviceName": "001",
"uid": "fa1c5eaa-de6e-48b6-805e-8f091c7bb831",
"state": {
"online": false
},
"createAt": 1649511426602,
"tag": {
"aligenie": {
"id": "aligenie",
"name": "天猫精灵接入",
"value": "是"
}
}
},
{
"id": "164785263238900cefafcfeeab0000125",
"deviceId": "164785263238900cefafcfeeab0000125",

0
data/init/home.json Normal file → Executable file
View File

4
data/init/oauthClient.json Normal file → Executable file
View File

@ -1,13 +1,13 @@
[
{
"id": "iotkit",
"clientId": "iotkit",
"name": "奇特物联",
"clientSecret": "b86cb53d-c005-48a3-bb02-3c262151b68c",
"allowUrl": "*",
"createAt": 1652840868485
},
{
"id": "dueros",
"clientId": "dueros",
"name": "小度音箱",
"clientSecret": "750c67c2-29cb-40c3-bf4d-c0b9bf3eed88",
"allowUrl": "*",

0
data/init/product.json Normal file → Executable file
View File

0
data/init/productModel.json Normal file → Executable file
View File

View File

@ -1,26 +1,14 @@
[
{
"id": "fee0e826-963f-4e53-a2cf-11e3e5f784ea",
"uid": "fa1c5eaa-de6e-48b6-805e-8f091c7bb831",
"name": "移动Onenet Studio接入",
"type": "biz",
"protocol": "http",
"jarFile": "iot-http-biz-component-0.3.2-SNAPSHOT.jar",
"config": "{\"port\":\"8086\"}",
"converter": "6260396d67aced2696184053",
"state": "stop",
"createAt": 1652238780184
},
{
"id": "eabb131d-8fd1-43a8-88d9-a198abfd3d42",
"uid": "fa1c5eaa-de6e-48b6-805e-8f091c7bb831",
"name": "MQTT标准协议组件",
"type": "device",
"protocol": "mqtt",
"jarFile": "iot-mqtt-component-0.3.2-SNAPSHOT.jar",
"jarFile": "iot-mqtt-component-0.4.0-SNAPSHOT.jar",
"config": "{\"port\":1883,\"ssl\":false,\"type\":\"server\"}",
"converter": "6260396d67aced2696184053",
"state": "stop",
"state": "running",
"createAt": 1650473458084
},
{
@ -29,10 +17,10 @@
"name": "EMQX标准协议组件",
"type": "device",
"protocol": "mqtt",
"jarFile": "iot-emqx-component-0.3.2-SNAPSHOT.jar",
"jarFile": "iot-emqx-component-0.4.0-SNAPSHOT.jar",
"config": "{\"port\":\"1884\",\"ssl\":false,\"type\":\"client\",\"subscribeTopics\":[\"/sys/+/+/s/#\",\"/sys/client/connected\",\"/sys/client/disconnected\",\"/sys/session/subscribed\",\"/sys/session/unsubscribed\"],\"authPort\":\"8088\",\"broker\":\"127.0.0.1\",\"clientId\":\"test\",\"username\":\"test\",\"password\":\"123\"}",
"converter": "6260396d67aced2696184053",
"state": "stop",
"state": "stopped",
"createAt": 1653180468724
},
{
@ -41,10 +29,10 @@
"name": "小度音箱接入组件",
"type": "biz",
"protocol": "http",
"jarFile": "iot-http-biz-component-0.3.2-SNAPSHOT.jar",
"jarFile": "iot-http-biz-component-0.4.0-SNAPSHOT.jar",
"config": "{\"port\":\"8084\"}",
"converter": "",
"state": "stop",
"state": "stopped",
"createAt": 1650685502665
}
]

0
data/init/protocolConverter.json Normal file → Executable file
View File

0
data/init/ruleInfo.json Normal file → Executable file
View File

0
data/init/space.json Normal file → Executable file
View File

0
data/init/spaceDevice.json Normal file → Executable file
View File

0
data/init/taskInfo.json Normal file → Executable file
View File

0
data/init/thingModel.json Normal file → Executable file
View File

0
data/init/userInfo.json Normal file → Executable file
View File

0
data/init/virtualDevice.json Normal file → Executable file
View File

0
doc/WechatIMG539.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 317 KiB

After

Width:  |  Height:  |  Size: 317 KiB

0
doc/mongodb安装配置.jpg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 497 KiB

After

Width:  |  Height:  |  Size: 497 KiB

0
doc/screenshot.jpg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

0
doc/安装Pulsar.jpg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

12
iot-auth-server/pom.xml Normal file → Executable file
View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iotkit-parent</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.3.2-SNAPSHOT</version>
<version>0.4.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -43,17 +43,17 @@
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-dao</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-data-service</artifactId>
</dependency>
</dependencies>
</project>

0
iot-auth-server/readme.txt Normal file → Executable file
View File

View File

@ -1,10 +1,19 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.oauth.controller;
import cc.iotkit.common.Constants;
import cc.iotkit.common.utils.CodecUtil;
import cc.iotkit.common.utils.ReflectUtil;
import cc.iotkit.dao.OauthClientCache;
import cc.iotkit.dao.UserInfoCache;
import cc.iotkit.data.IOauthClientData;
import cc.iotkit.data.IUserInfoData;
import cc.iotkit.model.OauthClient;
import cc.iotkit.model.UserInfo;
import cc.iotkit.oauth.vo.UserInfoVo;
@ -16,6 +25,7 @@ import com.ejlchina.okhttps.OkHttps;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.web.bind.annotation.GetMapping;
@ -36,16 +46,18 @@ public class AuthClientController {
private String serverUrl;
@Autowired
private OauthClientCache oauthClientCache;
@Qualifier("oauthClientDataCache")
private IOauthClientData oauthClientData;
@Autowired
private UserInfoCache userInfoCache;
@Qualifier("userInfoDataCache")
private IUserInfoData userInfoData;
/**
* Code Access-Token
*/
@RequestMapping("/codeLogin")
public SaResult codeLogin(String code, String clientId) {
OauthClient oauthClient = oauthClientCache.getClient(clientId);
OauthClient oauthClient = oauthClientData.findByClientId(clientId);
if (oauthClient == null) {
return SaResult.error("clientId does not exist");
}
@ -117,7 +129,7 @@ public class AuthClientController {
}
private UserInfoVo getUserInfo(String uid) {
UserInfo userInfo = userInfoCache.getUserInfo(uid);
UserInfo userInfo = userInfoData.findById(uid);
UserInfoVo userVo = new UserInfoVo();
ReflectUtil.copyNoNulls(userInfo, userVo);
return userVo;

View File

@ -10,7 +10,7 @@
package cc.iotkit.oauth.controller;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.dao.UserInfoRepository;
import cc.iotkit.data.IUserInfoData;
import cc.iotkit.model.UserInfo;
import cc.iotkit.oauth.service.TokenRequestHandler;
import cc.iotkit.utils.AuthUtil;
@ -33,7 +33,7 @@ import java.util.Map;
public class AuthServerController {
@Autowired
private UserInfoRepository userInfoRepository;
private IUserInfoData userInfoData;
/**
* OAuth
@ -56,7 +56,7 @@ public class AuthServerController {
// 登录处理函数
setDoLoginHandle((name, pwd) -> {
try {
UserInfo userInfo = userInfoRepository.findByUid(name);
UserInfo userInfo = userInfoData.findByUid(name);
if (userInfo != null) {
String secret = userInfo.getSecret();
if (AuthUtil.checkPwd(pwd, secret)) {

View File

@ -11,25 +11,27 @@ package cc.iotkit.oauth.service;
import cc.iotkit.common.Constants;
import cc.iotkit.common.utils.CodecUtil;
import cc.iotkit.dao.OauthClientCache;
import cc.iotkit.data.IOauthClientData;
import cc.iotkit.model.OauthClient;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Template;
import cn.dev33.satoken.oauth2.model.SaClientModel;
import cn.dev33.satoken.stp.StpUtil;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component
public class SaOAuth2TemplateImpl extends SaOAuth2Template {
@Autowired
private OauthClientCache oauthClientCache;
@Qualifier("oauthClientDataCache")
private IOauthClientData oauthClientData;
// 根据 id 获取 Client 信息
@Override
public SaClientModel getClientModel(String clientId) {
OauthClient client = oauthClientCache.getClient(clientId);
OauthClient client = oauthClientData.findByClientId(clientId);
if (client == null) {
return null;
}

View File

@ -9,10 +9,11 @@
*/
package cc.iotkit.oauth.service;
import cc.iotkit.dao.UserInfoCache;
import cc.iotkit.data.IUserInfoData;
import cc.iotkit.model.UserInfo;
import cn.dev33.satoken.stp.StpInterface;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import java.util.List;
@ -21,14 +22,15 @@ import java.util.List;
public class StpInterfaceImpl implements StpInterface {
@Autowired
private UserInfoCache userInfoCache;
@Qualifier("userInfoDataCache")
private IUserInfoData userInfoData;
/**
*
*/
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
UserInfo userInfo = userInfoCache.getUserInfo(loginId.toString());
UserInfo userInfo = userInfoData.findById(loginId.toString());
return userInfo.getPermissions();
}
@ -37,7 +39,7 @@ public class StpInterfaceImpl implements StpInterface {
*/
@Override
public List<String> getRoleList(Object loginId, String loginType) {
UserInfo userInfo = userInfoCache.getUserInfo(loginId.toString());
UserInfo userInfo = userInfoData.findById(loginId.toString());
return userInfo.getRoles();
}

View File

@ -1,3 +1,12 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.oauth.service;
import cn.dev33.satoken.context.SaHolder;

View File

View File

View File

View File

View File

0
iot-auth-server/src/test/java/GenPwdSecret.java Normal file → Executable file
View File

2
iot-common/pom.xml Normal file → Executable file
View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iotkit-parent</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.3.2-SNAPSHOT</version>
<version>0.4.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

0
iot-common/readme.txt Normal file → Executable file
View File

View File

View File

@ -15,21 +15,21 @@ public interface Constants {
String ACCOUNT_SECRET = "3n1z33kzvpgz1foijpkepyd3e8tw84us";
String PRODUCT_CACHE = "product_cache";
String CACHE_PRODUCT = "product_cache";
String DEVICE_CACHE = "device_cache";
String CACHE_DEVICE_INFO = "device_info_cache";
String DEVICE_STATS_CACHE = "device_stats_cache";
String CACHE_DEVICE_STATS = "device_stats_cache";
String CATEGORY_CACHE = "category_cache";
String CACHE_CATEGORY = "category_cache";
String SPACE_CACHE = "space_cache";
String CACHE_SPACE = "space_cache";
String THING_MODEL_CACHE = "thing_model_cache";
String USER_CACHE = "user_info_cache";
String CACHE_USER_INFO = "user_info_cache";
String OAUTH_CLIENT_CACHE = "oauth_client_cache";
String CACHE_OAUTH_CLIENT = "oauth_client_cache";
String WECHAT_APP_ID = "wx791cb7bf75950e0c";
@ -37,7 +37,7 @@ public interface Constants {
String APP_DESIGN_CACHE = "app_design_cache";
String PRODUCT_SCRIPT_CACHE = "product_script_cache";
String CACHE_PRODUCT_SCRIPT = "product_script_cache";
/**
*

View File

View File

View File

View File

View File

View File

View File

View File

View File

0
iot-components/.DS_Store vendored Normal file → Executable file
View File

0
iot-components/iot-component-base/.DS_Store vendored Normal file → Executable file
View File

7
iot-components/iot-component-base/pom.xml Normal file → Executable file
View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-components</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.3.2-SNAPSHOT</version>
<version>0.4.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -18,6 +18,11 @@
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

0
iot-components/iot-component-converter/.DS_Store vendored Normal file → Executable file
View File

2
iot-components/iot-component-converter/pom.xml Normal file → Executable file
View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-components</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.3.2-SNAPSHOT</version>
<version>0.4.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

0
iot-components/iot-component-server/.DS_Store vendored Normal file → Executable file
View File

19
iot-components/iot-component-server/pom.xml Normal file → Executable file
View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-components</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.3.2-SNAPSHOT</version>
<version>0.4.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -77,11 +77,6 @@
<artifactId>iot-model</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-dao</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-component-base</artifactId>
@ -94,7 +89,17 @@
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-device-dao</artifactId>
<artifactId>iot-data-service</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-temporal-service</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-data-cache</artifactId>
</dependency>
</dependencies>

View File

@ -16,7 +16,7 @@ import cc.iotkit.comp.CompConfig;
import cc.iotkit.comp.IComponent;
import cc.iotkit.comps.config.ComponentConfig;
import cc.iotkit.comps.service.DeviceBehaviourService;
import cc.iotkit.dao.ProtocolComponentRepository;
import cc.iotkit.data.IProtocolComponentData;
import cc.iotkit.model.protocol.ProtocolComponent;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
@ -41,14 +41,14 @@ public class BizComponentManager {
@Autowired
private ComponentConfig componentConfig;
@Autowired
private ProtocolComponentRepository componentRepository;
private IProtocolComponentData protocolComponentData;
@Autowired
private DeviceBehaviourService deviceBehaviourService;
@PostConstruct
public void init() {
try {
List<ProtocolComponent> componentList = componentRepository
List<ProtocolComponent> componentList = protocolComponentData
.findByStateAndType(ProtocolComponent.STATE_RUNNING, ProtocolComponent.TYPE_BIZ);
for (ProtocolComponent component : componentList) {
register(component);

View File

@ -23,9 +23,9 @@ import cc.iotkit.converter.Device;
import cc.iotkit.converter.DeviceMessage;
import cc.iotkit.converter.ScriptConverter;
import cc.iotkit.common.thing.ThingService;
import cc.iotkit.dao.DeviceCache;
import cc.iotkit.dao.ProductCache;
import cc.iotkit.dao.ProtocolComponentRepository;
import cc.iotkit.data.IDeviceInfoData;
import cc.iotkit.data.IProductData;
import cc.iotkit.data.IProtocolComponentData;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.device.message.ThingModelMessage;
import cc.iotkit.model.product.Product;
@ -34,6 +34,7 @@ import cc.iotkit.model.protocol.ProtocolConverter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
@ -60,27 +61,29 @@ public class DeviceComponentManager {
@Autowired
private ComponentConfig componentConfig;
@Autowired
private ProtocolComponentRepository componentRepository;
private IProtocolComponentData protocolComponentData;
@Autowired
private DeviceCache deviceCache;
@Qualifier("productDataCache")
IProductData productData;
@Autowired
ProductCache productCache;
@Qualifier("deviceInfoDataCache")
private IDeviceInfoData deviceInfoData;
@Autowired
private DeviceRouter deviceRouter;
@PostConstruct
public void init() {
try {
List<ProtocolComponent> componentList = componentRepository.findByStateAndType(
List<ProtocolComponent> componentList = protocolComponentData.findByStateAndType(
ProtocolComponent.STATE_RUNNING, ProtocolComponent.TYPE_DEVICE);
for (ProtocolComponent component : componentList) {
try {
register(component);
start(component.getId());
}
} catch (Throwable e) {
log.error("init protocol components error", e);
}
}
}
public void register(ProtocolComponent component) {
String id = component.getId();
@ -170,14 +173,14 @@ public class DeviceComponentManager {
throw new BizException("there is no components");
}
DeviceInfo deviceInfo = deviceCache.getDeviceInfo(service.getProductKey(), service.getDeviceName());
Product product = productCache.findById(service.getProductKey());
DeviceInfo deviceInfo = deviceInfoData.findByProductKeyAndDeviceName(service.getProductKey(), service.getDeviceName());
Product product = productData.findById(service.getProductKey());
String linkPk = service.getProductKey();
String linkDn = service.getDeviceName();
if (product.isTransparent()) {
//如果是透传设备,取父级设备进行链路查找
DeviceInfo parent = deviceCache.get(deviceInfo.getParentId());
DeviceInfo parent = deviceInfoData.findByDeviceId(deviceInfo.getParentId());
linkPk = parent.getProductKey();
linkDn = parent.getDeviceName();
}

View File

@ -1,6 +1,5 @@
package cc.iotkit.comps.config;
import cc.iotkit.model.device.message.DeviceReport;
import cc.iotkit.model.device.message.ThingModelMessage;
import cc.iotkit.mq.MqConsumer;
import cc.iotkit.mq.MqProducer;
@ -54,13 +53,4 @@ public class ComponentConfig {
return new VertxMqConsumer<>(ThingModelMessage.class);
}
@Bean("deviceReportProducer")
public MqProducer<DeviceReport> getDeviceReportProducer() {
return new VertxMqProducer<>(DeviceReport.class);
}
@Bean("deviceReportConsumer")
public MqConsumer<DeviceReport> getDeviceReportConsumer() {
return new VertxMqConsumer<>(DeviceReport.class);
}
}

View File

@ -16,7 +16,9 @@ import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.common.utils.UniqueIdUtil;
import cc.iotkit.comp.model.DeviceState;
import cc.iotkit.comp.model.RegisterInfo;
import cc.iotkit.dao.*;
import cc.iotkit.data.IDeviceInfoData;
import cc.iotkit.data.IProductModelData;
import cc.iotkit.data.IProductData;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.device.message.ThingModelMessage;
import cc.iotkit.model.product.Product;
@ -25,28 +27,27 @@ import cc.iotkit.mq.MqProducer;
import lombok.extern.slf4j.Slf4j;
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 java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@Slf4j
@Service
public class DeviceBehaviourService {
@Autowired
private ProductRepository productRepository;
private IProductModelData productModelData;
@Autowired
private ProductModelRepository productModelRepository;
@Autowired
private ProductCache productCache;
@Autowired
private DeviceInfoRepository deviceInfoRepository;
@Autowired
private DeviceCache deviceCache;
@Qualifier("deviceInfoDataCache")
private IDeviceInfoData deviceInfoData;
@Autowired
private MqProducer<ThingModelMessage> producer;
@Autowired
@Qualifier("productDataCache")
private IProductData productData;
public void register(RegisterInfo info) {
try {
@ -80,7 +81,7 @@ public class DeviceBehaviourService {
if (parentId != null) {
//透传设备pk为空、model不为空使用model查询产品
if (StringUtils.isBlank(pk) && StringUtils.isNotBlank(model)) {
ProductModel productModel = productModelRepository.findByModel(model);
ProductModel productModel = productModelData.findByModel(model);
if (productModel == null) {
throw new BizException("product model does not exist");
}
@ -88,13 +89,12 @@ public class DeviceBehaviourService {
}
}
Optional<Product> optProduct = productRepository.findById(pk);
if (optProduct.isEmpty()) {
Product product = productData.findById(pk);
if (product == null) {
throw new BizException("Product does not exist");
}
Product product = optProduct.get();
String uid = product.getUid();
DeviceInfo device = deviceInfoRepository.findByProductKeyAndDeviceName(pk, info.getDeviceName());
DeviceInfo device = deviceInfoData.findByProductKeyAndDeviceName(pk, info.getDeviceName());
boolean reportMsg = false;
if (device != null) {
@ -130,13 +130,14 @@ public class DeviceBehaviourService {
device.setParentId(parentId);
reportMsg = true;
}
deviceInfoRepository.save(device);
deviceInfoData.save(device);
//新设备或更换网关需要产生注册消息
if (reportMsg) {
log.info("device registered:{}", JsonUtil.toJsonString(device));
//新注册设备注册消息
ThingModelMessage modelMessage = new ThingModelMessage(
UUID.randomUUID().toString(),
UniqueIdUtil.newRequestId(), "",
pk, dn,
ThingModelMessage.TYPE_LIFETIME, "register",
@ -154,7 +155,7 @@ public class DeviceBehaviourService {
String deviceName,
String productSecret,
String deviceSecret) {
DeviceInfo deviceInfo = deviceInfoRepository.findByProductKeyAndDeviceName(productKey, deviceName);
DeviceInfo deviceInfo = deviceInfoData.findByProductKeyAndDeviceName(productKey, deviceName);
if (deviceInfo == null) {
throw new BizException("device does not exist");
}
@ -177,20 +178,23 @@ public class DeviceBehaviourService {
public void deviceStateChange(String productKey,
String deviceName,
boolean online) {
DeviceInfo device = deviceInfoRepository.findByProductKeyAndDeviceName(productKey, deviceName);
DeviceInfo device = deviceInfoData.findByProductKeyAndDeviceName(productKey, deviceName);
if (device == null) {
log.warn(String.format("productKey: %s,device: %s,online: %s", productKey, device, online));
throw new BizException("device does not exist");
}
deviceStateChange(device, online);
//父设备ID不为空说明是子设备
if (device.getParentId() != null) {
return;
}
List<DeviceInfo> subDevices = deviceInfoRepository.findByParentId(device.getDeviceId());
for (DeviceInfo subDevice : subDevices) {
Product product = productCache.findById(subDevice.getProductKey());
//否则为父设备,同步透传子设备状态
List<String> subDeviceIds = deviceInfoData.findSubDeviceIds(device.getDeviceId());
for (String subDeviceId : subDeviceIds) {
DeviceInfo subDevice=deviceInfoData.findByDeviceId(subDeviceId);
Product product = productData.findById(subDevice.getProductKey());
Boolean transparent = product.getTransparent();
//透传设备父设备上线,子设备也上线。非透传设备父设备离线,子设备才离线
if (transparent != null && transparent || !online) {
@ -207,10 +211,11 @@ public class DeviceBehaviourService {
device.getState().setOnline(false);
device.getState().setOfflineTime(System.currentTimeMillis());
}
deviceInfoRepository.save(device);
deviceInfoData.save(device);
//设备状态变更消息
ThingModelMessage modelMessage = new ThingModelMessage(
UUID.randomUUID().toString(),
UniqueIdUtil.newRequestId(), "",
device.getProductKey(), device.getDeviceName(),
ThingModelMessage.TYPE_STATE,
@ -225,8 +230,8 @@ public class DeviceBehaviourService {
public void reportMessage(ThingModelMessage message) {
try {
DeviceInfo device = deviceCache.getDeviceInfo(message.getProductKey(),
message.getDeviceName());
DeviceInfo device = deviceInfoData.findByProductKeyAndDeviceName(
message.getProductKey(), message.getDeviceName());
if (device == null) {
return;
}

View File

@ -13,7 +13,7 @@ import cc.iotkit.common.Constants;
import cc.iotkit.common.thing.ThingService;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.comps.DeviceComponentManager;
import cc.iotkit.dao.DeviceConfigRepository;
import cc.iotkit.data.IDeviceConfigData;
import cc.iotkit.model.device.DeviceConfig;
import cc.iotkit.model.device.message.ThingModelMessage;
import cc.iotkit.mq.ConsumerHandler;
@ -30,7 +30,7 @@ import java.util.Map;
*/
@Slf4j
@Service
public class DeviceConfigService implements ConsumerHandler<ThingModelMessage> {
public class DeviceConfigConsumer implements ConsumerHandler<ThingModelMessage> {
@Autowired
private MqConsumer<ThingModelMessage> configMessageConsumer;
@ -39,7 +39,7 @@ public class DeviceConfigService implements ConsumerHandler<ThingModelMessage> {
public DeviceComponentManager deviceComponentManager;
@Autowired
private DeviceConfigRepository deviceConfigRepository;
private IDeviceConfigData deviceConfigData;
@PostConstruct
public void init() {
@ -52,7 +52,7 @@ public class DeviceConfigService implements ConsumerHandler<ThingModelMessage> {
String identifier = msg.getIdentifier();
if (ThingModelMessage.ID_CONFIG_GET.equals(identifier)) {
//收到设备获取配置消息,回复配置信息给设备
DeviceConfig deviceConfig = deviceConfigRepository.findByDeviceId(msg.getDeviceId());
DeviceConfig deviceConfig = deviceConfigData.findByDeviceId(msg.getDeviceId());
if (deviceConfig == null) {
return;
}

View File

@ -10,35 +10,28 @@
package cc.iotkit.comps.service;
import cc.iotkit.common.Constants;
import cc.iotkit.dao.*;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.device.message.DeviceReport;
import cc.iotkit.model.device.message.ThingModelMessage;
import cc.iotkit.mq.ConsumerHandler;
import cc.iotkit.mq.MqConsumer;
import cc.iotkit.mq.MqProducer;
import cc.iotkit.temporal.IThingModelMessageData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.UUID;
@Slf4j
@Service
public class DeviceMessageConsumer implements ConsumerHandler<ThingModelMessage> {
@Lazy
@Autowired
private ThingModelMessageRepository messageRepository;
@Autowired
private DeviceCache deviceCache;
private IThingModelMessageData thingModelMessageData;
@Autowired
private MqConsumer<ThingModelMessage> thingModelMessageConsumer;
@Autowired
private MqProducer<ThingModelMessage> thingModelMessageMqProducer;
@Autowired
private MqProducer<DeviceReport> deviceReportProducer;
@PostConstruct
public void init() {
@ -59,29 +52,12 @@ public class DeviceMessageConsumer implements ConsumerHandler<ThingModelMessage>
thingModelMessageMqProducer.publish(Constants.DEVICE_CONFIG_TOPIC, msg);
}
//重新发布设备上报记录,不包含消息内容,用于数据统计
deviceReportProducer.publish(Constants.DEVICE_REPORT_RECORD_TOPIC, getDeviceReport(msg));
//设备消息入库
messageRepository.save(msg);
thingModelMessageData.add(msg);
} catch (Throwable e) {
//不能重复消费
log.error("device message consumer error", e);
}
}
private DeviceReport getDeviceReport(ThingModelMessage message) {
DeviceInfo device = deviceCache.get(message.getDeviceId());
return DeviceReport.builder()
.id(UUID.randomUUID().toString())
.deviceId(message.getDeviceId())
.productKey(message.getProductKey())
.deviceName(message.getDeviceName())
.uid(device.getUid())
.identifier(message.getIdentifier())
.type(message.getType())
.code(message.getCode())
.time(message.getTime())
.build();
}
}

View File

@ -1,15 +1,25 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.comps.service;
import cc.iotkit.common.Constants;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.dao.DeviceDao;
import cc.iotkit.dao.DevicePropertyRepository;
import cc.iotkit.data.IDeviceInfoData;
import cc.iotkit.model.device.message.DeviceProperty;
import cc.iotkit.model.device.message.ThingModelMessage;
import cc.iotkit.mq.ConsumerHandler;
import cc.iotkit.mq.MqConsumer;
import cc.iotkit.temporal.IDevicePropertyData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@ -22,14 +32,15 @@ import java.util.Map;
*/
@Slf4j
@Service
public class PropertyPersistService implements ConsumerHandler<ThingModelMessage> {
public class DevicePropertyConsumer implements ConsumerHandler<ThingModelMessage> {
@Autowired
private MqConsumer<ThingModelMessage> thingModelMessageMqConsumer;
@Autowired
private DeviceDao deviceDao;
private IDevicePropertyData devicePropertyData;
@Autowired
private DevicePropertyRepository propertyRepository;
@Qualifier("deviceInfoDataCache")
private IDeviceInfoData deviceInfoData;
@PostConstruct
public void init() {
@ -63,7 +74,7 @@ public class PropertyPersistService implements ConsumerHandler<ThingModelMessage
//批量保存
try {
propertyRepository.saveAll(batch);
devicePropertyData.addProperties(batch);
} catch (Throwable e) {
log.warn("save property data error", e);
}
@ -74,9 +85,8 @@ public class PropertyPersistService implements ConsumerHandler<ThingModelMessage
*/
private void updateDeviceCurrentProperties(String deviceId, Map<String, Object> properties) {
try {
log.info("update device property,deviceId:{},property:{}",
deviceId, JsonUtil.toJsonString(properties));
deviceDao.updateProperties(deviceId, properties);
log.info("save device property,deviceId:{},property:{}", deviceId, JsonUtil.toJsonString(properties));
deviceInfoData.saveProperties(deviceId, properties);
} catch (Throwable e) {
log.error("save device current properties error", e);
}

View File

@ -1,40 +0,0 @@
package cc.iotkit.comps.service;
import cc.iotkit.common.Constants;
import cc.iotkit.dao.DeviceReportRepository;
import cc.iotkit.model.device.message.DeviceReport;
import cc.iotkit.mq.ConsumerHandler;
import cc.iotkit.mq.MqConsumer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
/**
*
*/
@Slf4j
@Service
public class ReportRecordPersistService implements ConsumerHandler<DeviceReport> {
@Autowired
private MqConsumer<DeviceReport> deviceReportMqConsumer;
@Autowired
private DeviceReportRepository deviceReportRepository;
@PostConstruct
public void init() {
deviceReportMqConsumer.consume(Constants.DEVICE_REPORT_RECORD_TOPIC, this);
}
@Override
public void handler(DeviceReport msg) {
try {
deviceReportRepository.save(msg);
} catch (Throwable e) {
log.warn("save report record error", e);
}
}
}

0
iot-components/iot-ctwing-component/.DS_Store vendored Normal file → Executable file
View File

View File

@ -0,0 +1,92 @@
<?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-components</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.4.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>iot-ctwing-component</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-proxy</artifactId>
</dependency>
<dependency>
<groupId>com.ctg.ag</groupId>
<artifactId>ctg-ag-sdk-core</artifactId>
<version>2.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.ctg.ag</groupId>
<artifactId>ag-sdk-biz-84356.tar.gz</artifactId>
<version>20220603.182201-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-component-base</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<artifactSet>
<includes>
<include>io.vertx:vertx-web-proxy</include>
<include>io.vertx:vertx-web</include>
<include>io.vertx:vertx-bridge-common</include>
<include>io.vertx:vertx-http-proxy</include>
<include>io.vertx:vertx-core</include>
<include>io.netty:netty-codec-http2</include>
<include>com.ctg.ag:ctg-ag-sdk-core</include>
<include>com.ctg.ag:ag-sdk-biz-84356.tar.gz</include>
<include>org.apache.httpcomponents:httpasyncclient</include>
</includes>
</artifactSet>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,34 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.comp.http;
import lombok.Data;
@Data
public class CtwingConfig {
private int port;
/**
* ctwingtoken
*/
private String encryptToken;
/**
* ctwingappKey
*/
private String appKey;
/**
* ctwingappSecret
*/
private String appSecret;
}

View File

@ -0,0 +1,206 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.comp.http;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.utils.CodecUtil;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.comp.AbstractDeviceComponent;
import cc.iotkit.comp.CompConfig;
import cc.iotkit.converter.DeviceMessage;
import com.ctg.ag.sdk.biz.AepDeviceCommandClient;
import com.ctg.ag.sdk.biz.aep_device_command.CreateCommandRequest;
import com.ctg.ag.sdk.biz.aep_device_command.CreateCommandResponse;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import java.util.List;
import java.util.Map;
/**
*
*/
@Slf4j
public class CtwingDeviceComponent extends AbstractDeviceComponent {
private final Vertx vertx = Vertx.vertx();
private CtwingConfig ctwingConfig;
private HttpServer backendServer;
private AepDeviceCommandClient commandClient;
@Override
public void create(CompConfig config) {
super.create(config);
this.ctwingConfig = JsonUtil.parse(config.getOther(), CtwingConfig.class);
commandClient = AepDeviceCommandClient.newClient()
.appKey(ctwingConfig.getAppKey())
.appSecret(ctwingConfig.getAppSecret())
.build();
}
@Override
public void start() {
backendServer = vertx.createHttpServer();
Router backendRouter = Router.router(vertx);
backendRouter.route().handler(BodyHandler.create())
.handler(rc -> {
try {
Map<String, Object> httpHeader = ProtocolUtil.getData(rc.request().headers());
log.info("request header:{}", JsonUtil.toJsonString(httpHeader));
Map<String, List<Object>> httpParams = ProtocolUtil.getListData(rc.request().params());
log.info("request params:{}", JsonUtil.toJsonString(httpParams));
HttpServerRequest httpRequest = rc.request();
String contentType = httpRequest.headers().get("Content-Type");
String requestBody = "";
int responseCode = 500;
if ("application/json".equals(contentType)) {
requestBody = rc.getBody().toString();
EncodedMessage msg = JsonUtil.parse(requestBody, EncodedMessage.class);
String content = CodecUtil.aesDecrypt(ctwingConfig.getEncryptToken(), msg.getEnc_msg());
log.info("decrypt msg:{}", content);
getHandler().onReceive(httpHeader, "", content);
responseCode = 200;
}
log.info("request body:{}", requestBody);
rc.response().setStatusCode(responseCode)
.end();
} catch (Throwable e) {
log.error("handle request error", e);
rc.response().setStatusCode(500).end();
}
});
backendServer.requestHandler(backendRouter)
.listen(ctwingConfig.getPort(), (http) -> {
if (http.succeeded()) {
log.info("http server create succeed,port:{}", ctwingConfig.getPort());
} else {
log.error("http server create failed", http.cause());
}
});
}
@Override
public DeviceMessage send(DeviceMessage message) {
Object obj = message.getContent();
if (!(obj instanceof Map)) {
throw new BizException("message content is not Map");
}
SendContent msg = new SendContent();
try {
BeanUtils.populate(msg, (Map<String, ? extends Object>) obj);
} catch (Throwable e) {
throw new BizException("message content is incorrect");
}
CreateCommandRequest request = new CreateCommandRequest();
request.setParamMasterKey(msg.getMasterKey());
request.setBody(("{\n" +
" \"content\":{\n" +
" \"dataType\":2,\n" +
" \"payload\":\"" + msg.getPayload() + "\"\n" +
" },\n" +
" \"deviceId\":\"" + message.getDeviceName() + "\",\n" +
" \"operator\":\"none\",\n" +
" \"productId\":" + msg.getProductId() + ",\n" +
" \"ttl\":0,\n" +
" \"level\":1\n" +
"}").getBytes());
CreateCommandResponse response;
try {
response = commandClient.CreateCommand(request);
} catch (Exception e) {
throw new RuntimeException("send cmd to ctwing error", e);
}
String body = new String(response.getBody());
log.info("send ctwing cmd result:{}", body);
if (response.getStatusCode() != 200) {
throw new RuntimeException("send cmd to ctwing error:" + body);
}
CtwingCmdRsp cmdRsp = JsonUtil.parse(body, CtwingCmdRsp.class);
if (cmdRsp.code != 0) {
throw new RuntimeException("send cmd to ctwing failed:" + body);
}
return message;
}
@Override
public void stop() {
backendServer.close();
}
@Override
public void destroy() {
}
/**
* 68H16Hjs
*/
public String encode68H16H(String devId, String cardNo, Object[] values) {
return ProtocolUtil.encode68H16H(devId, cardNo, values);
}
/**
* 68H16Hbase64mapjs
*/
public Map<String, Object> decode68H16H(String base64Str) {
return ProtocolUtil.decode68H16H(base64Str);
}
@Data
public static class EncodedMessage {
private String msg_signature;
private String enc_msg;
}
@Data
public static class SendContent {
private String masterKey;
private String productId;
private String payload;
}
@Data
public static class CtwingCmdRsp {
private int code;
protected String msg;
protected CmdResult result;
}
@Data
public static class CmdResult {
private String commandId;
private String command;
private String commandStatus;
private int productId;
private String deviceId;
private String imei;
private String createBy;
private String createTime;
private int ttl;
}
}

Some files were not shown because too many files have changed in this diff Show More