English
English
简体中文
Contact Us
Register
Log In

TuyaLink-Based Devices

Last Updated on : 2022-09-22 10:26:28download

TuyaLink is an open solution that enables IoT devices, including proprietary network modules and smart devices, to connect to Tuya’s cloud services.

TuyaLink lowers the bar for IoT development by integrating with Tuya’s IoT Core technologies, including things data model, rule engines, data parsing, device management, operations and monitoring, alert management, OTA firmware updates, and application development.

TuyaLink allows you to quickly integrate with the Tuya ecosystem and achieve interconnectivity between devices across different domains. A range of development resources for PaaS, SaaS, and apps helps you implement IoT projects with improved cost efficiency and reduced lead time.

TuyaLink-Based Devices

For more information, see TuyaLink.

Identify TuyaLink-based device

API description

- (BOOL)isSupportThingModelDevice;

Example

ObjC:

- (void)judgeSupportTuyaLink {
	// self.device = [TuyaSmartDevice deviceWithDeviceId:@"your_device_id"];
  
  BOOL isSupport =	[self.device.deviceModel isSupportThingModelDevice];
	NSLog(@"judgeSupportTuyaLink: %ld", isSupport);
}

Swift:

func judgeSupportTuyaLink() {
    let isSupport = device?.deviceModel?.isSupportThingModelDevice()
}

Things data model

The device model construct describes an abstraction of physical devices. It defines the characteristics and behaviors of a type of device that connects to the Tuya IoT Development Platform.

A device model defines an abstract representation of a device as a set of properties, actions, and events. This model determines how a connected physical device interacts with the cloud applications.

Type Description
Property The property type is used to define the continuous and queryable states of a device, which can represent one or several feature parameters. A property can be read-write or read-only for data update and query. When a specific feature parameter is updated, the device can update the property accordingly. For example, a light bulb might have properties like power state and brightness.
Action The action type is used to run complex tasks. An action command is not intended to change the device property, but directs the device to return a response. For example, face recognition and picture transmission.
Event The event type is used to define a live notification reported by a device, which requires external sensing and processing. Events work with message subscription or rule engines to respond as per the predefined logic, for example, overheating alerts and fault alerts.

Currently, things data models are returned on demand from a local cache. To keep the cached data up to date, you need to timely pull the latest things data model and update the cache.

API description

@interface TuyaSmartDeviceModel
// ....

// Returns the locally cached things data model.
@property (nonatomic, strong, nullable) TuyaSmartThingModel *thingModel;
@end

@interface TuyaSmartDevice
// ...
  
// Pulls the latest things data model that matches current device information and updates the cached data.
- (void)getThingModelWithSuccess:(nullable void(^)(TuyaSmartThingModel * _Nullable thingModel))success
                         failure:(nullable TYFailureError)failure;

// Pulls the latest things data model that matches the specified product ID (PID) and PID version and updates the cached data.
+ (void)getThingModelWithProductId:(NSString *)pid
                    productVersion:(NSString *)productVersion
                           success:(nullable void (^)(TuyaSmartThingModel * _Nullable thingModel))success
                           failure:(nullable TYFailureError)failure;
@end

Data model of TuyaSmartThingModel

Field Type Description
modelId NSString The ID of the things data model.
productId NSString The product ID (PID).
productVersion NSString The version of the PID.
services NSArray<TuyaSmartThingServiceModel *> The service model.
extensions NSDictionary The extension information.

Data model of TuyaSmartThingServiceModel

Field Type Description
properties TuyaSmartThingProperty Property
actions TuyaSmartThingAction Action
events TuyaSmartThingEvent Event

Data model of TuyaSmartThingProperty

Field Type Description
abilityId NSInteger The property ID
can be regarded as dpId of dps for a generic device.
code NSString The property code.
accessMode NSString The access mode. Valid values:
rw: can be sent and reported
ro: only reported
wr: only sent
typeSpec NSDictionary The definition of a data type.
defaultValue id The default value.

Description

Currently, typeSpec supports the following data types: value, string, date, bool, enum, fault (bitmap), array, and struct.

The array and struct types are dedicated for TuyaLink. struct is a nested type that encloses other type definitions.

Examples of data types

// type = value
{
  "unit" : "°C",
  "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
      }
    }
  }
}

Data model of TuyaSmartThingAction

Field Type Description
abilityId NSInteger The action ID.
code NSString The action code.
inputParams NSArray The list of parameters to be sent.
outputParams NSArray The list of parameters to be reported.

inputParams and outputParams are arrays of typeSpec and can be empty. Example:

// 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"
  }]
}

Data model of TuyaSmartThingEvent

Field Type Description
abilityId NSInteger The event ID.
code NSString The event code.
outputParams NSArray The list of parameters to be reported.

Control devices

Send commands

API description

- (void)publishThingMessageWithType:(TuyaSmartThingMessageType)thingMessageType
                            payload:(NSDictionary *)payload
                            success:(TYSuccessHandler)success
                            failure:(TYFailureError)failure

Parameters

Parameter Type Description
thingMessageType TuyaSmartThingMessageType 0: property. 1: action. 2: event.
payload NSDictionary The content to be sent.
success TYSuccessHandler The success callback.
failure TYFailureError The failure callback.
  • The content validity is checked to send a command. Therefore, the things data model must be cached in this process. You need to timely check and pull the latest things data model.

  • To support the features of TuyaLink-based devices, they can be controlled over MQTT only.

  • The events in TuyaSmartThingMessageType can only be reported, which means they are read-only and cannot be changed.

  • The following examples show the payload format.

Rules of sending properties

// Multiple properties can be sent simultaneously. `code` is the property code in a things data model. `value` is subject to the definition of `typeSpec`.
{
	"code": value,
	"code": value
}

// Example:
{
	"color":"green",
	"brightness": 50
}

Rules of sending an action

// Only one action can be sent at a time.
{
  "actionCode": "code",
  "inputParams": {
    "paramsCode": value,
    "paramsCode": value,
  }
}

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

Example

ObjC:

// Pulls the latest things data model at the right time, for example, when users tap a device to go to the device control page.
- (void)fetchThingModel {
    // self.device = [TuyaSmartDevice deviceWithDeviceId:@"your_device_id"];

    if (!self.device.deviceModel.thingModel) {
      [self.device getThingModelWithSuccess:^(TuyaSmartThingModel * _Nullable thingModel) {
          NSLog(@"fetch thing model success: %@", thingModel);
      } failure:^(NSError *error) {
          NSLog(@"fetch thing model fail: %@", error);
      }];
    }
}

// Device control: send properties
// Note: `deviceModel.thingModel` must exist before properties are sent.
- (void)publishProperty {
    // self.device = [TuyaSmartDevice deviceWithDeviceId:@"your_device_id"];

  	// Sends properties.
  	NSDictionary *propertyPayload = @@{
        @"color": @"green",
        @"brightness": @50
    };
		[self.device publishThingMessageWithType:TuyaSmartThingMessageTypeProperty payload:propertyPayload success:^{
        NSLog(@"success");
    } failure:^(NSError *error) {
        NSLog(@"failure: %@", error);
    }];
}

// Device control: send an action
// Note: `deviceModel.thingModel` must exist before an action is sent.
- (void)publishAction {
    // self.device = [TuyaSmartDevice deviceWithDeviceId:@"your_device_id"];

  	// Sends an action.
		NSDictionary *actionPayload = @{
        @"actionCode": @"action_input_output_params",
        @"inputParams": @{
            @"action_value": @5,
            @"action_string": @"test_string"
        }
    };
  	[self.device publishThingMessageWithType:TuyaSmartThingMessageTypeAction payload:actionPayload success:^{
        NSLog(@"success");
    } failure:^(NSError *error) {
        NSLog(@"failure: %@", error);
    }];
}

Swift:

// Pulls the latest things data model at the right time, for example, when users tap a device to go to the device control page.
func fetchThingModel() {
  device?.getThingModel(success: { thingModel in
      print("success \(thingModel)")
  }, failure: { error in
      if let err = error {
          print("failure \(err)")
      }
  })
}

// Device control: send properties
// Note: `deviceModel.thingModel` must exist before properties are sent.
func publishProperty() {
  let porpetyPayload = [
    "color": "green",
    "brightness": 50
  ]
  device?.publishThingMessage(with: .property, payload: porpetyPayload, success: {
    print("publish property success")
  }, failure: { error in
    if let err = error {
      print("publish property fail.(%@)", err)
    }
  })
}

func publishAction() {
  let actionPayload = [
    "actionCode": "action_input_output_params",
    "inputParams": [
      "action_value": 5,
      "action_string": "test_string"
    ]
  ]
  device?.publishThingMessage(with: .action, payload: actionPayload, success: {
    print("publish action success")
  }, failure: { error in
    if let err = error {
      print("publish action fail.(%@)", err)
    }
  })
}

Listen for the callback

You can use TuyaSmartDevice to set a delegate and listen for the callback.

API description

- (void)device:(TuyaSmartDevice *)device didReceiveThingMessageWithType:(TuyaSmartThingMessageType)thingMessageType payload:(NSDictionary *)payload;

Parameters

Parameter Type Description
device TuyaSmartDevice The device object to be operated.
TuyaSmartThingMessageType TuyaSmartThingMessageType 0: property. 1: action. 2: event.
payload NSDictionary The reported content that is received. The format can vary, depending on different values of type. For more information, see the examples below in things to note.
  • The content validity is checked to report status data. Therefore, the things data model must be cached in this process. You need to timely check and pull the latest things data model.
  • The property messages will be converted into the dps format, and the callback will be returned by -device:dpsUpdate:.
  • The following examples show the payload format.

Report device properties

// Rules of the format
{
  "code": {
    "value": value,
    "time": 1234567890
  },
  "code": {
    "value": value,
    "time": 1234567890
  }
}

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

Report an action

// Rules of the format
{
	"actionCode": code,
	"outputParams": {
		"outputParam1": value,
		"outputParam2": value
	}
}

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

Report an event

// Rules of the format
{
	"eventCode": code,
	"outputParams": {
		"outputParam1": value,
		"outputParam2": value
	}
}

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

Example

ObjC:

// Listens for the callback at the right time.
- (void)addThingDeviceListner {
  	// self.device = [TuyaSmartDevice deviceWithDeviceId:@"your_device_id"];
	  device.delegate = self;
}

// Note: `deviceModel.thingModel` must exist before the reported content is received.
- (void)device:(TuyaSmartDevice *)device didReceiveThingMessageWithType:(TuyaSmartThingMessageType)thingMessageType payload:(NSDictionary *)payload {
    
    NSLog(@"---did receive thing msg type: %ld, msg: %@", thingMessageType, payload);
    // The payload format can vary, depending on different values of `type`. For more information, see the parameter description.
    if (thingMessageType == TuyaSmartThingMessageTypeProperty) {
        //.. do something
    } else if (thingMessageType == TuyaSmartThingMessageTypeAction) {
        //.. do something
    } else if (thingMessageType == TuyaSmartThingMessageTypeEvent) {
        //.. do something
    }
}

Swift:

// Listens for the callback at the right time.
func addThingDeviceListner {
  device?.delegate = self;
}

// Note: `deviceModel.thingModel` must exist before the reported content is received.
func device(_ device: TuyaSmartDevice, didReceiveThingMessageWith thingMessageType: TuyaSmartThingMessageType, payload: [AnyHashable : Any]) {
  print("---did receive thing msg type: \(thingMessageType), payload: \(payload)")
  switch thingMessageType {
  case .property:
    //.. do something
  case .action:
    //.. do something
  case .event:
    //.. do something
  }
}

Cached payload of property, action, and event

For a things data model, the property represents the continuous and queryable states of a device. The action and event represent the real-time responses of a device.

Therefore, the cache rules for each message payload are described as follows:

  • The property is cached. TuyaSmartDeviceModel::dps can be used to get the cached content.
  • The action is not cached.
  • The event is not cached.

The property is defined in the same way as the data point (DP) of a generic device. Therefore, the property can be cached based on TuyaSmartDeviceModel::dps. Format: dpId = value.

The property is displayed based on the mappings of TuyaSmartThingProperty::abilityId in the property model.

Convert property payload to DP

The properties of a TuyaLink-based device are defined in the same way as the DP of a generic device. The difference is that array and struct are added as new types for TuyaLink.

When reported property messages are received, a callback is returned by -device:didReceiveThingMessageWithType:payload:. Meanwhile, the property is converted to dps, and a callback is returned by -device:dpsUpdate:. The returned content is cached in deviceModel.dps and deviceModel.dpsTime.

You can also convert the property to the DP by using the method -dpsFromProperties: opened in TuyaSmartThingModel.

API description

@interface TuyaSmartThingModel : NSObject
//...
  
// Converts the property to the DP.
- (NSDictionary *)dpsFromProperties:(NSDictionary *)properties;
@end

Parameters

Parameter Type Description
properties NSDictionary The property payload, in the same format as that of the reported property, as described in the following example.

Format of the property payload

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

Example

ObjC:

- (void)transferPropertiesToDp {
	  TuyaSmartThingModel *thing = self.device.deviceModel.thingModel;
  
  	NSDictionary *propertiesPayload = @{
        @"color": @"green",
        @"brightness": @50
    }
    NSDictionary *dps = [thing dpsFromProperties:propertiesPayload];
    NSLog(@"---- dps: %@", dps);
  
  	/**
  		In the output, `101` and `105` respectively represent `color` and `brightness` of `TuyaSmartThingProperty::abilityId`.
  		@{
  			@"101": @"green",
  			@"105": @50
  		}
  	*/
}

Swift:

func trnasferPropertiesToDp {
  if let thing = device?.deviceModel.thingModel {
    let propertiesPayload = [
      "color": "green",
      "brightness": 50
    ]
    let dps = thing?.dps(fromProperties: propertiesPayload)
    print("--- dps: \(dps)")
  }
}