Skip to content

Commit

Permalink
feat: 消息订阅
Browse files Browse the repository at this point in the history
  • Loading branch information
yuqiufeng committed Oct 24, 2024
1 parent 0089178 commit 25424c5
Show file tree
Hide file tree
Showing 16 changed files with 618 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -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;

/**
* <p> TODO
*
* @author 丘枫(余秋风 qiufeng.yu@tuya.com)
* @since 2021/3/24 3:56 下午
*/
@Slf4j
public class MessageFactory {

private static Map<String, Class<? extends BaseTuyaMessage>> messageHandler = new HashMap<>();

static {
Reflections reflections = new Reflections("com.tuya.connector.open.messaging.event");
Set<Class<? extends BaseTuyaMessage>> 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;
}
}
Original file line number Diff line number Diff line change
@@ -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 {

Expand Down
Original file line number Diff line number Diff line change
@@ -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<DeviceDetail> 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<Firmware> getFirmware(@Path("device_id") String deviceId);

@GET("/v1.0/iot-03/devices/{device_id}/properties")
List<Map<String, Object>> getDeviceExtProperties(@Path("device_id") String deviceId);

@GET("/v1.0/iot-03/devices/{device_id}/specification")
DeviceSpecification getDeviceSpecification(@Path("device_id") String deviceId);

@GET("/v2.0/cloud/thing/{device_id}/model")
Map<String, String> getDeviceModel(@Path("device_id") String deviceId);

@GET("/v2.0/cloud/thing/{device_id}/shadow/properties")
DeviceProperties getDeviceProperties(@Path("device_id") String deviceId);

@GET("/v2.0/cloud/thing/{device_id}/state")
Map<String, Object> getDeviceState(@Path("device_id") String deviceId);

@POST("/v2.0/cloud/thing/{device_id}/shadow/properties/issue")
Result<Void> issueDeviceProperties(@Path("device_id") String deviceId, @Body Map<String, Object> param);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import com.tuya.connector.open.messaging.event.NameUpdateMessage;
import com.tuya.connector.open.messaging.event.StatusReportMessage;
import com.tuya.open.spring.boot.sample.ability.messaging.msg.DeviceNameUpdate;
import com.tuya.open.spring.boot.sample.ability.messaging.msg.DeviceOfflineMessage;
import com.tuya.open.spring.boot.sample.ability.messaging.msg.DeviceOnlineMessage;
import com.tuya.open.spring.boot.sample.ability.messaging.msg.DevicePropertyMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
Expand All @@ -17,12 +20,12 @@
@Component
public class TuyaMessageListener {

@EventListener
// @EventListener
public void updateStatusEvent(StatusReportMessage message) {
log.info("StatusReport event happened: {}", message);
}

@EventListener
// @EventListener
public void nameUpdateMessage(NameUpdateMessage message) {
log.info("NameUpdate event happened: {}", message);
}
Expand All @@ -32,4 +35,20 @@ public void deviceNameUpdateMsg(DeviceNameUpdate message) {
log.info("deviceNameUpdateMsg event happened: {}", message);
}

@EventListener
public void deviceOfflineMsg(DeviceOfflineMessage msg) {
log.warn("pulsar msg, DeviceOfflineMessage:{}", msg);
}

@EventListener
public void deviceOnlineMsg(DeviceOnlineMessage msg) {
log.warn("pulsar msg, DeviceOnlineMessage:{}", msg);
}

@EventListener
public void devicePropertyMsg(DevicePropertyMessage msg) {
log.warn("pulsar msg, DevicePropertyMessage:{}", msg);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@
public class DeviceNameUpdate extends BaseTuyaMessage {

private String devId;
private String produceId;
private String productId;
private String uid;
private String name;
private String uuid;

@Override
public void defaultBuild(SourceMessage sourceMessage, JSONObject messageBody) {
super.defaultBuild(sourceMessage, messageBody);
this.devId = messageBody.getString("devId");
this.produceId = messageBody.getString("produceId");
this.uid = messageBody.getString("uid");
this.name = messageBody.getString("name");
this.uuid = messageBody.getString("uuid");
this.devId = messageBody.getJSONObject("bizData").getString("devId");
this.productId = messageBody.getJSONObject("bizData").getString("productId");
this.uid = messageBody.getJSONObject("bizData").getString("uid");
this.name = messageBody.getJSONObject("bizData").getString("name");
this.uuid = messageBody.getJSONObject("bizData").getString("uuid");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.tuya.open.spring.boot.sample.ability.messaging.msg;

import com.alibaba.fastjson.JSONObject;
import com.tuya.connector.open.messaging.SourceMessage;
import com.tuya.connector.open.messaging.event.BaseTuyaMessage;
import lombok.Getter;
import lombok.Setter;

@Getter @Setter
public class DeviceOfflineMessage extends BaseTuyaMessage {
private String devId;
private String productId;
private String uid;
private Long time;

@Override
public void defaultBuild(SourceMessage sourceMessage, JSONObject messageBody) {
super.defaultBuild(sourceMessage, messageBody);
this.devId = messageBody.getJSONObject("bizData").getString("devId");
this.productId = messageBody.getJSONObject("bizData").getString("productId");
this.uid = messageBody.getJSONObject("bizData").getString("uid");
this.time = messageBody.getJSONObject("bizData").getLong("time");
}

@Override
public String type() {
return "deviceOffline";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.tuya.open.spring.boot.sample.ability.messaging.msg;

import com.alibaba.fastjson.JSONObject;
import com.tuya.connector.open.messaging.SourceMessage;
import com.tuya.connector.open.messaging.event.BaseTuyaMessage;
import lombok.Getter;
import lombok.Setter;

@Getter @Setter
public class DeviceOnlineMessage extends BaseTuyaMessage {
private String devId;
private String productId;
private String uid;
private Long time;

@Override
public void defaultBuild(SourceMessage sourceMessage, JSONObject messageBody) {
super.defaultBuild(sourceMessage, messageBody);
this.devId = messageBody.getJSONObject("bizData").getString("devId");
this.productId = messageBody.getJSONObject("bizData").getString("productId");
this.uid = messageBody.getJSONObject("bizData").getString("uid");
this.time = messageBody.getJSONObject("bizData").getLong("time");
}

@Override
public String type() {
return "deviceOnline";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.tuya.open.spring.boot.sample.ability.messaging.msg;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tuya.connector.open.messaging.SourceMessage;
import com.tuya.connector.open.messaging.event.BaseTuyaMessage;
import lombok.Getter;
import lombok.Setter;

import java.io.Serial;
import java.io.Serializable;
import java.util.List;

@Getter @Setter
public class DevicePropertyMessage extends BaseTuyaMessage {

private String dataId;
private String devId;
private String productId;
private List<PropertyItem> properties;

@Override
public void defaultBuild(SourceMessage sourceMessage, JSONObject messageBody) {
super.defaultBuild(sourceMessage, messageBody);
this.dataId = messageBody.getJSONObject("bizData").getString("dataId");
this.devId = messageBody.getJSONObject("bizData").getString("devId");
this.productId = messageBody.getJSONObject("bizData").getString("productId");
JSONArray jsonArray = messageBody.getJSONObject("bizData").getJSONArray("properties");
if (jsonArray != null) {
properties = jsonArray.stream().map(
item -> {
JSONObject jsonObject = (JSONObject) item;
PropertyItem propertyItem = new PropertyItem();
propertyItem.setCode(jsonObject.getString("code"));
propertyItem.setValue(jsonObject.get("value"));
propertyItem.setDpId(jsonObject.getString("dpId"));
propertyItem.setTime(jsonObject.getLong("time"));
return propertyItem;
}
).toList();
}
}

@Override
public String type() {
return "devicePropertyMessage";
}

@Getter @Setter
class PropertyItem implements Serializable {

@Serial
private static final long serialVersionUID = -5316969945618066530L;

private String code;
private Object value;
private String dpId;
private Long time;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.tuya.open.spring.boot.sample.ability.model;

import lombok.Data;

import java.io.Serial;
import java.io.Serializable;

@Data
public class DeviceDetail implements Serializable {

@Serial
private static final long serialVersionUID = -1389103173186462562L;

private String id; // 设备 ID
private Long activeTime; // 设备的激活时间(时间戳秒数)
private String category; // 设备的产品品类
private Long createTime; // 设备的初次配网时间(时间戳秒数)
private Long updateTime; // 设备的更新时间(时间戳秒数)
private String customName; // 设备的自定义名称
private String icon; // 设备的图标
private String ip; // 设备的 IP 地址
private Boolean isOnline; // 设备的在线状态
private Boolean online; // 设备的在线状态
private String lat; // 设备的纬度
private String localKey; // 设备的局域网加密后的唯一密钥
private String lon; // 设备的经度
private String name; // 设备的名称
private String productId; // 设备的产品 ID
private String productName; // 设备的产品名称
private Boolean sub; // 是否为子设备
private String timeZone; // 设备的时区
private String uuid; // 设备的 UUID
private String bindSpaceId; // 空间 Id
private String gatewayId; // 网关 ID
private String nodeId; // 设备的节点 ID
private String assetId; // 设备的资产 ID
private String model; // 设备的型号
private String sn; // 设备的序列号

}
Loading

0 comments on commit 25424c5

Please sign in to comment.