Device Pairing UI BizBundle

Last Updated on : 2023-11-17 07:28:31download

Smart Life Device Pairing UI BizBundle is used to implement pairing guidance and smart device activation. It applies to multiple common types of smart devices, such as Wi-Fi devices, Zigbee devices, Bluetooth devices, and devices that support QR code scanning like GPRS & NB-IoT devices. The UI BizBundle provides the service logic and UI encapsulation to guide pairing and activate smart devices over different protocols.

Feature description

Wi-Fi device pairing

Wi-Fi smart devices can be paired and connected to cloud services in two modes: Wi-Fi Easy Connect (EZ) mode and access point (AP) or hotspot mode. IP cameras (IPCs) can be paired after QR code scanning.

Term Description
Wi-Fi EZ mode Also known as the EZ mode. This pairing mode is implemented through the following steps:
  1. The app encapsulates the pairing data into the specified section of an IEEE 802.11 packet and sends the packet to the network.
  2. The Wi-Fi module of a smart device runs in promiscuous mode and listens for and captures all packets over the network.
  3. The Wi-Fi mode parses the packets that carry the pairing data from the app into the data format specified by the protocol.
AP mode Also known as the hotspot mode. A mobile phone acts as a station (STA) and connects to the hotspot of a smart device. Then, both devices are paired to establish a socket connection between them and exchange data through the specified ports.
IPC pairing in QR code mode An IPC scans the QR code on the app to get the pairing data.

Zigbee device pairing

Zigbee gateways and sub-devices can be paired.

Term Description
Zigbee gateway The device that integrates the coordinator with Wi-Fi features on a Zigbee network. The gateway is responsible to formulate the Zigbee network and store data.
Zigbee sub-device A router or an end device on a Zigbee network. Each Zigbee sub-device is responsible to forward data, or respond to control commands.

Bluetooth device pairing

Tuya provides the following Bluetooth solutions.

Term Description
Bluetooth Low Energy (LE) A point-to-point connection is created between a Bluetooth or Bluetooth LE device and a mobile phone.
Bluetooth mesh Enable many-to-many (m:m) device communications over a mesh network released by Bluetooth Special Interest Group (SIG). This solution is also known as Bluetooth LE mesh.
Tuya mesh Tuya’s proprietary technology that enables Bluetooth devices to communicate over a mesh network.
Combo devices The devices that support Bluetooth and Wi-Fi combo can be paired over either Bluetooth or Wi-Fi.

QR code pairing

A smart device that supports this pairing mode is connected to Tuya’s cloud services immediately after power on. The app can be used to scan the QR code on the device to implement cloud-based device activation and binding. The QR code must comply with Tuya’s QR code rules. For more information, contact Tuya’s account manager.

Term Description
GPRS devices Smart devices that apply GPRS technologies to connect to the network and access cloud services.
NB-IoT devices Smart devices that apply NB-IoT technologies.

Pairing by auto discovery

Tuya provides efficient pairing features on top of Tuya’s generic pairing technologies for smart devices.

Integrate with the UI BizBundle

Add the components of the Device Pairing UI BizBundle to the Podfile and run the command pod update.

source 'https://github.com/tuya/tuya-pod-specs.git'
source 'https://cdn.cocoapods.org/'
platform :ios, '11.0'

target 'your_target_name' do
  # Adds the Device Pairing UI BizBundle.
  pod 'ThingSmartActivatorBizBundle'
end

To implement pairing of Wi-Fi devices, you must get the name of the current Wi-Fi network after location is enabled in your project. To achieve this purpose, add the following permission declaration to info.plist of your project, create the CLLocationManager sample, and then call the method requestWhenInUseAuthorization:

NSLocationAlwaysAndWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
NSLocationWhenInUseUsageDescription

To implement QR code scanning, the permissions on access to cameras of mobile phones are required. You can add the following permission declaration in info.plist:

NSCameraUsageDescription

Customize settings

Bluetooth device pairing

The Device Pairing UI BizBundle supports device pairing over protocols such as Wi-Fi and Bluetooth. Bluetooth pairing is optional.

  • If your app does not require Bluetooth pairing, you only need to set the needBle property in thing_custom_config.json to false.

  • If your app requires Bluetooth pairing, you must first add the following Bluetooth permission declaration to info.plist of your project, set the needBle property in thing_custom_config.json to true, and then add the following dependencies to your project:

    System permissions

    NSBluetoothAlwaysUsageDescription
    NSBluetoothPeripheralUsageDescription
    

    Configuration items

    {
        "config": {
            "appId": 123,
            "thingAppKey": "xxxxxxxxxxxx",
            "appScheme": "tuyaSmart",
            "hotspotPrefixs": ["SmartLife"],
            "needBle": true, // Sets the value to `true` to support pairing of Bluetooth devices.
            "needQRCode": true // Sets the value to `true` to support QRCode pairing.
        },
    "colors":{
            "themeColor": "#FF5A28",
        }
    }
    

    Dependencies

    pod 'ThingBLEInterfaceImpl'
    pod 'ThingBLEMeshInterfaceImpl'
    pod 'ThingSmartBLEKit'
    pod 'ThingSmartBLEMeshKit'
    

Hotspot name settings

  • By default, the hotspot name of each Tuya-enabled device is prefixed with SmartLife.

  • If the hotspot prefix of the current smart device is modified, you must set the hotspotPrefixs property in thing_custom_config.json to the current hotspot prefix.

    {
        "config": {
            "appId": 123,
            "thingAppKey": "xxxxxxxxxxxx",
            "appScheme": "tuyaSmart",
            "hotspotPrefixs": ["SL"], // The supported hotspot prefix is set to `SL`.
            "needBle": true
        },
    "colors":{
            "themeColor": "#FF5A28",
        }
    }
    

Auto discovery settings

If you need to control the device types supported by auto discovery, you need to set the activator_auto_serach_capacity property in the thing_custom_config.json file.

```json
{
    "config": {
        "appId": 123,
        "thingAppKey": "xxxxxxxxxxxx",
        "appScheme": "tuyaSmart",
        "hotspotPrefixs": ["SL"], // Indicates that the hotspot prefix of the supported device is changed to SL.
        "needBle": true,           
        "activator_auto_serach_capacity": {
                "searchTypeBle": true,
                "searchTypeEZ": false,
                "searchTypePegasus": true,
                "searchTypeWired": true,
                "searchTypeZigbee": true,
                "searchTypeMatter": true
        },
    },
"colors":{
        "themeColor": "#FF5A28",
    }
}
```

Matter device pairing

To make your app support pairing Matter devices, perform the following steps:

  • Add the iOS permission matter.allow-setup-payload to your project.

  • Add the Bonjour service configurations for iOS to info.plist.

  • In thing_custom_config.json, set the property is_matter_support to true to enable device pairing over Matter. By default, this property is set to false.

  • Add Matter Extension Target to the project, and use the same App Groups between the main project and Matter Extension Target.

    System permissions

    com.apple.developer.matter.allow-setup-payload
    

    Configuration of info.plist

        <key>NSBonjourServices</key>
         <array>
        <string>_meshcop._udp</string>
        <string>_matterd._udp</string>
        <string>_matter._tcp</string>
        <string>_matterc._udp</string>
         </array>
    

    Configuration items

    {
        "config": {
            "appId": 123,
            "thingAppKey": "xxxxxxxxxxxx",
            "appScheme": "tuyaSmart",
            "hotspotPrefixs": ["SmartLife"],
            "needBle": true // Sets the value to `true` to support pairing of Bluetooth devices.
                    "is_matter_support":true,
        },
    "colors":{
            "themeColor": "#FF5A28",
        }
    }
    

    Dependencies

    target 'your_target_name' do
       pod 'ThingSmartMatterInterface'  
    end
    
    target 'MatterExtension' do
       pod 'ThingSmartMatterExtensionKit'
    end
    

    Implement Matter Extension

    //
    // RequestHandler.swift
    // ThingMatterExtension
    //
    
    import MatterSupport
    import ThingSmartMatterExtensionKit
    
    // The extension is launched in response to `MatterAddDeviceRequest.perform()` and this class is the entry point
    // for the extension operations.
    class RequestHandler: MatterAddDeviceExtensionRequestHandler {
    
        override init() {
            super.init()
            ThingMatterExtensionSupport.shared.setMatterConfigKey(configKey: "your app group")
        }
    
        override func validateDeviceCredential(_ deviceCredential: MatterAddDeviceExtensionRequestHandler.DeviceCredential) async throws {
            ThingMatterExtensionSupport.shared.validateDeviceCredential(deviceCredential)
        }
    
        override func selectWi-FiNetwork(from wifiScanResults: [MatterAddDeviceExtensionRequestHandler.Wi-FiScanResult]) async throws -> MatterAddDeviceExtensionRequestHandler.Wi-FiNetworkAssociation {
            // Use this function to select a Wi-Fi network for the device if your ecosystem has special requirements.
            // Or, return `.defaultSystemNetwork` to use the iOS device's current network.
    //        return .defaultSystemNetwork
    
            return ThingMatterExtensionSupport.shared.selectWi-FiNetwork(from: wifiScanResults)
        }
    
        override func selectThreadNetwork(from threadScanResults: [MatterAddDeviceExtensionRequestHandler.ThreadScanResult]) async throws -> MatterAddDeviceExtensionRequestHandler.ThreadNetworkAssociation {
            // Use this function to select a Thread network for the device if your ecosystem has special requirements.
            // Or, return `.defaultSystemNetwork` to use the default Thread network.
            return ThingMatterExtensionSupport.shared.selectThreadNetwork(from: threadScanResults)
    //        return .defaultSystemNetwork
        }
    
        override func commissionDevice(in home: MatterAddDeviceRequest.Home?, onboardingPayload: String, commissioningID: UUID) async throws {
            // Use this function to commission the device with your Matter stack.
            ThingMatterExtensionSupport.shared.commissionDevice(in: home, onboardingPayload: onboardingPayload, commissioningID: commissioningID)
        }
    
        override func rooms(in home: MatterAddDeviceRequest.Home?) async -> [MatterAddDeviceRequest.Room] {
            // Use this function to return the rooms your ecosystem manages.
            // If your ecosystem manages multiple homes, ensure you are returning rooms that belong to the provided home.
            return [MatterAddDeviceRequest.Room(displayName: "room")]
        }
    
        override func configureDevice(named name: String, in room: MatterAddDeviceRequest.Room?) async {
            // Use this function to configure the (now) commissioned device with the given name and room.
            ThingMatterExtensionSupport.shared.configureDevice(named: name, in: room)
        }
    }
    

Service protocols

Provide services

The UI BizBundle relies on the implementation of the protocol ThingActivatorProtocol to provide services. You can view the ThingActivatorProtocol.h file in the ThingModuleServices component.

#ifndef ThingActivatorProtocol_h
#define ThingActivatorProtocol_h

typedef NS_ENUM(NSUInteger, ThingActivatorCompletionNode) {
    ThingActivatorCompletionNodeNormal
};

@class ThingSmartHome;

@protocol ThingActivatorProtocol <NSObject>

/**
 * Start config
 * Goto device config list view
 */
- (void)gotoCategoryViewController;

/**
 *  Obtain device information after each device connection
 *  @param node completion node, default ThingActivatorCompletionNodeNormal
 *  @param custionJump default false, set true for process not need to jump to de device panel
 */
- (void)activatorCompletion:(ThingActivatorCompletionNode)node customJump:(BOOL)customJump completionBlock:(void (^)(NSArray * _Nullable deviceList))callback;

/**
 *  Open qrcode view
 *  @param userInfo reserved parameter
 */
- (void)gotoQRCodeViewControllerWithUserInfo:(nullable NSDictionary *)userInfo;

@end
#endif /* ThingActivatorProtocol_h */

To customize the returned list of categories or products for pairing, implement the protocol methods provided by ThingActivatorExternalExtensionProtocol.

ThingActivatorExternalExtensionProtocol

/**
 *  Back action form category View Controller
 *  Need to implement when additional operations are needed
 */
- (BOOL)categoryViewControllerCustomBackAction;

Depend on services

The UI BizBundle depends on the method provided by the protocol ThingSmartHomeDataProtocol to get the current home details required for pairing. To call the UI BizBundle, you must implement this dependent protocol.

/**
 Returns the current home. If the current user does not have a home, `nil` is returned.

 @return ThingSmartHome
 */
- (ThingSmartHome *)getCurrentHome;

Usage instruction

Things to note

  • Before the call of any API method, make sure that the user has logged in to the app.

  • Before the UI BizBundle is used, the getCurrentHome method provided by the protocol ThingSmartHomeDataProtocol must be implemented first.

    Objective-C:

    #import <ThingSmartBizCore/ThingSmartBizCore.h>
    #import <ThingModuleServices/ThingSmartHomeDataProtocol.h>
    
    - (void)initCurrentHome {
        // Registers the protocol to be implemented.
        [[ThingSmartBizCore sharedInstance] registerService:@protocol(ThingSmartHomeDataProtocol) withInstance:self];
    }
    
    // Implements the protocol method.
    - (ThingSmartHome *)getCurrentHome {
        ThingSmartHome *home = [ThingSmartHome homeWithHomeId:@"Current home ID"];
        return home;
    }
    

    Swift:

    import ThingSmartDeviceKit
    
    class ThingActivatorTest: NSObject,ThingSmartHomeDataProtocol{
    
        func test() {
            ThingSmartBizCore.sharedInstance().registerService(ThingSmartHomeDataProtocol.self, withInstance: self)
        }
    
        func getCurrentHome() -> ThingSmartHome! {
            let home = ThingSmartHome.init(homeId: 111)
            return home
        }
    
    }
    

Start the pairing mode

Objective-C:

#import <ThingSmartBizCore/ThingSmartBizCore.h>
#import <ThingModuleServices/ThingActivatorProtocol.h>

- (void)gotoDeviceConfig {
    id<ThingActivatorProtocol> impl = [[ThingSmartBizCore sharedInstance] serviceOfProtocol:@protocol(ThingActivatorProtocol)];
    [impl gotoCategoryViewController];

    // Returns the pairing result.
    [impl activatorCompletion:ThingActivatorCompletionNodeNormal customJump:NO completionBlock:^(NSArray * _Nullable deviceList) {
        NSLog(@"deviceList: %@",deviceList);
    }];
}

Swift:

let impl = ThingSmartBizCore.sharedInstance().service(of: ThingActivatorProtocol.self) as? ThingActivatorProtocol
impl?.gotoCategoryViewController()

impl?.activatorCompletion(ThingActivatorCompletionNodeNormal, customJump: false, completionBlock: { (evIdList:[Any]?) in
            print(devIdList ?? [])
        })

Query custom categories for pairing

Objective-C:

#import <ThingSmartBizCore/ThingSmartBizCore.h>
#import <ThingModuleServices/ThingActivatorExternalExtensionProtocol.h>

- (void)initCurrentHome {
    // Registers the protocol to be implemented.
    [[ThingSmartBizCore sharedInstance] registerService:@protocol(ThingActivatorExternalExtensionProtocol) withInstance:self];
}

// Implements the protocol method.
- (BOOL)categoryViewControllerCustomBackAction {
    [self.navigationController popToRootViewControllerAnimated:YES];
    return YES;
}

Swift:

class ThingActivatorTest: NSObject,ThingActivatorExternalExtensionProtocol{

    func test() {
 ThingSmartBizCore.sharedInstance().registerService(ThingActivatorExternalExtensionProtocol.self, withInstance: self)
    }

    func categoryViewControllerCustomBackAction() -> Bool {
        self.navigationController?.popToRootViewController(animated: true)
        return true;
    }

}

Implement QR code scanning

Objective-C:

#import <ThingSmartBizCore/ThingSmartBizCore.h>
#import <ThingModuleServices/ThingActivatorProtocol.h>

- (void)gotoQRCodeViewController {
    // Registers the protocol to be implemented.
      id<ThingActivatorProtocol> impl = [[ThingSmartBizCore sharedInstance] serviceOfProtocol:@protocol(ThingActivatorProtocol)];
      if ([impl respondsToSelector:@selector(gotoQRCodeViewControllerWithUserInfo:)]) {
        [impl gotoQRCodeViewControllerWithUserInfo:nil];
    }
}

Swift:

if let impl = ThingSmartBizCore.sharedInstance.service(of: ThingActivatorProtocol.self),
   impl.responds(to: #selector(impl.gotoQRCodeViewController(withUserInfo:))) {
    impl.gotoQRCodeViewController(withUserInfo: nil)
}