TuyaLink 设备

更新时间:2023-03-09 08:08:14

TuyaLink 生态设备接入是面向物联网生态领域(自研模组/成品智能设备)全面开放的设备上云解决方案。

通过整合并全面升级涂鸦 IoT 开发平台技术底座 IoT Core,提供包含物模型、规则引擎、数据解析、设备管理、运维监控、告警管理、固件 OTA 升级和应用开发等全面的物联网开发套件,极大地降低了开发者接入门槛。

通过此方案可以快速加入涂鸦生态体系,实现跨领域设备间互连互通,并可使用平台丰富的 PaaS、SaaS 和 App 等应用开发能力,最大程度地降低物联网整体解决方案的落地实施成本,减少开发周期。

TuyaLink 设备

更多详情,请参考 生态设备接入

判断 TuyaLink 设备

接口说明

boolean isSupportThingModelDevice();

代码示例:

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

物模型

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

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

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

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

接口说明

获取物模型

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

示例

TuyaSmartThingModel thingModel = TuyaOSDevice.getDeviceBean("your_device_id").getThingModel();

物模型接口请求并保存


ITuyaDeviceOperator.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,ITuyaDataCallback<TuyaSmartThingModel> 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,ITuyaDataCallback<TuyaSmartThingModel> callback);

示例


TuyaOsDevice.getDeviceOperator().getThingModelWithProductId(“pid", new ITuyaDataCallback<TuyaSmartThingModel>() {
            @Override
            public void onSuccess(TuyaSmartThingModel result) {
                
            }

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

            }
        });
    }

TuyaSmartThingModel 数据模型

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

TuyaSmartThingServiceModel 数据模型

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

TuyaSmartThingProperty 数据模型

字段 类型 说明
abilityId int 属性 ID
可与普通设备的 dpsdpId 对应
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
      }
    }
  }
}

TuyaSmartThingAction 数据模型

字段 类型 说明
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"
  }]
}

TuyaSmartThingEvent 数据模型

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

控制设备

下发控制

接口说明

ITuyaDevice

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

参数说明

参数 类型 说明
thingMessageType TuyaSmartThingMessageType PROPERTY, //属性
ACTION, //动作
EVENT; //事件
command Object 下发内容(JsonString 格式)
callback IResultCallback 成功、失败回调
  • 由于下发时会校验内容合法性,下发时需要有物模型缓存,请在合适的时机判断和拉取物模型。

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

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

  • 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 = TuyaOSDevice.getDeviceBean("your_device_id");

    if (deviceBean.isSupportThingModelDevice()) {
      TuyaOsDevice.getDeviceOperator().getThingModelWithProductId(“pid", new ITuyaDataCallback<TuyaSmartThingModel>() {
            @Override
            public void onSuccess(TuyaSmartThingModel result) {
                
            }

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

            }
        });
    }
}


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

  	// 下发属性
    JSONObject command = new JSONObject();
    command.put("color","green");
    command.put("brightness", 50);
  	device.publishThingMessageWithType(TuyaSmartThingMessageType.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(){
    // ITuyaDevice device = TuyaOSDevice.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(TuyaSmartThingMessageType.ACTION, command, new   IResultCallback() {
            @Override
            public void onError(String code, String error) {
                Log.i("publish", "error");
            }

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

监听回调

通过 ITuyaDevice 设置,进行监听回调。

接口说明

//注册监听
void registerTuyaLinkMessageListener(ITuyaLinkDeviceListener listener);
//取消注册 ,在 ITuyaDevice#onDestroy 中兜底进行了取消注册
void unRegisterTuyaLinkMessageListener();

参数说明

ITuyaLinkDeviceListener#(TuyaSmartThingMessageType messageType, Map<String, Object> payload)

参数 类型 说明
messageType TuyaSmartThingMessageType PROPERTY, //属性
ACTION, //动作
EVENT; //事件
payload Map<String, Object> 收到的上报内容,type不同格式不同,具体见 下述注意事项 中的样例
  • 由于上报时会校验内容合法性,上报时需要有物模型缓存,请在合适的时机判断和拉取物模型
  • 仅对于属性消息,还会转换成 dps 格式,也会通过 ITuyaDevice注册的 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"
	}
}

代码示例

ITuyaDevice

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

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

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

所以,对应消息的 payload 的缓存机制如下所述:

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

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

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

属性 payload 转换为 DP

TuyaLink 设备的属性和原本涂鸦普通设备的 DP 点概念一致。只是相比 DP 点,增加 arraystruct 两种新的类型定义。

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

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

接口说明

ITuyaDeviceOperator{
//...
  
// 将属性 转换为 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" 的 TuyaSmartThingProperty::abilityId
  		@{
  			@"101": @"green",
  			@"105": @50
  		}
  	*/
}