TuyaLink-Based Device Pairing

Last Updated on : 2023-10-11 06:54:24download

TuyaLink is an open solution that enables IoT devices, including proprietary network modules and smart devices, to connect to Tuya’s cloud services. 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. For more information, see TuyaLink.

Pairing process

AppBizBundle SDKDeviceCloudDevice enters pairingmode.Scan device's QR code1Parse the QR code.Call the QR code parsingmethod.2Call the QR code parsing method.3Return the parsing result.4Return the parsing result.5alt[Scan for devices.]Send a device activationrequest.6Send a device activationrequest.7Register the device with thecloud.8Return the list of activated devices.9Return the list of activateddevices.10alt[Activation and pairing]AppBizBundle SDKDeviceCloudTuyaLink-Based Device Pairing

Parse QR code

Extract the URL from the QR code and get the device information through the common API. Based on the return value, determine whether the device is a TuyaLink-based device.

@protocol ThingSmartActivatorRequestProtocol <NSObject>

/// Provide QR code parsing capability
/// @param param Request Parameters
/// @param success Network success callback
/// @param failure Network Failure Callbacks
- (void)requestParseQRCodeWithParam:(ThingActivatorParseQRCodeRequestData *)param success:(void(^)(ThingSmartAScanCodeModel *result))success failure:(ThingActivatorCallbackError)failure;
@end

Parameter description

Parameters Description
param The request parameter.
success The success callback.
failure The failure callback.

Description of the return value:

@interface ThingSmartAScanCodeModel : NSObject
@property (nonatomic, strong) NSString * _Nullable actionName;
@property (nonatomic, assign) id _Nullable actionData;
@end

The actionName for a TuyaLink-based device is "device_net_conn_bind_tuyalink". See the example for usage.

Register the pairing type

When the device pairing service is initialized, register the pairing type, which is ThingSmartActivatorTypeThingLinkModel.

/// Initialize network configuration types
/// @param typeList Network configuration types
- (void)registerWithActivatorList:(NSArray<ThingSmartActivatorTypeModel *>*)typeList;

Parameter description

Parameters Description
typeList The list of pairing types.

Activate a device

API description

/// Activate devices with a single network configuration type
/// @param type Network configuration type
/// @param deviceList Devices to be activated
- (void)startActive:(ThingSmartActivatorTypeModel *)type deviceList:(NSArray<ThingSmartActivatorDeviceModel *>*)deviceList;

Parameter description

Parameters Description
type The pairing type.
deviceList The list of devices to be activated. Currently, only one device is supported.

Stop activation

API description

/// Stop activating devices
/// @param typeList Array of network configuration types
/// @param clearCache Whether to clear the cache
- (void)stopActive:(NSArray <ThingSmartActivatorTypeModel *>*)typeList clearCache:(BOOL)clearCache;

Parameter description

Parameters Description
typeList The pairing type.
clearCache Specifies whether to clear the cache search result.

Activation callback

API description

// Device network configuration result callback
/// @param service Device network configuration implementation object
/// @param type Network configuration type
/// @param devices Devices being configured
/// @param errorModel Error encountered during network configuration
- (void)activatorService:(id<ThingSmartActivatorActiveProtocol>)service
           activatorType:(ThingSmartActivatorTypeModel *)type
       didReceiveDevices:(nullable NSArray<ThingSmartActivatorDeviceModel *> *)devices
                   error:(nullable ThingSmartActivatorErrorModel *)errorModel;

Parameter description

Parameters Description
service The pairing service.
type The pairing type.
devices The activated device.
errorModel This model is returned if pairing fails or times out. nil is returned on success.

Error codes

ThingSmartActivatorErrorModel is returned if pairing fails or times out.

@interface ThingSmartActivatorErrorModel : NSObject
@property (nonatomic, strong) ThingSmartActivatorDeviceModel *deviceModel;
@property (nonatomic) NSError *error;
@end

ThingSmartActivatorDiscoveryError includes the definition of error codes.

Example

Swift:

class TuyaLinkDeviceBindTableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        title = "ThingLink Bind"
    }

    private var typeModel: ThingSmartActivatorTypeThingLinkModel = {
        let type = ThingSmartActivatorTypeThingLinkModel()
        type.type = ThingSmartActivatorType.thingLink
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.thingLink)
        type.timeout = 120
        return type
    }()

    lazy var discovery: ThingSmartActivatorDiscovery = {
        let discovery = ThingSmartActivatorDiscovery()
        discovery.register(withActivatorList: [self.typeModel])
        discovery.setupDelegate(self)
        discovery.loadConfig()
        return discovery
    }()

    var request: ThingSmartActivatorDiscoveryRequest = {
        let request = ThingSmartActivatorDiscoveryRequest()
        return request
    }()

    func bindThingLink(qrcode codeStr: String?) -> Void {
        let homeId = (Home.current?.homeId)!
        SVProgressHUD.show()
        let requestDate = ThingActivatorParseQRCodeRequestData()
        requestDate.code = codeStr ?? ""
        request.requestParseQRCode(withParam: requestDate) { codeModel in
            if codeModel.actionName == "device_net_conn_bind_tuyalink" {
                self.typeModel.uuid = codeModel.actionData?.object(forKey: "uuid") as! String
                self.typeModel.spaceId = homeId
                self.discovery.startActive(self.typeModel, deviceList: [])
            }
        } failure: { error in

        }
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let vc = QRCodeScanerViewController()
        vc.scanCallback = { [weak self] codeStr in
            self?.bindThingLink(qrcode: codeStr)
        }
        navigationController?.pushViewController(vc, animated: true)
    }

}

extension TuyaLinkDeviceBindTableViewController: ThingSmartActivatorActiveDelegate {
    func activatorService(_ service: ThingSmartActivatorActiveProtocol, activatorType type: ThingSmartActivatorTypeModel, didReceiveDevices devices: [ThingSmartActivatorDeviceModel]?, error errorModel: ThingSmartActivatorErrorModel?) {
        if errorModel != nil {
            SVProgressHUD.showError(withStatus: "Bind Failure. (\(errorModel?.error.localizedDescription ?? ""))")
            return
        }

        let device = devices?.first
        SVProgressHUD.show(withStatus: "Bind Success. \n devId: \(device?.uniqueID ?? "") \n name: \(device?.name ?? "")")
    }
}

Objective-C:

- (void)qrParse:(NSString *)url {
ThingActivatorParseQRCodeRequestData *param = [[ThingActivatorParseQRCodeRequestData alloc] init];
    param.code = url;

[self.requestService requestParseQRCodeWithParam:param success:^(ThingSmartAScanCodeModel * _Nonnull codeModel) {
       if ([result.actionName isEqualToString:@"device_net_conn_bind_tuyalink"]){
        NSDictionary *dict = result.actionData;
        NSString *uuid = [dict objectForKey:@"uuid"];
        ThingSmartActivatorTypeThingLinkModel *type = [[ThingSmartActivatorTypeThingLinkModel alloc] init];
        type.type = ThingSmartActivatorTypeThingLink;
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeThingLink);
        type.timeout = 120;
        type.spaceId = [ThingSmartActivatorLinkTool getSpaceId];
        type.uuid = uuid;
        [self startConfigQRCode:type];
       }
   } failure:^(NSError *error) {

   }];
}

- (void)startConfigQRCode:(ThingSmartActivatorTypeMQTTDirectlyModel *)type {

  [self.discovery registerWithActivatorList:@[type]];
  [self.discovery setupDelegate:self];
  [self.discovery startActive:type deviceList:@[]];

}

- (void)activatorService:(id<ThingSmartActivatorActiveProtocol>)service 
           activatorType:(ThingSmartActivatorTypeModel *)type 
       didReceiveDevices:(NSArray<ThingSmartActivatorDeviceModel *> *)devices 
                   error:(ThingSmartActivatorErrorModel *)errorModel {    
    if (errorModel) {
        [self _connectWifiError:errorModel];
        return;
    }

    if (device) {
        [self _handleDevice:device];
    }
}

- (void)_handleDevice:(ThingSmartActivatorDeviceModel *)deviceModel {

}

- (ThingSmartActivatorDiscovery *)discovery {
    if (!_discovery) {
        _discovery = [[ThingSmartActivatorDiscovery alloc] init];
    }
    return _discovery;
}

- (ThingSmartActivatorDiscoveryRequest *)requestService {
    if (!_requestService) {
        _requestService = [[ThingSmartActivatorDiscoveryRequest alloc] init];
    }
    return _requestService;
}