Tuya Mesh

Last Updated on : 2024-03-20 03:54:06download

This topic describes the implementation of communication over Bluetooth based on Thing’s proprietary mesh networking technology, also known as Thing mesh. Each Thing mesh device serves as a child node, and multiple mesh devices form a mesh network, in which the child nodes communicate with each other by advertising. This topic provides the development guidance on pairing, control, and management of devices that use Thing mesh. For more information about Bluetooth mesh concepts, see Bluetooth Mesh.

Class name Description
ThingBLEMeshManager Encapsulates all API methods of Thing mesh.

Preparation

Enables Thing mesh.

// Enables Thing mesh during initialization.
[[ThingSmartSDK sharedInstance] setValue:@(YES) forKey:@"bleMeshEnable"];

Management

Thing mesh operation classes are included in the file ThingSmartBleMesh.h.

Create a mesh network

A home can belong to multiple mesh networks, but one mesh network is recommended for each home. Before the request, check whether a mesh network is created. If not, you can call this API method to create one.

All mesh operations are implemented based on the initialized home data. For more information, see Home Management.

API description

+ (void)createBleMeshWithMeshName:(NSString *)meshName
                           homeId:(long long)homeId
                          success:(void(^)(ThingSmartBleMeshModel *meshModel))success
                          failure:(ThingFailureError)failure;

Parameters

Parameter Description
meshName The name of the Thing mesh network. It can be customized.
homeId The home ID.
success The success callback.
failure The failure callback.

Example

ThingSmartHome *home = #<The initialized home instance>;
long long homeId = home.homeModel.homeId;
[ThingSmartBleMesh createBleMeshWithMeshName:@"yourMeshName" homeId:homeId success:^(ThingSmartBleMeshModel *meshModel) {
    // success do...
} failure:^(NSError *error) {
    NSLog(@"create mesh error: %@", error);
}];

The meshName of this method is a custom parameter. We recommend that you uniquely set it in the format of mesh+<timestamp>.

Delete a mesh network

API description

Deletes a mesh network. If sub-devices are included in the mesh group, they are also removed. In this case, the Wi-Fi connector is also removed.

- (void)removeMeshWithSuccess:(ThingSuccessHandler)success failure:(ThingFailureError)failure;

Parameters

Parameter Description
success The success callback.
failure The failure callback.

Example

self.mesh = #<ThingSmartBleMesh instance>;
[self.mesh removeMeshWithSuccess:^{
    // success do...
} failure:^(NSError *error) {
    XCTFail(@"test remove mesh failure: %@", error);
}];

Query a list of mesh networks in a home

API description

Returns a list of mesh networks for an initialized home instance.

- (void)getMeshListWithSuccess:(void(^)(NSArray <ThingSmartBleMeshModel *> *list))success
                       failure:(ThingFailureError)failure;

Parameters

Parameter Description
success The success callback.
failure The failure callback.

Example

ThingSmartHome *home = #<home instance>
[home getMeshListWithSuccess:^(NSArray<ThingSmartBleMeshModel *> *list) {
    // success do
} failure:^(NSError *error) {
    NSLog(@"get mesh list error: %@", error);
}];

Query a mesh instance

API description

+ (instancetype)bleMeshWithMeshId:(NSString *)meshId homeId:(long long)homeId;

Parameters

Parameter Description
meshId The mesh ID.
homeId The current home ID.

Example

You can create a mesh instance by using meshModel for the home instance of the ThingSmartHome class. Pass the mesh instance to ThingSmartUser. The SDK and the upper-layer encapsulation are based on whether ThingSmartUser has the value.

// The mesh network is not queried.
if ([ThingSmartUser sharedInstance].meshModel == nil) {
    ThingSmartHome *home = #<home instance>
    [home getMeshListWithSuccess:^(NSArray<ThingSmartBleMeshModel *> *list) {
            if (list.count > 0) {
                // Assigns values.
                [ThingSmartUser sharedInstance].meshModel = home.meshModel;
                [ThingSmartUser sharedInstance].mesh = [ThingSmartBleMesh bleMeshWithMeshId:home.meshModel.meshId homeId:home.meshModel.homeId];

                // Subsequence operations.
            } else {
                // The created mesh instance is used if no mesh information is found in the cloud.
                NSTimeInterval interval = [[NSDate date] timeIntervalSince1970];
                NSString *meshName = [NSString stringWithFormat:@"tymesh%.0f", interval];

                [ThingSmartBleMesh createBleMeshWithMeshName:meshName homeId:home.homeModel.homeId success:^(ThingSmartBleMeshModel *meshModel) {
                    // Assigns values.
                    [ThingSmartUser sharedInstance].meshModel = meshModel;
                    [ThingSmartUser sharedInstance].mesh = [ThingSmartBleMesh bleMeshWithMeshId:meshModel.meshId homeId:home.homeModel.homeId];

                    // Subsequence operations.
                } failure:^(NSError *error) {
                    // Processes errors.
                }];
            }
        } failure:^(NSError *error) {
            // Processes errors.
        }];
} else {
    // Subsequence operations.
}

Connect to a mesh sub-device

Connect a paired device to a Thing mesh network. During this process, Bluetooth must be enabled.

API description

  • To run only a pairing task, enter the default mesh name and password. Then, only
    - (void)bleMeshManager:(ThingBLEMeshManager *)manager didScanedDevice:(ThingBleMeshDeviceModel *)device; of ThingBLEMeshManagerDelegate returns the scanning result.

  • To connect a paired device to a mesh network, enter the name and password of the created mesh network. The data is returned by cloud-based API methods. Then, the paired device is automatically connected to the mesh network. The system also automatically queries the online status of each device once on the mesh network.

    - (void)startScanWithName:(NSString *)name
    					pwd:(NSString *)pwd
    				active:(BOOL)active
    			wifiAddress:(uint32_t)wifiAddress
    			otaAddress:(uint32_t)otaAddress;
    

Parameters

Parameter Description
name The name of the mesh network.
pwd The password of the mesh network.
active Specifies whether to pair and activate a device.
wifiAddress The Wi-Fi address. This parameter is required for pairing a gateway and set to 0 for other types of devices.
otaAddress The IP address of the OTA update device. This parameter is required for OTA update and set to 0 for other types of devices.

Callback

Queries the online status of all devices on a mesh network after a paired device is connected to the mesh network. In the callback, the delegate method ThingSmartHomeDelegate is called.

// Device information such as a device name is changed.
- (void)home:(ThingSmartHome *)home deviceInfoUpdate:(ThingSmartDeviceModel *)device;

Example

// The parameters of `active`, `wifiAddress`, and `otaAddress`.
[[ThingBLEMeshManager sharedInstance] startScanWithName:[ThingSmartUser sharedInstance].meshModel.code pwd:[ThingSmartUser sharedInstance].meshModel.password active:NO wifiAddress:0 otaAddress:0];

// Device information such as a device name is changed.
- (void)home:(ThingSmartHome *)home deviceInfoUpdate:(ThingSmartDeviceModel *)device {
    // The callback.
}

Pairing

A Bluetooth device in the reset and disconnected state can be paired to join a mesh network. Mesh devices to be paired are classified into:

  • A Thing mesh sub-device, such as lights, sockets, and low-power devices. This type of device runs without a gateway.
  • A mesh gateway.

Thing mesh operation classes are included in the file ThingBLEMeshManager. It is a singleton class.

Reset devices

The default name of a device in the reset state is out_of_mesh and the default password is 123456. The following list describes common device resetting methods.

Product category Reset method State pending pairing
Lighting Turn on and off the light consecutively three times in a row The indicator is flickering quickly.
Socket Tap and hold the switch for three seconds The indicator is flickering quickly.
Gateway Tap and hold the switch for three seconds The red and blue indicators are flickering quickly.
Low-power device Tap and hold the switch for three seconds Press the switch once again to see that the indicator is steady on. The pairing process must be completed when the indicator is on.
Alarm Tap and hold the switch for three seconds The indicator is flickering quickly.

Scan for sub-devices pending pairing

To simplify scanning and subsequent pairing operations, Thing encapsulates all operations in the same API.

  • To run only a pairing task, enter the default mesh name and password. Then, only
    - (void)bleMeshManager:(ThingBLEMeshManager *)manager didScanedDevice:(ThingBleMeshDeviceModel *)device; of ThingBLEMeshManagerDelegate returns the scanning result.

  • To connect a paired device to a mesh network, enter the name and password of the created mesh network. The data is returned by cloud-based API methods. Then, the paired device is automatically connected to the mesh network. The system also automatically queries the online status of each device once on the mesh network.

API description

- (void)startScanWithName:(NSString *)name
                      pwd:(NSString *)pwd
                   active:(BOOL)active
              wifiAddress:(uint32_t)wifiAddress
               otaAddress:(uint32_t)otaAddress;

Parameters

Parameter Description
name The name of the mesh network.
pwd The password of the mesh network.
wifiAddress The Wi-Fi address. This parameter is required for pairing a gateway and set to 0 for other types of devices.
otaAddress The IP address of the OTA update device. This parameter is required for OTA update and set to 0 for other types of devices.

Callback

  • If name is the default value out_of_mesh in an activation task, the system will scan for surrounding devices to be paired. In the callback, ThingBLEMeshManagerDelegate returns the scanning result.

  • To connect a paired device to a mesh network, subsequent operations will automatically proceed without a callback. The API calls are similar to those for connecting to and disconnecting from a mesh network.

    - (void)bleMeshManager:(ThingBLEMeshManager *)manager didScanedDevice:(ThingBleMeshDeviceModel *)device;
    

Parameters

Parameter Description
manager The mesh manager.
device The information about the device pending pairing.

Example

// Starts scanning for a device pending pairing.
[[ThingBLEMeshManager sharedInstance] startScanWithName:@"out_of_mesh" pwd:@"123456" active:YES wifiAddress:0 otaAddress:0];

// The callback of `ThingBLEMeshManagerDelegate`.
- (void)bleMeshManager:(ThingBLEMeshManager *)manager didScanedDevice:(ThingBleMeshDeviceModel *)device {

    // This callback method applies to scanning for both gateways and sub-devices.
    // `device.type` and `device.vendorInfo` determines whether the target device is a mesh gateway.
    if (device.type == [TPUtils getIntValueByHex:@"0x0108"] || ([TPUtils getIntValueByHex:[device.vendorInfo substringWithRange:NSMakeRange(0, 2)]] & 0x08) == 0x08) {
          // The mesh gateway.
        return;
    } else {
        // Mesh sub-devices.
    }
}

// Implements `getIntValueByHex`.
+ (uint32_t)getIntValueByHex:(NSString *)getStr
{
    NSScanner *tempScaner=[[NSScanner alloc] initWithString:getStr];
    uint32_t tempValue;
    [tempScaner scanHexInt:&tempValue];
    return tempValue;
}

Activate sub-devices

API description

- (void)activeMeshDeviceIncludeGateway:(BOOL)includeGateway;

Parameters

Parameter Description
includeGateway Indicates whether to activate a gateway. A value of yes indicates that a discovered gateway, rather than the sub-devices, will be activated. Otherwise, all discovered devices rather than the gateway will be activated.

Callback

- (void)activeDeviceSuccessWithName:(NSString *)name deviceId:(NSString *)deviceId error:(NSError *)error;

Parameters

Parameter Description
name The name of the device.
deviceId The device ID.
error The error message that might be returned during activation. If it is returned, name and deviceId are empty.

Activate a specific sub-device

API description

- (void)activeMeshDevice:(ThingBleMeshDeviceModel *)deviceModel;

Parameters

Parameter Description
deviceModel The device model.

The pairing result will be returned by ThingBLEMeshManagerDelegate.

Callback

- (void)activeWifiDeviceWithName:(NSString *)name address:(NSInteger)address mac:(NSInteger)mac error:(NSError *)error;

Parameters

Parameter Description
name The name of the device.
address The IP address of the device.
mac The MAC address of the gateway.
error The failure callback.

Query the pairing token for a mesh gateway

If the target device is a gateway device, after the callback of activeWifiDeviceWithName, the pairing with the Wi-Fi module must be implemented. The method ThingSmartActivator is called.

API description

This token is valid for 10 minutes.

- (void)getTokenWithMeshId:(NSString *)meshId
                    nodeId:(NSString *)nodeId
                 productId:(NSString *)productId
                      uuid:(NSString *)uuid
                   authKey:(NSString *)authKey
                   version:(NSString *)version
                   success:(ThingSuccessString)success
                   failure:(ThingFailureError)failure;

Parameters

Parameter Description
meshId The mesh ID.
nodeId The node ID.
productId The product ID (PID).
uuid The UUID of the device.
authKey The AuthKey of the device.
success The success callback. A pairing token is returned.
failure The failure callback.

Pair a mesh gateway

Pairs a mesh gateway by using the pairing token and the hotspot name and password of the router. This method can be called only the callback of activeWifiDeviceWithName of ThingBLEMeshManagerDelegate is executed.

API description

- (void)startBleMeshConfigWiFiWithSsid:(NSString *)ssid
                              password:(NSString *)password
                                 token:(NSString *)token
                               timeout:(NSTimeInterval)timeout;

Parameters

Parameter Description
ssid The hotspot name of the router.
password The hotspot password of the router.
token The pairing token.
timeout The timeout value of a pairing task. Default value: 100. Unit: seconds.

Example

// Pairs a mesh device without a mesh gateway.
// 1. Activates a sub-device.
[[ThingBLEMeshManager sharedInstance] activeMeshDeviceIncludeGateway:NO];

// 2. Executes the callback of `ThingBLEMeshManagerDelegate`.
- (void)activeDeviceSuccessWithName:(NSString *)name deviceId:(NSString *)deviceId error:(NSError *)error {

    if (error) {
        NSLog(@"error : %@", error);
        return;
    }

    // 3. A sub-device is activated.
}
// Activates the mesh gateway.
// 1. Activates a sub-device.
[[ThingBLEMeshManager sharedInstance] activeMeshDeviceIncludeGateway:NO];

// 2. Executes the callback of `ThingBLEMeshManagerDelegate`.
- (void)activeWifiDeviceWithName:(NSString *)name address:(NSInteger)address mac:(NSInteger)mac error:(NSError *)error {
    if (error) {
       NSLog(@"error : %@", error);
       return;
    }

    // The gateway is activated. Only the Bluetooth module is activated, and you need to continue to activate the Wi-Fi module.
    // 3. The user enters the password for reconnection. After the device is reconnected, the SSID, password, and token are sent.
    // This operation is required. Otherwise, a Wi-Fi data writing error will occur and cause the pairing task to be failed.
    [ThingBLEMeshManager sharedInstance].wifiMac = (int)mac;

    // 4. Returns the pairing token.
    NSString *nodeId = [NSString stringWithFormat:@"%02x", (int)address];
    [[ThingSmartActivator sharedInstance] getTokenWithMeshId:[ThingSmartUser sharedInstance].meshModel.meshId
                                                 nodeId:nodeId
                                              productId:[ThingBLEMeshManager sharedInstance].productId
                                                   uuid:[ThingBLEMeshManager sharedInstance].uuid
                                                authKey:[ThingBLEMeshManager sharedInstance].authKey
                                                version:[ThingBLEMeshManager sharedInstance].version
                                                success:^(NSString *token) {
                                                    // 5. Sets a pairing delegate to receive the activation result.
                                                    [ThingSmartActivator sharedInstance].delegate = self;
                                                    // 6. Starts Wi-Fi pairing.
                                                    [[ThingSmartActivator sharedInstance] startBleMeshConfigWiFiWithSsid:@"Wi-Fi name" password:@"Wi-Fi password" token:token timeout:100];
                                                } failure:^(NSError *error) {
                                                    NSLog(@"error: %@", error);
                                                }];
}

- (void)meshActivator:(ThingSmartActivator *)activator didReceiveDeviceId:(NSString *)deviceId meshId:(NSString *)meshId error:(NSError *)error {
      // 7. Returns the activation result.

  }

Identify mesh connections

Checks whether Bluetooth devices are connected to a mesh network. This result determines the way to send control and operation commands.

// The mesh connection tag. If a Bluetooth device is connected to the mesh network, this value is `yes`.
BOOL isLogin = [ThingBLEMeshManager sharedInstance].isLogin;

Pairing error codes

Error code Description
3088 Failed to activate the device.
3090 The specified mesh name and password are incorrect.
3091 Failed to log in.
3092 Failed to log in and decrypt.
3093 Failed to query the AuthKey.
3094 The length of the address has exceeded the upper limit.
3095 Failed to change the address.
3096 Failed to write the mesh information.
3097 The mesh information is empty.
3098 The mesh device has not been connected to the network.
3099 Failed to write data.
4000 An error has occurred while processing the Wi-Fi information.
4001 The Wi-Fi pairing token is incorrect.
4010 A timeout error has occurred while logging in.
4011 A timeout error has occurred while querying AuthKey.
4012 A timeout error has occurred while modifying the address.
4013 A timeout error has occurred while writing the mesh information.
4014 A timeout error has occurred while setting the Wi-Fi information.

Devices

The device class is ThingSmartDevice. In this class, the deviceType field of ThingSmartDeviceModel indicates a device type. The value of deviceType for mesh devices is ThingSmartDeviceModelTypeSIGMeshSubDev.

Rename a sub-device

API description

- (void)renameMeshSubDeviceWithDeviceId:(NSString *)deviceId name:(NSString *)name success:(ThingSuccessHandler)success failure:(ThingFailureError)failure;

Parameters

Parameter Description
deviceId The device ID.
name The new name.
success The success callback.
failure The failure callback.

Example

[[ThingSmartUser sharedInstance].mesh renameMeshSubDeviceWithDeviceId:self.device.devId name:name success:^{
            // success do
        } failure:^(NSError *error) {
            // failure do
        }];

Add a paired device to a mesh network (v2.0)

The SDK automatically processes this method during pairing. You can ignore this method.

- (void)addSubDeviceWithUuid:(NSString *)uuid
                      homeId:(long long)homeId
                     authKey:(NSString *)authKey
                      nodeId:(NSString *)nodeId
                  productKey:(NSString *)productKey
                         ver:(NSString *)ver
                     success:(void (^)(NSString *devId, NSString *name))success
                     failure:(ThingFailureError)failure;

Parameters

Parameter Description
uuid The short address of a Bluetooth sub-device.
authKey The authorization key.
nodeId The mesh node ID (short address).
productKey The product ID.
ver The version number.
success The success callback.
failure The failure callback.

Example

[[ThingSmartUser sharedInstance].mesh addSubDeviceWithUuid:_uuid homeId:[ThingSmartUser sharedInstance].meshModel.homeId authKey:_authKey nodeId:nodeHex productKey:_selectedPeripheral.productId ver:_selectedPeripheral.version success:^(NSString *devId, NSString *name) {
                    // success do
                    } failure:^(NSError *error) {
                    // failure do
                    }];

Locally connect to sub-devices

Mesh sub-devices can be connected locally or in another online status. Connects to a mesh device over Bluetooth from a mobile phone on which Bluetooth is enabled. Commands are sent to the device over Bluetooth. You can use deviceModel.isOnline && deviceModel.isMeshBleOnline to check the device connection status.

Connect to sub-devices through a gateway

Mesh sub-devices can also be connected through a gateway. Connect to a mesh device through a mesh gateway from a mobile phone on which Bluetooth is disabled or that is far away from the device. Commands are sent to the device over Wi-Fi. You can use deviceModel.isOnline && !deviceModel.isMeshBleOnline to check the device connection status.

Remove a sub-device

Removes a sub-device from both the cloud and the local app.

Locally remove a sub-device

// Removes the device over Bluetooth.
- (void)kickoutLightWithAddress:(uint32_t)address type:(NSString *)type;

// Removes the device through a gateway.
- (NSString *)rawDataKickoutLightWithAddress:(uint32_t)address type:(NSString *)type;

   /**
    Sends commands of Raw type to the device.

    @param raw The value of Raw type.
    @param success The success callback.
    @param failure The failure callback.
    */
- (void)publishRawDataWithRaw:(NSString *)raw
                          pcc:(NSString *)pcc
                      success:(ThingSuccessHandler)success
                      failure:(ThingFailureError)failure;

Remove a sub-device from the cloud

- (void)removeMeshSubDeviceWithDeviceId:(NSString *)deviceId success:(ThingSuccessHandler)success failure:(ThingFailureError)failure;

Parameters

Parameter Description
deviceId The device ID.
success The success callback.
failure The failure callback.

Example

 int address = [smartDevice.deviceModel.nodeId intValue] << 8;

        // 1. Removes the device from the cloud.
        [[ThingSmartUser sharedInstance].mesh removeMeshSubDeviceWithDeviceId:[smartDevice.deviceModel.devId success:^{

        } failure:^(NSError *error) {

        }];

        // 2. Locally removes the device.
        // Checks whether the device is connected through a gateway or over Bluetooth.
        if ([ThingBLEMeshManager sharedInstance].isLogin) {

            [[ThingBLEMeshManager sharedInstance] kickoutLightWithAddress:address type:[smartDevice.deviceModel.pcc];

        } else {

            [[ThingSmartUser sharedInstance].mesh publishRawDataWithRaw:[[ThingBLEMeshManager sharedInstance] rawDataKickoutLightWithAddress:address type:[smartDevice.deviceModel.pcc] pcc:[smartDevice.deviceModel.pcc success:^{

            } failure:^(NSError *error) {

            }];
        }

Query sub-device status

API description

- (void)getDeviceStatusAllWithAddress:(uint32_t)address
                                 type:(NSString *)type;

Parameters

Parameter Description
address The IP address of the device.
type The category and type of the device.

Groups

Certain devices on a mesh network can be grouped, so they can be controlled with group control commands. For example, all lights are added to a group. Users can control the switch status and colors of the group and thus control all lights in the group with the same properties.

The following methods of ThingSmartBleMeshGroup are available.

Create a mesh group

  • The value of localId for a mesh group starts from 0x8001 and is sequentially incremented.

  • A mesh group and its sub-devices follow the same rules of categories and types.

  • Currently, each mesh network supports up to 255 groups and each device can be added to up to 8 groups at the same time.

    We recommend that devices of different categories do not belong to the same group. Otherwise, group device control might fail due to different device features.

API description

+ (void)createMeshGroupWithGroupName:(NSString *)groupName
                              meshId:(NSString *)meshId
                             localId:(NSString *)localId
                                 pcc:(NSString *)pcc
                             success:(ThingSuccessInt)success
                             failure:(ThingFailureError)failure;

Parameters

Parameter Description
groupName The name of the mesh group.
meshId The mesh ID.
localId The local short address of the group.
pcc The category and type of the group device.
success The success callback.
failure The failure callback.

Example

NSInteger localId = 0x8001;
[ThingSmartBleMeshGroup createMeshGroupWithGroupName:@<Group name> meshId:[ThingSmartUser sharedInstance].meshModel.meshId localId:[NSString stringWithFormat:@"%lx", localId] pcc:#<The category and type of the group> success:^(int result) {
     // success do
    // Queries the group instance.
     self.meshGroup = [ThingSmartBleMeshGroup meshGroupWithGroupId:result];

    } failure:^(NSError *error) {
       // failure do
    }];

Add sub-devices to a mesh group

Before a sub-device can be added to a mesh group, it must be verified both locally and in the cloud. Multiple sub-devices must be added one by one to the mesh group. They cannot be removed concurrently in the same task.

Process

Tuya Mesh

API description

// Locally-connected sub-device.
// The result is returned by `ThingBLEMeshManagerDelegate`.
- (void)addDeviceAddress:(uint32_t)deviceAddress type:(NSString *)type groupAddress:(uint32_t)groupAddress;

// ThingBLEMeshManagerDelegate
- (void)deviceAddGroupAddress:(uint32_t)address error:(NSError *)error;

// Sub-device connected through a gateway.
  // Queries the command of Raw type to add a sub-device to a mesh group.
- (NSString *)rawDataAddDeviceAddress:(uint32_t)deviceAddress groupAddress:(uint32_t)groupAddress type:(NSString *)type;

API description

Sends pass-through commands to the device.

- (void)publishRawDataWithRaw:(NSString *)raw
                            pcc:(NSString *)pcc
                        success:(ThingSuccessHandler)success
                        failure:(ThingFailureError)failure;

  // The result is returned by ``ThingSmartBleMeshDelegate` - (void)bleMeshReceiveRawData:(NSString *)raw`.
  // ThingSmartBleMeshDelegate
- (void)bleMeshReceiveRawData:(NSString *)raw;

Parameters

Parameter Description
raw The value of Raw type.
success The success callback.
failure The failure callback.

API description

Records the operation in the cloud after the verification and continues to add the next sub-device.

- (void)addDeviceWithDeviceId:(NSString *)deviceId success:(ThingSuccessHandler)success failure:(ThingFailureError)failure;

Parameters

Parameter Description
success The success callback.
failure The failure callback.

Example

- (void)addDeviceToGroup:(ThingSmartDeviceModel *)model {
        int nodeId = [model.nodeId intValue] << 8;
        // Records the IP address of the current device for future use.
        _address = nodeId >> 8;

        if ([ThingBLEMeshManager sharedInstance].isLogin) {
            // Bluetooth LE
            [[ThingBLEMeshManager sharedInstance] addDeviceAddress:nodeId type:self.meshGroup.meshGroupModel.pcc groupAddress:[self.meshGroup.meshGroupModel.localId intValue]];
        } else {
            // Wi-Fi
            [[ThingSmartUser sharedInstance].mesh publishRawDataWithRaw:[[ThingBLEMeshManager sharedInstance] rawDataAddDeviceAddress:nodeId groupAddress:[self.meshGroup.meshGroupModel.localId intValue] type:self.meshGroup.meshGroupModel.pcc] pcc:self.meshGroup.meshGroupModel.pcc success:^{
            } failure:^(NSError *error) {
            }];
        }

        // The current operation is flagged as adding a device.
        _isAdd = YES;

    // Customizes a timeout value. After this timeout period, the failure callback is executed and the system continues to add the next device. Recommended value: `5`. Unit: seconds.
}

#pragma mark - ThingBLEMeshManagerDelegate
- (void)deviceAddGroupAddress:(uint32_t)address; {
    NSLog(@" --- deviceAddGroupAddress %d ", address);

    if (_address == address) {

            [self.meshGroup addDeviceWithDeviceId:_devId success:^{
                // Proceeds to add the next device after the success callback.
            } failure:^(NSError *error) {

            }];
    }
}

#pragma mark - ThingSmartBleMeshDelegate

// Adds sub-devices that are connected through a gateway to a mesh group.
- (void)bleMeshReceiveRawData:(NSString *)raw {
    if ([[raw substringWithRange:NSMakeRange(4, 2)] isEqualToString:@"d4"] && _address == [TPUtils getIntValueByHex:[raw substringWithRange:NSMakeRange(0, 2)]]) {

        if (raw.length < 14) {
            NSLog(@"Length error of raw data.");
            return;
        }

        BOOL isNewProtocol = [TPUtils getIntValueByHex:[raw substringWithRange:NSMakeRange(10, 2)]] == 255;

        if (isNewProtocol) {
            int state = [TPUtils getIntValueByHex:[raw substringWithRange:NSMakeRange(12, 2)]];

            if (state == 1 || state == 255) {
                NSLog(@"The device is added to the group.");
            } else {
                   // Proceeds to add the next device after the failure callback.
                return;
            }

        }

            [self.meshGroup addDeviceWithDeviceId:_devId success:^{
                // Proceeds to add the next device after the success callback.
            } failure:^(NSError *error) {
            }];
    }
}

Remove sub-devices from a group

Similar to the addition process, before a sub-device can be removed from a mesh group, it must be verified both locally and in the cloud. Multiple sub-devices must be removed one by one from the mesh group. They cannot be removed concurrently in the same task.

Process

Tuya Mesh

API description

// Locally-connected sub-device.
// The result is returned by `ThingBLEMeshManagerDelegate`.
- (void)deleteDeviceAddress:(uint32_t)deviceAddress type:(NSString *)type groupAddress:(uint32_t)groupAddress;

// ThingBLEMeshManagerDelegate
- (void)deviceAddGroupAddress:(uint32_t)address error:(NSError *)error;

// Sub-device connected through a gateway.
// Queries the command of Raw type to remove a sub-device from a mesh group.
- (NSString *)rawDataDeleteDeviceAddress:(uint32_t)deviceAddress groupAddress:(uint32_t)groupAddress type:(NSString *)type;

API description

- (void)publishRawDataWithRaw:(NSString *)raw
                          pcc:(NSString *)pcc
                      success:(ThingSuccessHandler)success
                      failure:(ThingFailureError)failure;

// The result is returned by ``ThingSmartBleMeshDelegate` - (void)bleMeshReceiveRawData:(NSString *)raw`.
// ThingSmartBleMeshDelegate
- (void)bleMeshReceiveRawData:(NSString *)raw;

Parameters

Parameter Description
raw The value of Raw type.
success The success callback.
failure The failure callback.

API description

Records the operation in the cloud after the verification and continues to add the next sub-device.

- (void)removeDeviceWithDeviceId:(NSString *)deviceId success:(ThingSuccessHandler)success failure:(ThingFailureError)failure;

Parameters

Parameter Description
deviceId The device ID.
success The success callback.
failure The failure callback.

Example

- (void)deleteDeviceFromGroup:(ThingSmartDeviceModel *)model {

        int nodeId = [model.nodeId intValue] << 8;

        // Records the IP address of the current device for future use.
        _address = nodeId >> 8;
        if ([ThingBLEMeshManager sharedInstance].isLogin) {
            // Bluetooth LE
            [[ThingBLEMeshManager sharedInstance] deleteDeviceAddress:nodeId type:self.meshGroup.meshGroupModel.pcc groupAddress:[self.meshGroup.meshGroupModel.localId intValue]];
        } else {
            // Wi-Fi
            [[ThingSmartUser sharedInstance].mesh publishRawDataWithRaw:[[ThingBLEMeshManager sharedInstance] rawDataDeleteDeviceAddress:nodeId groupAddress:[self.meshGroup.meshGroupModel.localId intValue] type:self.meshGroup.meshGroupModel.pcc] pcc:self.meshGroup.meshGroupModel.pcc success:^{
            } failure:^(NSError *error) {
            }];
        }

        // The current operation is flagged as removing a device.
        _isAdd = NO;

    // Customizes a timeout value. After this timeout period, the failure callback is executed and the system continues to add the next device. Recommended value: `5`. Unit: seconds.
}

#pragma mark - ThingBLEMeshManagerDelegate
- (void)deviceAddGroupAddress:(uint32_t)address; {
    NSLog(@" --- deviceAddGroupAddress %d ", address);

    if (_address == address) {

            [self.meshGroup removeDeviceWithDeviceId:_devId success:^{
                // Proceeds to add the next device after the success callback.
            } failure:^(NSError *error) {
            }];
    }
}

#pragma mark - ThingSmartBleMeshDelegate

// Adds sub-devices that are connected through a gateway to a mesh group.
- (void)bleMeshReceiveRawData:(NSString *)raw {
    if ([[raw substringWithRange:NSMakeRange(4, 2)] isEqualToString:@"d4"] && _address == [TPUtils getIntValueByHex:[raw substringWithRange:NSMakeRange(0, 2)]]) {

        if (raw.length < 14) {
            NSLog(@"Length error of raw data.");
            return;
        }

        BOOL isNewProtocol = [TPUtils getIntValueByHex:[raw substringWithRange:NSMakeRange(10, 2)]] == 255;

        if (isNewProtocol) {
            int state = [TPUtils getIntValueByHex:[raw substringWithRange:NSMakeRange(12, 2)]];

            if (state == 1 || state == 255) {
                NSLog(@"The device is added to the group.");
            } else {
                   // Proceeds to add the next device after the failure callback.
                return;
            }

        }

            [self.meshGroup removeDeviceWithDeviceId:_devId success:^{
                // Proceeds to remove the next device after the success callback.
            } failure:^(NSError *error) {
            }];
    }
}

Query a mesh group instance

API description

+ (instancetype)meshGroupWithGroupId:(NSInteger)groupId;

Parameters

Parameter Description
groupId The group ID.

groupId is different from localId. It is the group ID returned from the cloud after the group is created. All group operations require the address indicated by localId, rather than the group ID.

Rename a mesh group

API description

- (void)updateMeshGroupName:(NSString *)meshGroupName success:(ThingSuccessHandler)success failure:(ThingFailureError)failure;

Parameters

Parameter Description
meshGroupName The name of the mesh group.
success The success callback.
failure The failure callback.

Delete a mesh group

Deletes a mesh group locally or from the cloud, in a similar way like removing a device.

API description

// Locally remove the device.
- (void)deleteGroupAddress:(uint32_t)groupAddress type:(NSString *)type;

// Sub-device connected through a gateway.
- (NSString *)rawDataDeleteGroupAddress:(uint32_t)groupAddress type:(NSString *)type

API description

// Sends commands of Raw type to the device.
- (void)publishRawDataWithRaw:(NSString *)raw
                          pcc:(NSString *)pcc
                      success:(ThingSuccessHandler)success
                      failure:(ThingFailureError)failure;

Parameters

Parameter Description
raw The value of Raw type.
success The success callback.
failure The failure callback.

API description

// Removes the device from the cloud.
- (void)removeMeshGroupWithSuccess:(ThingSuccessHandler)success failure:(ThingFailureError)failure;

Parameters

Parameter Description
success The success callback.
failure The failure callback.

Example

[self.meshGroup removeMeshGroupWithSuccess:^{
		// The success callback.
} failure:^(NSError *error) {
	// The failure callback.
}];

// Locally-connected sub-device.
if ([ThingBLEMeshManager sharedInstance].isLogin) {

	// Removes a group over Bluetooth.
	[[ThingBLEMeshManager sharedInstance] deleteGroupAddress:[self.meshGroup.meshGroupModel.localId intValue] type:self.meshGroup.meshGroupModel.pcc];
} else {
	// Wi-Fi
	// Removes a group through a gateway.
	[[ThingSmartUser sharedInstance].mesh publishRawDataWithRaw:[[ThingBLEMeshManager sharedInstance] rawDataDeleteGroupAddress:[self.meshGroup.meshGroupModel.localId intValue] type:self.meshGroup.meshGroupModel.pcc] pcc:self.meshGroup.meshGroupModel.pcc success:^{
	} failure:^(NSError *error) {
	}];
}

Query a mesh group device

API description

- (void)getDeviveListInfoWithSuccess:(void (^)(NSArray <ThingSmartDeviceModel *> *deviceList))success failure:(ThingFailureError)failure;

Example

[self.meshGroup getDeviveListInfoWithSuccess:^(NSArray<ThingSmartDeviceModel *> *deviceList) {
        // The success callback.
} failure:^(NSError *error) {
            // The failure callback.
        }];

Control

Smart devices are managed with DPs. Thing mesh devices are also controlled by device DPs.

Mesh commands carry DP data when they are sent to target devices.

Command format

DPs are sent to control devices in the following format: {"(dpId)" : "(dpValue)"}. Example: @{@"101" : @"44"}. For more information about DPs, see Device Control.

Send DPs to control a device

API description

- (void)publishNodeId:(NSString *)nodeId
                  pcc:(NSString *)pcc
                  dps:(NSDictionary *)dps
              success:(ThingSuccessHandler)success
              failure:(ThingFailureError)failure;

Parameters

Parameter Description
nodeId The short address of a Bluetooth sub-device.
pcc The product category and type.
dps The DPs in the dictionary format.
success The success callback.
failure The failure callback.

Example

int address = [[self.smartDevice deviceModel].nodeId intValue] << 8;

[self.mesh publishNodeId:[NSString stringWithFormat:@"%d", address] pcc:self.smartDevice.deviceModel.pcc dps:@{@"1":@(1)} success:^{
    // success do
    } failure:^(NSError *error) {
    // error do
}];

Send DPs to control a group

API description

- (void)multiPublishWithLocalId:(NSString *)localId
                            pcc:(NSString *)pcc
                            dps:(NSDictionary *)dps
                        success:(ThingSuccessHandler)success
                        failure:(ThingFailureError)failure;

Parameters

Parameter Description
localId localId
pcc The product category and type.
dps The DPs in the dictionary format.
success The success callback.
failure The failure callback.

Example

int address = [[self.meshGroup meshGroupModel].localId intValue];

[self.mesh multiPublishWithLocalId:[NSString stringWithFormat:@"%d", address] pcc:self.meshGroup.meshGroupModel.pcc dps:@{@"1":@(1)} success:^{
    // success do
    } failure:^(NSError *error) {
    // error do
}];

Send data of Raw type

ThingBLEMeshManager provides commands to send data of Raw type.

Sends commands of Raw type to devices

API description

- (void)publishRawDataWithRaw:(NSString *)raw
                          pcc:(NSString *)pcc
                      success:(ThingSuccessHandler)success
                      failure:(ThingFailureError)failure;

Parameters

Parameter Description
raw The value of Raw type.
success The success callback.
failure The failure callback.

Update device data

Updates device data. The device response is returned by the delegate ThingSmartHomeDelegate.

API description

// Updates DP data.
- (void)home:(ThingSmartHome *)home device:(ThingSmartDeviceModel *)device dpsUpdate:(NSDictionary *)dps;

Update

A unified method for OTA firmware updates has been implemented in SDK v3.35.5 and later versions. For more information, see Firmware Update.

If you do not opt for the simplified OTA process, continue with the section below.

Get firmware update information

For more information, see Get Firmware Update Information.

Update sub-devices

Before the update, make sure that the target device has been connected over Bluetooth.

  • To run only a pairing task, enter the default mesh name and password. Then, only
    - (void)bleMeshManager:(ThingBLEMeshManager *)manager didScanedDevice:(ThingBleMeshDeviceModel *)device; of ThingBLEMeshManagerDelegate returns the scanning result.

  • To connect a paired device to a mesh network, enter the name and password of the created mesh network. The data is returned by cloud-based API methods. Then, the paired device is automatically connected to the mesh network. The system also automatically queries the online status of each device once on the mesh network.

API description

- (void)startScanWithName:(NSString *)name
                      pwd:(NSString *)pwd
                   active:(BOOL)active
              wifiAddress:(uint32_t)wifiAddress
               otaAddress:(uint32_t)otaAddress;

Parameters

Parameter Description
name The name of the mesh network.
pwd The password of the mesh network.
active Specifies whether to pair and activate a device.
wifiAddress The Wi-Fi address. This parameter is required for pairing a gateway and set to 0 for other types of devices.
otaAddress The IP address of the OTA update device. This parameter is required for OTA update and set to 0 for other types of devices.

The pairing result will be returned by ThingBLEMeshManagerDelegate.

API description

Connects to the mesh network to enable the update.

- (void)notifyLoginSuccessWithAddress:(uint32_t)address;

Parameters

Parameter Description
address The IP address of the device.

Send update package after callback

- (void)sendOTAPackWithAddress:(NSInteger)address version:(NSString *)version otaData:(NSData *)otaData success:(ThingSuccessHandler)success failure:(ThingFailureHandler)failure;

Parameters

Parameter Description
address The IP address of the device.
version The version number.
otaData The update data.
success The success callback.
failure The failure callback.

Update version number in the cloud

- (void)updateDeviceVersion:(NSString *)version type:(NSInteger)type success:(ThingSuccessHandler)success failure:(ThingFailureError)failure;

Parameters

Parameter Description
version The version number.
type The type of firmware.
success The success callback.
failure The failure callback.

Example

1. Prepare for the update.
int otaAddress = [self.device.deviceModel.nodeId intValue] << 8;
// Connected without a gateway.
    [[ThingBLEMeshManager sharedInstance] startScanWithName:[ThingSmartUser sharedInstance].meshModel.code pwd:[ThingSmartUser sharedInstance].meshModel.password active:NO wifiAddress:0 otaAddress:otaAddress];
    [ThingBLEMeshManager sharedInstance].delegate = self;

2. Receive the callback and send the update package.
- (void)notifyLoginSuccessWithAddress:(uint32_t)address {
    [[ThingBLEMeshManager sharedInstance] sendOTAPackWithAddress:address version:@"Target version number" otaData:_otaData success:^{
        [self updateVersion];
    } failure:^{
        NSLog(@"ota failure!");
    }];
}

3. Update the version number in the cloud.
- (void)updateVersion {
    WEAKSELF_AT
    [self.smartDevice updateDeviceVersion:_upgradeModel.version type:_upgradeModel.type success:^{
       // success do..
    } failure:^(NSError *error) {
       // error do..
    }];
}

Update light format in smart scenes

Before the update, make sure that the firmware supports smart scenes.

Scenes 1 to 4 are the static color mode. Update Scene 1:

{set_scene1="0ff808000000000E0"}

`0`: the static color mode
`ff`: R
`80`: G
`80`: B
`00`: W, warm
`00`: C, cold
`00`: L, brightness
`00`: S, step (set to `0`)
`E0`: V, the validity of `RGBWCLS`. `RGB` validity is `E0` and `WCL` validity is `1C`.

Scenes 5 to 8 are the dazzling mode. Update Scene 5:

{set_scene5="180ff560055AA0055AA"}

`1`: the dazzling mode
`80`: L, brightness of `HLS`
`ff`: S, saturation of `HLS`
`56`: the binary value `01010110`. Higher 5 bits indicate the gradient time=10 (unit: 200 ms). It represents the real time 10 × 200 ms = 2s. Lower 3 bits indicate the number of gradient groups=6 groups.
`00`, `55`, `AA`, `00`, `55`, and `AA`: H, hue of `HLS`, 6 groups
Based on the values of `L` and `S`, as well as `H` for each group, the RGB values of six groups are calculated.

0 c7 ed cc c8 37 64 00 e0

Start a scene and send `null` to query the values for the scene.

{set_scene1=null}

Switch to white: 109 = "white"
Switch to color: send the `rgb` command or `109 = "colour"`.

Switch to Scene 1: 109 = "scene_1"
Switch to Scene 2: 109 = "scene_2"
Switch to Scene 3: 109 = "scene_3"
...
Switch to Scene 8: 109 = "scene_8"

Set Scenes 1 to 8: sequentially send DPs 111 to 118.
For example, to set Scene 5: 115 = "0f19ec27f806400e0"
The format follows the previously mentioned DP format.