Merge branch 'dev'

V0.5.x
xiwa 2022-06-07 00:02:58 +08:00
commit 364535dc0a
38 changed files with 757 additions and 46 deletions

View File

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

View File

@ -43,12 +43,12 @@ public interface Constants {
/**
*
*/
String ROLE_SYSTEM = "iot_system_user";
String ROLE_SYSTEM = "iot_system";
/**
* C
*/
String ROLE_CLIENT = "iot_client_user";
String ROLE_CLIENT = "iot_client";
/**
* C

View File

@ -15,7 +15,7 @@ public class DeviceUtil {
int maxDnLen = 16;
String dn = deviceNae.replaceAll("[^0-9A-Za-z]", "");
if (dn.length() > maxDnLen) {
dn = dn.substring(dn.length() - maxDnLen);
dn = dn.substring(dn.length() - maxDnLen + 1);
} else {
dn = (dn + "00000000000000000000").substring(0, maxDnLen);
}

View File

@ -94,6 +94,15 @@ public class HexUtil {
return buffer.array();
}
/**
* bytesint
*/
public static int bytesToInt(byte[] bytes) {
ByteBuffer buffer = ByteBuffer.wrap(bytes);
buffer.flip();
return buffer.getInt();
}
public static int checkSum(ByteBuffer buffer) {
buffer.flip();
byte sum = 0;
@ -209,4 +218,85 @@ public class HexUtil {
return add33Bytes(HexUtil.parseHex(bcdString(strV)));
}
/**
* CRC16
*
* @param data
* @param offset
* @param len
* @return CRC16
*/
public static int calcCrc16(byte[] data, int offset, int len) {
byte[] crc16_tab_h = {
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
(byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
(byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
(byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
(byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40
};
byte[] crc16_tab_l = {
(byte) 0x00, (byte) 0xC0, (byte) 0xC1, (byte) 0x01, (byte) 0xC3, (byte) 0x03, (byte) 0x02, (byte) 0xC2, (byte) 0xC6, (byte) 0x06,
(byte) 0x07, (byte) 0xC7, (byte) 0x05, (byte) 0xC5, (byte) 0xC4, (byte) 0x04, (byte) 0xCC, (byte) 0x0C, (byte) 0x0D, (byte) 0xCD,
(byte) 0x0F, (byte) 0xCF, (byte) 0xCE, (byte) 0x0E, (byte) 0x0A, (byte) 0xCA, (byte) 0xCB, (byte) 0x0B, (byte) 0xC9, (byte) 0x09,
(byte) 0x08, (byte) 0xC8, (byte) 0xD8, (byte) 0x18, (byte) 0x19, (byte) 0xD9, (byte) 0x1B, (byte) 0xDB, (byte) 0xDA, (byte) 0x1A,
(byte) 0x1E, (byte) 0xDE, (byte) 0xDF, (byte) 0x1F, (byte) 0xDD, (byte) 0x1D, (byte) 0x1C, (byte) 0xDC, (byte) 0x14, (byte) 0xD4,
(byte) 0xD5, (byte) 0x15, (byte) 0xD7, (byte) 0x17, (byte) 0x16, (byte) 0xD6, (byte) 0xD2, (byte) 0x12, (byte) 0x13, (byte) 0xD3,
(byte) 0x11, (byte) 0xD1, (byte) 0xD0, (byte) 0x10, (byte) 0xF0, (byte) 0x30, (byte) 0x31, (byte) 0xF1, (byte) 0x33, (byte) 0xF3,
(byte) 0xF2, (byte) 0x32, (byte) 0x36, (byte) 0xF6, (byte) 0xF7, (byte) 0x37, (byte) 0xF5, (byte) 0x35, (byte) 0x34, (byte) 0xF4,
(byte) 0x3C, (byte) 0xFC, (byte) 0xFD, (byte) 0x3D, (byte) 0xFF, (byte) 0x3F, (byte) 0x3E, (byte) 0xFE, (byte) 0xFA, (byte) 0x3A,
(byte) 0x3B, (byte) 0xFB, (byte) 0x39, (byte) 0xF9, (byte) 0xF8, (byte) 0x38, (byte) 0x28, (byte) 0xE8, (byte) 0xE9, (byte) 0x29,
(byte) 0xEB, (byte) 0x2B, (byte) 0x2A, (byte) 0xEA, (byte) 0xEE, (byte) 0x2E, (byte) 0x2F, (byte) 0xEF, (byte) 0x2D, (byte) 0xED,
(byte) 0xEC, (byte) 0x2C, (byte) 0xE4, (byte) 0x24, (byte) 0x25, (byte) 0xE5, (byte) 0x27, (byte) 0xE7, (byte) 0xE6, (byte) 0x26,
(byte) 0x22, (byte) 0xE2, (byte) 0xE3, (byte) 0x23, (byte) 0xE1, (byte) 0x21, (byte) 0x20, (byte) 0xE0, (byte) 0xA0, (byte) 0x60,
(byte) 0x61, (byte) 0xA1, (byte) 0x63, (byte) 0xA3, (byte) 0xA2, (byte) 0x62, (byte) 0x66, (byte) 0xA6, (byte) 0xA7, (byte) 0x67,
(byte) 0xA5, (byte) 0x65, (byte) 0x64, (byte) 0xA4, (byte) 0x6C, (byte) 0xAC, (byte) 0xAD, (byte) 0x6D, (byte) 0xAF, (byte) 0x6F,
(byte) 0x6E, (byte) 0xAE, (byte) 0xAA, (byte) 0x6A, (byte) 0x6B, (byte) 0xAB, (byte) 0x69, (byte) 0xA9, (byte) 0xA8, (byte) 0x68,
(byte) 0x78, (byte) 0xB8, (byte) 0xB9, (byte) 0x79, (byte) 0xBB, (byte) 0x7B, (byte) 0x7A, (byte) 0xBA, (byte) 0xBE, (byte) 0x7E,
(byte) 0x7F, (byte) 0xBF, (byte) 0x7D, (byte) 0xBD, (byte) 0xBC, (byte) 0x7C, (byte) 0xB4, (byte) 0x74, (byte) 0x75, (byte) 0xB5,
(byte) 0x77, (byte) 0xB7, (byte) 0xB6, (byte) 0x76, (byte) 0x72, (byte) 0xB2, (byte) 0xB3, (byte) 0x73, (byte) 0xB1, (byte) 0x71,
(byte) 0x70, (byte) 0xB0, (byte) 0x50, (byte) 0x90, (byte) 0x91, (byte) 0x51, (byte) 0x93, (byte) 0x53, (byte) 0x52, (byte) 0x92,
(byte) 0x96, (byte) 0x56, (byte) 0x57, (byte) 0x97, (byte) 0x55, (byte) 0x95, (byte) 0x94, (byte) 0x54, (byte) 0x9C, (byte) 0x5C,
(byte) 0x5D, (byte) 0x9D, (byte) 0x5F, (byte) 0x9F, (byte) 0x9E, (byte) 0x5E, (byte) 0x5A, (byte) 0x9A, (byte) 0x9B, (byte) 0x5B,
(byte) 0x99, (byte) 0x59, (byte) 0x58, (byte) 0x98, (byte) 0x88, (byte) 0x48, (byte) 0x49, (byte) 0x89, (byte) 0x4B, (byte) 0x8B,
(byte) 0x8A, (byte) 0x4A, (byte) 0x4E, (byte) 0x8E, (byte) 0x8F, (byte) 0x4F, (byte) 0x8D, (byte) 0x4D, (byte) 0x4C, (byte) 0x8C,
(byte) 0x44, (byte) 0x84, (byte) 0x85, (byte) 0x45, (byte) 0x87, (byte) 0x47, (byte) 0x46, (byte) 0x86, (byte) 0x82, (byte) 0x42,
(byte) 0x43, (byte) 0x83, (byte) 0x41, (byte) 0x81, (byte) 0x80, (byte) 0x40
};
int pre = 0xffff;
int ucCRCHi = (pre & 0xff00) >> 8;
int ucCRCLo = pre & 0x00ff;
int iIndex;
for (int i = 0; i < len; ++i) {
iIndex = (ucCRCLo ^ data[offset + i]) & 0x00ff;
ucCRCLo = ucCRCHi ^ crc16_tab_h[iIndex];
ucCRCHi = crc16_tab_l[iIndex];
}
return ((ucCRCHi & 0x00ff) << 8) | (ucCRCLo & 0x00ff) & 0xffff;
}
}

View File

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

View File

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

View File

@ -5,9 +5,13 @@ import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.utils.CodecUtil;
import cc.iotkit.common.utils.ReflectUtil;
import cc.iotkit.dao.AligenieDeviceRepository;
import cc.iotkit.dao.HomeRepository;
import cc.iotkit.dao.SpaceRepository;
import cc.iotkit.dao.UserInfoRepository;
import cc.iotkit.manager.service.DataOwnerService;
import cc.iotkit.manager.service.PulsarAdminService;
import cc.iotkit.model.space.Home;
import cc.iotkit.model.space.Space;
import cc.iotkit.utils.AuthUtil;
import cc.iotkit.model.UserInfo;
import cn.dev33.satoken.annotation.SaCheckRole;
@ -28,6 +32,10 @@ public class UserInfoController {
private AligenieDeviceRepository aligenieDeviceRepository;
@Autowired
private DataOwnerService ownerService;
@Autowired
private HomeRepository homeRepository;
@Autowired
private SpaceRepository spaceRepository;
/**
@ -76,7 +84,27 @@ public class UserInfoController {
user.setRoles(Collections.singletonList(Constants.ROLE_CLIENT));
user.setCreateAt(System.currentTimeMillis());
user.setSecret(AuthUtil.enCryptPwd(Constants.PWD_CLIENT_USER));
userInfoRepository.save(user);
user = userInfoRepository.save(user);
//添加默认家庭
Home home = homeRepository.save(Home.builder()
.name("我的家庭")
.address("")
.deviceNum(0)
.spaceNum(0)
.uid(user.getId())
.current(true)
.build());
//添加默认房间
for (String name : new String[]{"客厅", "卧室", "厨房"}) {
spaceRepository.save(Space.builder()
.homeId(home.getId())
.name(name)
.uid(user.getId())
.createAt(System.currentTimeMillis())
.build());
}
}
@PostMapping("/client/user/{id}/delete")

View File

@ -5,9 +5,9 @@
<parent>
<artifactId>iotkit-parent</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
</parent>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<artifactId>model</artifactId>

View File

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

View File

@ -23,7 +23,7 @@
<groupId>cc.iotkit</groupId>
<artifactId>iotkit-parent</artifactId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
<name>iotkit-parent</name>
<description>iotkit parent</description>
<properties>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>protocol-gateway</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -135,6 +135,7 @@ public class DeviceComponentManager {
deviceBehaviourService, deviceRouter);
messageHandler.putScriptEnv("apiTool", new ApiTool());
messageHandler.putScriptEnv("deviceBehaviour", deviceBehaviourService);
messageHandler.putScriptEnv("component", component);
component.setHandler(messageHandler);
component.start();
@ -178,19 +179,36 @@ public class DeviceComponentManager {
}
IDeviceComponent deviceComponent = (IDeviceComponent) component;
Device device = new Device(deviceInfo.getDeviceId(), deviceInfo.getModel(), product.isTransparent());
//构建必要的设备信息
Map<String, Object> tag = new HashMap<>();
deviceInfo.getTag().forEach((k, v) -> tag.put(k, v.getValue()));
Device device = new Device(deviceInfo.getDeviceId(),
deviceInfo.getModel(),
deviceInfo.getProperty(),
tag,
product.isTransparent());
//对下发消息进行编码转换
DeviceMessage message = deviceComponent.getConverter().encode(service, device);
if (message == null) {
throw new BizException("encode send message failed");
}
//保存设备端mid与平台mid对应关系
redisTemplate.opsForValue().set(
CacheKey.getKeyCmdMid(message.getDeviceName(), message.getMid()),
service.getMid(), deviceComponent.getConfig().getCmdTimeout(), TimeUnit.SECONDS);
//发送消息给设备
deviceComponent.send(message);
String sendMid = message.getMid();
long timeout=deviceComponent.getConfig().getCmdTimeout();
//保存设备端mid与平台mid对应关系
saveMidMapping(message,timeout,service.getMid());
//发送消息给设备
message = deviceComponent.send(message);
//mid发生改变
if (!sendMid.equals(message.getMid())) {
//重新保存消息id映射
saveMidMapping(message,timeout,service.getMid());
}
//产生下发消息
ThingModelMessage thingModelMessage = ThingModelMessage.builder()
.mid(service.getMid())
.productKey(service.getProductKey())
@ -202,6 +220,15 @@ public class DeviceComponentManager {
deviceBehaviourService.reportMessage(thingModelMessage);
}
/**
* midmid
*/
private void saveMidMapping(DeviceMessage message, long cmdTimeout, String serviceMid) {
redisTemplate.opsForValue().set(
CacheKey.getKeyCmdMid(message.getDeviceName(), message.getMid()),
serviceMid, cmdTimeout, TimeUnit.SECONDS);
}
public String getPlatformMid(String deviceName, String mid) {
return redisTemplate.opsForValue().get(CacheKey.getKeyCmdMid(deviceName, mid));
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>protocol-gateway</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -19,7 +19,7 @@ public abstract class AbstractDeviceComponent implements IDeviceComponent {
protected String script;
private String id;
protected String id;
@Override
public void create(CompConfig config) {

View File

@ -14,7 +14,7 @@ public interface IDeviceComponent extends IComponent {
void onDeviceStateChange(DeviceState state);
void send(DeviceMessage message);
DeviceMessage send(DeviceMessage message);
void setHandler(IMessageHandler handler);

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>protocol-gateway</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -4,6 +4,9 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.HashMap;
import java.util.Map;
@Data
@NoArgsConstructor
@AllArgsConstructor
@ -13,6 +16,10 @@ public class Device {
private String model;
private Map<String, Object> property = new HashMap<>();
private Map<String, Object> tag = new HashMap<>();
/**
*
*/

View File

@ -0,0 +1,84 @@
<?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/maven-v4_0_0.xsd">
<parent>
<artifactId>protocol-gateway</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.2.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ctwing-component</artifactId>
<build>
<plugins>
<plugin>
<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>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-proxy</artifactId>
<version>4.2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>component</artifactId>
<version>0.2.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.ctg.ag</groupId>
<artifactId>ctg-ag-sdk-core</artifactId>
<version>2.5.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.ctg.ag</groupId>
<artifactId>ag-sdk-biz-84356.tar.gz</artifactId>
<version>20220603.182201-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>8</maven.compiler.source>
</properties>
</project>

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>protocol-gateway</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.2.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>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>cc.iotkit</groupId>
<artifactId>component</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>
</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>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,25 @@
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,197 @@
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;
}
}

View File

@ -0,0 +1,120 @@
package cc.iotkit.comp.http;
import cc.iotkit.common.utils.HexUtil;
import io.vertx.core.MultiMap;
import java.nio.ByteBuffer;
import java.util.*;
public class ProtocolUtil {
/**
* 68H16H
*/
public static String encode68H16H(String devId, String cardNo, Object[] values) {
//构建数据域
ByteBuffer bufferData = ByteBuffer.allocate(7);
//模拟数据..
bufferData.put((byte) 1);
bufferData.putShort((short) 4);
bufferData.putInt(100);
byte[] data = bufferData.array();
//起始符到卡号部分数据
ByteBuffer buffer = ByteBuffer.allocate(1 + 2 + 5 + data.length + 4 + 7 + 2);
int len = 1 + 2 + 5 + data.length + 4 + 7 + 2;
buffer.put((byte) len);
buffer.put((byte) 0x68);
buffer.putShort((short) 0);
buffer.put(devId.getBytes());
buffer.put(data);
buffer.putInt(0);
buffer.put(cardNo.getBytes());
byte[] data1 = buffer.array();
//校验码
int check = HexUtil.calcCrc16(data1, 0, data1.length);
//完整数据包
buffer = ByteBuffer.allocate(1 + data1.length + 2 + 1);
buffer.put((byte) (data1.length + 2));//帧长度
buffer.put(data1);//起始符到卡号部分数据
buffer.putShort((short) check);//检验码
buffer.put((byte) 0x16);
return HexUtil.toHexString(buffer.array());
}
/**
* 68H16Hbase64map
*/
public static Map<String, Object> decode68H16H(String base64Str) {
byte[] bytes = Base64.getDecoder().decode(base64Str);
Map<String, Object> decodeData = new HashMap<>();
ByteBuffer buffer = ByteBuffer.wrap(bytes);
buffer.flip();
byte len = buffer.get();//帧长度
buffer.get();//帧起始符
buffer.getShort();//预留2byte
byte[] devId = new byte[5];//设备ID
buffer.get(devId, 0, 5);
String strDevId = new String(devId);
decodeData.put("devId", strDevId);
//数据域长度=帧长度-起始符-预留-设备ID-系统用-卡号-校验码
int dataLen = len - 1 - 2 - 5 - 4 - 7 - 2;
//数据域
byte[] data = new byte[dataLen];
buffer.get(data, 0, dataLen);
Object[] values = ProtocolUtil.getTlvValues(data);
//模拟取1个值
decodeData.put("flow", values[0]);
buffer.getInt();//系统用
//卡号
byte[] card = new byte[7];
buffer.get(card, 0, card.length);
String cardNo = new String(card);
decodeData.put("cardNo", cardNo);
return decodeData;
}
public static Object[] getTlvValues(byte[] data) {
List<Object> result = new ArrayList<>();
ByteBuffer dataBuff = ByteBuffer.wrap(data);
dataBuff.flip();
//对数据域解码...
while (dataBuff.hasRemaining()) {
byte t = dataBuff.get();
byte l = dataBuff.get();
byte[] bytesV = new byte[l];
dataBuff.get(bytesV, 0, bytesV.length);
if (t == 0) {
//int
result.add(HexUtil.bytesToInt(bytesV));
}
//..其它类型
}
return result.toArray();
}
public static Map<String, List<Object>> getListData(MultiMap multiMap) {
Map<String, List<Object>> listData = new HashMap<>();
for (Map.Entry<String, String> entry : multiMap.entries()) {
String key = entry.getKey();
Object value = entry.getValue();
listData.putIfAbsent(key, new ArrayList<>());
listData.get(key).add(value);
}
return listData;
}
public static Map<String, Object> getData(MultiMap multiMap) {
Map<String, Object> data = new HashMap<>();
for (Map.Entry<String, String> entry : multiMap.entries()) {
data.put(entry.getKey(), entry.getValue());
}
return data;
}
}

View File

@ -0,0 +1,36 @@
//引用api工具类
var apiTool = Java.type("cc.iotkit.comp.biz.ApiTool");
//api配置
apiTool.config("http://localhost",8086,3000);
this.onReceive=function(method,path,header,params,body){
//methodpost、get、delete...
//path请求路径
//headerhttp请求头数据,结构:{xx:xx,yy:yy}
//params请求参数结构{xx:[...],yy:[...]}
//body请求体当提交的数据为json格式时使用结构{xx:xx,yy:yy}
apiTool.log("onReceive method:"+method);
apiTool.log("onReceive path:"+path);
apiTool.log("onReceive header:"+header);
apiTool.log("onReceive params:"+params);
apiTool.log("onReceive body:"+body);
var duHeader=body.header;
var namespace=duHeader.namespace;
var requestName=duHeader.name;
var messageId=duHeader.messageId;
var duPayload=duHeader.payload;
var token=duHeader.accessToken;
//设备发现
if(namespace=="DuerOS.ConnectedHome.Discovery" && requestName=="DiscoverAppliancesRequest"){
}
return {
url:"xx",//不指定直接作为响应返回
header:{
contentType:"xx"
},
content:"xx"
}
}

View File

@ -0,0 +1 @@
cc.iotkit.comp.http.CtwingDeviceComponent

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>protocol-gateway</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>emqx-component</artifactId>
@ -76,19 +76,19 @@
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>model</artifactId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>common</artifactId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>component</artifactId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
@ -100,7 +100,7 @@
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>dao</artifactId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>protocol-gateway</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -181,7 +181,7 @@ public class EmqxDeviceComponent extends AbstractDeviceComponent {
}
@Override
public void send(DeviceMessage message) {
public DeviceMessage send(DeviceMessage message) {
Object obj = message.getContent();
if (!(obj instanceof Map)) {
throw new BizException("message content is not Map");
@ -201,6 +201,8 @@ public class EmqxDeviceComponent extends AbstractDeviceComponent {
MqttQoS.AT_LEAST_ONCE,
false,
false);
return message;
}
/**

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>protocol-gateway</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>http-biz-component</artifactId>
@ -58,7 +58,7 @@
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>component</artifactId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>protocol-gateway</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>protocol-gateway</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<description>mqtt客户端模拟器</description>

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>protocol-gateway</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mqtt-component</artifactId>
@ -80,19 +80,19 @@
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>common</artifactId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>component</artifactId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>dao</artifactId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>protocol-gateway</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -87,7 +87,7 @@ public class MqttDeviceComponent extends AbstractDeviceComponent {
}
@Override
public void send(DeviceMessage message) {
public DeviceMessage send(DeviceMessage message) {
Device child = new Device(message.getProductKey(), message.getDeviceName());
//作为子设备查找父设备
Device parent = deviceChildToParent.get(child.toString());
@ -108,6 +108,8 @@ public class MqttDeviceComponent extends AbstractDeviceComponent {
log.info("publish topic:{},payload:{}", msg.getTopic(), msg.getPayload());
mqttVerticle.publish(parent.getProductKey(), parent.getDeviceName(),
msg.getTopic(), msg.getPayload());
return message;
}
@Override

View File

@ -8,7 +8,6 @@ import io.netty.handler.codec.mqtt.MqttProperties;
import io.netty.handler.codec.mqtt.MqttQoS;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.PemKeyCertOptions;
import io.vertx.mqtt.*;
@ -30,7 +29,7 @@ public class MqttVerticle extends AbstractVerticle {
private IMessageHandler executor;
private Map<String, MqttEndpoint> endpointMap = new HashMap<>();
private final Map<String, MqttEndpoint> endpointMap = new HashMap<>();
public MqttVerticle(MqttConfig config) {
this.config = config;

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iotkit-parent</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.2.0-SNAPSHOT</version>
<version>0.2.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -19,6 +19,7 @@
<module>component</module>
<module>mqtt-client-simulator</module>
<module>http-biz-component</module>
<module>ctwing-component</module>
</modules>
</project>

View File

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

View File

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

View File

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