diff --git a/tuya-messaging/src/main/java/com/tuya/connector/open/messaging/MessageFactory.java b/tuya-messaging/src/main/java/com/tuya/connector/open/messaging/MessageFactory.java
new file mode 100644
index 0000000..2571e39
--- /dev/null
+++ b/tuya-messaging/src/main/java/com/tuya/connector/open/messaging/MessageFactory.java
@@ -0,0 +1,65 @@
+package com.tuya.connector.open.messaging;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.tuya.connector.open.messaging.event.BaseTuyaMessage;
+import com.tuya.connector.open.messaging.event.UnknownMessage;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.reflections.Reflections;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ *
TODO
+ *
+ * @author 丘枫(余秋风 qiufeng.yu@tuya.com)
+ * @since 2021/3/24 3:56 下午
+ */
+@Slf4j
+public class MessageFactory {
+
+ private static Map> messageHandler = new HashMap<>();
+
+ static {
+ Reflections reflections = new Reflections("com.tuya.connector.open.messaging.event");
+ Set> classSet = reflections.getSubTypesOf(BaseTuyaMessage.class);
+ classSet.forEach(handler -> {
+ try {
+ BaseTuyaMessage baseTuyaMessage = handler.newInstance();
+ messageHandler.put(baseTuyaMessage.type(), handler);
+ } catch (Exception ignore) {
+ log.error("ignore {} handler.", handler.getSimpleName());
+ }
+ });
+ }
+
+ @SneakyThrows
+ public static BaseTuyaMessage extract(SourceMessage sourceMessage, String sk) {
+ String data;
+ if (sourceMessage.getEncryptPayload() != null) {
+ // problem left over by history
+ data = sourceMessage.getEncryptPayload();
+ } else {
+ data = sourceMessage.getData();
+ }
+ String decryptData = AESBase64Utils.decrypt(data, sk.substring(8, 24));
+ JSONObject messageBody = JSON.parseObject(decryptData);
+ String bizCode = null;
+ if (Objects.nonNull(messageBody) && messageBody.size() > 0) {
+ bizCode = messageBody.getString("bizCode");
+ }
+ return generate(bizCode, sourceMessage, messageBody);
+ }
+
+ @SneakyThrows
+ public static BaseTuyaMessage generate(String bizCode, SourceMessage sourceMessage, JSONObject messageBody) {
+ Class extends BaseTuyaMessage> msgHandler = messageHandler.getOrDefault(bizCode, UnknownMessage.class);
+ BaseTuyaMessage tuyaMessage = msgHandler.newInstance();
+ tuyaMessage.defaultBuild(sourceMessage, messageBody);
+ return tuyaMessage;
+ }
+}
diff --git a/tuya-spring-boot-starter-sample/src/main/java/com/tuya/open/spring/boot/sample/TuyaSpringBootStarterSampleApplication.java b/tuya-spring-boot-starter-sample/src/main/java/com/tuya/open/spring/boot/sample/TuyaSpringBootStarterSampleApplication.java
index ef67ff7..0d2a2f8 100644
--- a/tuya-spring-boot-starter-sample/src/main/java/com/tuya/open/spring/boot/sample/TuyaSpringBootStarterSampleApplication.java
+++ b/tuya-spring-boot-starter-sample/src/main/java/com/tuya/open/spring/boot/sample/TuyaSpringBootStarterSampleApplication.java
@@ -1,12 +1,11 @@
package com.tuya.open.spring.boot.sample;
-import com.tuya.connector.open.messaging.autoconfig.EnableMessaging;
import com.tuya.connector.spring.annotations.ConnectorScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@ConnectorScan(basePackages = "com.tuya.open.spring.boot.sample.ability.api")
-@EnableMessaging(msgPaths = {"com.tuya.open.spring.boot.sample.ability.messaging.msg"})
+//@EnableMessaging(msgPaths = {"com.tuya.open.spring.boot.sample.ability.messaging.msg"})
@SpringBootApplication
public class TuyaSpringBootStarterSampleApplication {
diff --git a/tuya-spring-boot-starter-sample/src/main/java/com/tuya/open/spring/boot/sample/ability/api/ThingConnector.java b/tuya-spring-boot-starter-sample/src/main/java/com/tuya/open/spring/boot/sample/ability/api/ThingConnector.java
new file mode 100644
index 0000000..509397d
--- /dev/null
+++ b/tuya-spring-boot-starter-sample/src/main/java/com/tuya/open/spring/boot/sample/ability/api/ThingConnector.java
@@ -0,0 +1,46 @@
+package com.tuya.open.spring.boot.sample.ability.api;
+
+import com.tuya.connector.api.annotations.Body;
+import com.tuya.connector.api.annotations.GET;
+import com.tuya.connector.api.annotations.POST;
+import com.tuya.connector.api.annotations.Path;
+import com.tuya.connector.api.model.Result;
+import com.tuya.open.spring.boot.sample.ability.model.DeviceDetail;
+import com.tuya.open.spring.boot.sample.ability.model.DeviceProperties;
+import com.tuya.open.spring.boot.sample.ability.model.DeviceSpecification;
+import com.tuya.open.spring.boot.sample.ability.model.Firmware;
+
+import java.util.List;
+import java.util.Map;
+
+public interface ThingConnector {
+ @GET("/v2.0/cloud/thing/{device_id}")
+ Result getDeviceResult(@Path("device_id") String deviceId);
+
+ @GET("/v2.0/cloud/thing/{device_id}")
+ DeviceDetail getDevice(@Path("device_id") String deviceId);
+
+ @GET("/v1.1/iot-03/devices/{device_id}")
+ DeviceDetail getIndustryDevice(@Path("device_id") String deviceId);
+
+ @GET("/v2.0/cloud/thing/{device_id}/firmware")
+ List getFirmware(@Path("device_id") String deviceId);
+
+ @GET("/v1.0/iot-03/devices/{device_id}/properties")
+ List