TuyaLink 设备

更新时间:2023-04-13 09:36:19下载pdf

TuyaLink 生态设备接入是面向物联网生态领域(自研模组/成品智能设备)全面开放的设备上云解决方案。通过此方案可以快速加入涂鸦生态体系,实现跨领域设备间互连互通,并可使用平台丰富的 PaaS、SaaS 和 App 等应用开发能力,最大程度地降低物联网整体解决方案的落地实施成本,减少开发周期。更多详情,请参考 生态设备接入

判断 TuyaLink 设备

接口说明

boolean isSupportThingModelDevice();

代码示例:

public void judgeSupportThingLink(){
	// DeviceBean deviceBean = ThingOSDevice.getDeviceBean("your_device_id");
  
  boolean isSupport =	deviceBean.isSupportThingModelDevice();
	Log.i("judgeSupportThingLink", isSupport);
}

物模型

涂鸦 IoT 开发平台 针对物理实体设备在云端建立的数据模型,主要用于描述产品的功能。

它主要通过定义一款产品设备所应具备的基本状态(属性)、可以被外部系统调用的复杂指令(动作),以及在运行过程中产生的各种事件状态(事件)。这三种功能类型的集合用来表示一个物理实体设备,在云端的数据展现。

功能类型 说明
属性 (Property) 属性主要用于定义设备具有持续性、可查询等特点的状态,它代表设备的某个或者某几个功能参数。属性可以通过设置读写操作来实现对设备功能参数的修改和查询。当设备本身的某项功能参数发生变更,设备也可以主动修改属性。如灯的亮度、开关状态等。
动作 (Action) 动作用于控制设备执行复杂的业务功能。 动作是不涉及设备属性变更的控制指令。 这种指令需要设备对其响应,从而对外提供一个可供调用的方法。如人脸识别、照片下发等。
事件 (Event) 事件是设备上报的瞬时通知消息,可以包含多个输出参数,需要被外部感知和处理。事件通常需要搭配数据订阅服务或者与规则引擎结合,对事件信息作出业务逻辑上的处理,以满足特定的功能。如水温报警、故障报警等。

特别注意

目前,物模型信息是按需获取机制,请在合适的时机检查物模型本地缓存,并在适当的时候 获取并更新 物模型缓存。

接口说明

获取物模型

DeviceBean{
	// ....
	// 属性获取设备的物模型本地缓存
	ThingSmartThingModel thingModel;
}


示例

ThingSmartThingModel thingModel = ThingOSDevice.getDeviceBean("your_device_id").getThingModel();

物模型接口请求并保存


IThingDeviceOperator.java
/**
     * Get thing model from cloud and update cache.通过pid查询
     * @param pid
     * @param callback Called when the task is finished or interrupted by an error
     */
    void getThingModelWithProductId(String pid,IThingDataCallback<ThingSmartThingModel> callback);

    /**
     * Get thing model from cloud and update cache. 通过pid + productVersion查询
     * @param pid
     * @param productVersion
     * @param callback Called when the task is finished or interrupted by an error
     */
    void getThingModelWithProductId(String pid, String productVersion,IThingDataCallback<ThingSmartThingModel> callback);

示例


ThingOsDevice.getDeviceOperator().getThingModelWithProductId(“pid", new IThingDataCallback<ThingSmartThingModel>() {
            @Override
            public void onSuccess(ThingSmartThingModel result) {
                
            }

            @Override
            public void onError(String errorCode, String errorMessage) {

            }
        });
    }

ThingSmartThingModel数据模型

字段 类型 说明
modelId String 物模型id
productId String 产品id
productVersion String 产品id版本
services List 服务模型
extensions Map<String, Object> 扩展信息

ThingSmartThingServiceModel数据模型

字段 类型 说明
properties List 属性
actions List 动作
events List 事件

ThingSmartThingProperty数据模型

字段 类型 说明
abilityId int 属性id
可与普通设备的 dps 的 dpId 对应
code String 属性code
accessMode String 访问模式
rw: 可下发可上报, ro: 仅上报, wr: 仅下发
typeSpec Map<String, Object> 类型定义
defaultValue Object 默认值

附加说明

typeSpec 类型定义

目前 有 valuestringdateboolenumfault(bitmap)arraystruct 几种类型

其中 arraystruct 是 TuyaLink 特有的,struct 中存在嵌套,在使用时请注意嵌套定义。

各种类型定义样例:

// type = value
{
  "unit" : "℃",
  "type" : "value",
  "min" : 0,
  "max" : 100,
  "typeDefaultValue" : 0,
  "step" : 1,
  "scale" : 1
}

// type = string
{
  "type" : "string",
  "typeDefaultValue" : "",
  "maxlen" : 50
}

// date
{
  "type" : "date",
  "typeDefaultValue" : 1658482441413
}

// bool
{
  "type" : "bool",
  "typeDefaultValue" : false
}

// enum
{
  "range" : [
    "e1",
    "e2",
    "e3"
  ],
  "typeDefaultValue" : "e1",
  "type" : "enum"
}

// fault (bitmap)
{
  "label" : [
    "f1",
    "f2"
  ],
  "typeDefaultValue" : 0,
  "type" : "bitmap"
}

// array
{
  "maxSize" : 4,
  "type" : "array",
  "elementTypeSpec" : {
    "type" : "value"
  }
}

// struct
{
  "type" : "struct",
  "properties" : {
    "struct_value" : {
      "name" : "test_value",
      "typeSpec" : {
        "type" : "value",
        "min" : 11,
        "typeDefaultValue" : 11,
        "max" : 22,
        "step" : 2,
        "scale" : 1
      }
    }
  }
}

ThingSmartThingAction数据模型

字段 类型 说明
abilityId int 动作id
code String 动作code
inputParams List 下发参数列表
outputParams List 上报参数列表

inputParamsoutputParams 实际上是 typeSpec 的数组,可为空数组,例如:

// input
{
  "code": "action_input_output_params",
  "abilityId" : 108,
  
  "inputParams" : [{
    "typeSpec" : {
      "unit" : "¥",
      "type" : "value",
      "min" : 0,
      "max" : 5,
      "typeDefaultValue" : 0,
      "step" : 1,
      "scale" : 0
    },
    "code" : "action_value"
  },
  {
    "typeSpec" : {
      "type" : "string",
      "typeDefaultValue" : "",
      "maxlen" : 100
    },
    "code" : "action_string"
  }],
  
  "outputParams" : [{
    "typeSpec" : {
      "unit" : "$",
      "type" : "value",
      "min" : 0,
      "max" : 100,
      "typeDefaultValue" : 0,
      "step" : 1,
      "scale" : 0
    },
    "code" : "out_action_value"
  }]
}

ThingSmartThingEvent数据模型

字段 类型 说明
abilityId int 事件id
code String 事件code
outputParams List 上报参数列表

控制设备

下发控制

接口说明

IThingDevice

void publishThingMessageWithType(ThingSmartThingMessageType thingMessageType,
                            Object command,
                            IResultCallback callback);

参数说明

参数 类型 说明
thingMessageType ThingSmartThingMessageType PROPERTY, //属性
ACTION, //动作
EVENT; //事件
command Object 下发内容 (JsonString格式)
callback IResultCallback 成功、失败回调

特别注意

  • 由于下发时会校验内容合法性,下发时需要有物模型缓存,请在合适的时机判断和拉取物模型

  • 由于 TuyaLink 设备的特性,目前仅通过 MQTT 通道进行控制

  • ThingSmartThingMessageType 中 事件 仅上报,不能下发

  • command 格式如下:

下发属性时规则

// 可多个同时下发,code是物模型中属性的code,value要符合typeSpec定义
{
	"code": value,
	"code": value
}

// 例如:
{
	"color":"green",
	"brightness": 50
}

下发动作时规则

// 同时只能下发一个动作
{
  "actionCode": "code",
  "inputParams": {
    "paramsCode": value,
    "paramsCode": value,
  }
}

// 例如:
{
	"actionCode": "action_input_output_params",
	"inputParams": {
		"action_value": 5,
		"action_string": "test_string"
	}
}

代码示例:

// 在合适的时机去拉取,比如:用户点击设备进入控制页的时候
void fetchThingModel(){
    // DeviceBean deviceBean = ThingOSDevice.getDeviceBean("your_device_id");

    if (deviceBean.isSupportThingModelDevice()) {
      ThingOsDevice.getDeviceOperator().getThingModelWithProductId(“pid", new IThingDataCallback<ThingSmartThingModel>() {
            @Override
            public void onSuccess(ThingSmartThingModel result) {
                
            }

            @Override
            public void onError(String errorCode, String errorMessage) {

            }
        });
    }
}


// 控制设备-下发属性
// 注意:在下发前需要deviceModel.thingModel是存在的
void publishProperty(){
    // IThingDevice device = ThingOSDevice.newDeviceInstance("your_device_id");

  	// 下发属性
    JSONObject command = new JSONObject();
    command.put("color","green");
    command.put("brightness", 50);
  	device.publishThingMessageWithType(ThingSmartThingMessageType.PROPERTY, command, new   IResultCallback() {
            @Override
            public void onError(String code, String error) {
                Log.i("publish", "error");
            }

            @Override
            public void onSuccess() {
							Log.i("publish", "success");
            }
        });

}

// 控制设备-下发动作
// 注意:在下发前需要deviceModel.thingModel是存在的
void publishAction(){
    // IThingDevice device = ThingOSDevice.newDeviceInstance("your_device_id");

  	// 下发动作
    JSONObject command = new JSONObject();
    command.put("actionCode","action_input_output_params");
  
    JSONObject inputParams = new JSONObject();
    inputParams.put("action_value",5);
  	inputParams.put("action_string", "test_string");
  
    command.put("inputParams", inputParams);
  	device.publishThingMessageWithType(ThingSmartThingMessageType.ACTION, command, new   IResultCallback() {
            @Override
            public void onError(String code, String error) {
                Log.i("publish", "error");
            }

            @Override
            public void onSuccess() {
							Log.i("publish", "success");
            }
        });
}

监听回调

通过 IThingDevice 设置 进行监听回调

接口说明

//注册监听
void registerThingLinkMessageListener(IThingLinkDeviceListener listener);
//取消注册 ,在IThingDevice#onDestroy中兜底进行了取消注册
void unRegisterThingLinkMessageListener();

参数说明

IThingLinkDeviceListener#(ThingSmartThingMessageType messageType, Map<String, Object> payload)

参数 类型 说明
messageType ThingSmartThingMessageType PROPERTY, //属性
ACTION, //动作
EVENT; //事件
payload Map<String, Object> 收到的上报内容,type不同格式不同,具体见 特别注意 中样例

特别注意

  • 由于上报时会校验内容合法性,上报时需要有物模型缓存,请在合适的时机判断和拉取物模型
  • 仅对于属性消息,还会转换成 dps 格式,也会通过 IThingDevice注册的 IDevListener#onDpUpdate(String devId,String dpStr) 回调
  • payload 在不同消息类型下的格式如下:

上报属性时

// 格式规则
{
  "code": {
    "value": value,
    "time": 1234567890
  },
  "code": {
    "value": value,
    "time": 1234567890
  }
}

// 例如:
{
	"color": {
		"value": "green",
		"time": 1234567890
	},
	"brightness": {
		"value": 50,
		"time": 1234567890
	}
}

上报动作时

// 格式规则
{
	"actionCode": code,
	"outputParams": {
		"outputParam1": value,
		"outputParam2": value
	}
}

// 例如
{
	"actionCode": "open_door_action",
	"outputParams": {
		"status": "open",
		"angle": 30
	}
}

上报事件时

// 格式规则
{
	"eventCode": code,
	"outputParams": {
		"outputParam1": value,
		"outputParam2": value
	}
}

// 例如
{
	"eventCode": "people_move_event",
	"outputParams": {
		"count": 2,
		"time": "2022-07-22 18:30:00"
	}
}

代码示例

IThingDevice

// 在合适的时机去监听
IThingDevice thingDevice = ThingOSDevice.newDeviceInstance("your device id");
// 注意:在接收上报前需要 deviceModel.thingModel 是存在的
thingDevice.registerThingLinkMessageListener(new IThingLinkDeviceListener() {
            @Override
            public void onReceiveThingMessage(ThingSmartThingMessageType thingMessageType, Map<String, Object> payload) {
               Log.i("ThingDevice", thingMessageType, payload);
              // 不同 type 的消息 payload 格式不同,详见参数说明
              if (thingMessageType == ThingSmartThingMessageType.PROPERTY) {
                  //.. do something
              } else if (thingMessageType == ThingSmartThingMessageType.ACTION) {
                  //.. do something
              } else if (thingMessageType == ThingSmartThingMessageType.EVENT) {
                  //.. do something
              }
});

属性、动作、事件的payload缓存

在物模型介绍中有提到: 属性 表示设备的持续性、可查询的状态,而 动作事件 是设备实时的响应。

所以在 对应消息的 payload 的缓存机制是:

  • 属性 有缓存,可以通过 DeviceBean##getDps() 来获取缓存
  • 动作 无缓存
  • 事件 无缓存

特别说明

属性 实际与原本普通设备的 DP 含义一致,所以通过 DeviceBean##getDps 来缓存,格式定义为:dpId = value

在使用时,请通过 属性模型ThingSmartThingProperty##abilityId 来进行映射对应来展示。

属性 payload 转换为 DP

ThingLink设备的属性实际上和原本涂鸦普通设备的 DP 点概念是一致的。只是相比 DP 点多出了 arraystruct 两种新的类型定义。

当收到属性消息的上报时,我们会在通过 IThingDevice#registerThingLinkMessageListener(IThingLinkDeviceListener listener) 回调的同时,也会同步转换成 dps 通过 IThingDevice#registerDevListener(IDevListener listener)注册的监听, 回调监听的onDpUpdate,并缓存在 DeviceBean##dpsDeviceBean##dpsTime属性 中。

你也可以使用 ThingOSDevice#getDeviceOperator#dpsFromProperties(String deviceId,String propertyPayload) 将 属性数据 转换为 DP。

接口说明

IThingDeviceOperator{
//...
  
// 将属性 转换为 DP 格式
String dpsFromProperties(String deviceId, String properties);
}

参数说明

参数 类型 说明
properties String 属性 payload,(JsonString)格式与上报属性时一致,格式如下

属性 payload 格式:

{
  "code": {
    "value": value,
    "time": time
  },
  "code": {
    "value": value,
    "time": time
  },
}

代码示例

void transferPropertiesToDp(){
	  JSONObject propertiesPayload = new JSONObject();
    propertiesPayload.put("color","green");
    propertiesPayload.put("brightness", 50);
  
    String dps = dpsFromProperties(”deviceId“, propertiesPayload.toJSONString());
    Log.i("dps:", dps);
  
  	/**
  		输出结果是,101、105实际就是 "color" 和 "brightness" 的 ThingSmartThingProperty::abilityId
  		@{
  			@"101": @"green",
  			@"105": @50
  		}
  	*/
}