You can use the sub-device management feature when you connect sub-devices of a gateway to IoT Platform.

Perform dynamic registration

This feature allows you to dynamically register sub-devices, query sub-devices of a gateway, add and remove sub-devices, connect sub-devices, and disconnect sub-devices. You can also listen to messages about disabling and removing sub-devices, and manage communication between sub-devices and IoT Platform.

A gateway is a directly connected device. For more information about how to develop a gateway, see the following topics: Authentication and connection, and MQTT topic-based communication. To manage sub-devices of a gateway, you must connect the gateway to IoT Platform.

During dynamic registration, you request the DeviceSecret of a sub-device from IoT Platform by using the ProductKey and DeviceName. After you obtain the DeviceSecret, you must persist it on the gateway. This way, the DeviceSecret of the sub-device cannot be lost even if the gateway is reset.

The sub-device manufacturer must enable the dynamic registration feature in IoT Platform, and upload a DeviceName to IoT Platform.

Sample code:

    self.gatewayInterface = [[LinkKitEntry sharedKit] gatewayInterface];

    NSMutableArray * subBases = @[].mutableCopy;
    for (NSDictionary * subinfo in _subDevices) {
        LinkkitDeviceBase * base = [[LinkkitDeviceBase alloc] init];
        base.productKey = [subinfo valueForKey:@"productKey"];
        base.deviceName = [subinfo valueForKey:@"deviceName"];
        [subBases addObject:base];
    }
    [self.gatewayInterface subDeviceRegisterBatch:subBases
                                      resultBlock:^(NSArray * _Nullable result, NSError * _Nullable error) {
                                          LinkkitLogDebug(@"subDeviceRegisterBatch error : %@", error);
                                          self.subDevicesReg = result;
                                          LinkkitDeviceAuth * authSub = result[0];
/// The LinkkitDeviceAuth class contains the DeviceSecret. We recommend that you persist the DeviceSecret. When the sub-device goes online again, you must use the saved ProductKey, DeviceName, and DeviceSecret for authentication.
                                          dispatch_async(dispatch_get_main_queue(), ^{
                                              [self ims_showHUDWithMessage:[NSString stringWithFormat:@ "The number of registered sub-devices: %@",
                                                                            (int)self.subDevicesReg.count]];
                                          });
    }];
        

Add sub-devices to a gateway

Adding a sub-device indicates establishing a topological relationship between the sub-device and the gateway on premises and in IoT Platform. A topological relationship must be established before the gateway can be used as a proxy of the sub-device to send upstream and downstream data. After a sub-device is added, the topological relationship remains until you remove the sub-device.

You can use the following methods to add a sub-device:

  • Obtain the ProductKey, DeviceName, and DeviceSecret of the sub-device by using dynamic registration. Sample code:
       __weak typeof (self) weakSelf = self;
       LinkkitDeviceAuth * authSub = self.subDevicesReg[0];
        [self.gatewayInterface addSubDevice:authSub
                                   delegate:self
                                resultBlock:^(id<ILKSubDeviceChannel>  _Nonnull subChannel, NSError * _Nullable error) {
                                    LinkkitLogDebug(@"subDevice logout add to gateway : %@", error);
                                    weakSelf.subChannel = subChannel;
                                    dispatch_async(dispatch_get_main_queue(), ^{
                                        weakSelf.lableSubState.text = @ "Associated with the gateway";
                                        [weakSelf ims_showHUDWithMessage:[NSString stringWithFormat:@ "Add the sub-device to the gateway :%@", error? @ "Failure":@ "Success"]];
                                    });
        }];
                        
  • Use the ProductKey, DeviceName, and DeviceSecret that is burned to the sub-device. In this scenario, you do not need to perform dynamic registration. Sample code:
    
    
        __weak typeof (self) weakSelf = self;
        LinkkitDeviceBase * devBase = [[LinkkitDeviceBase alloc] init];
        devBase.productKey = @"sub device productKey";
        devBase.deviceName = @"sub device deviceName";
    
        [self.gatewayInterface addSubDevice:devBase signer:self
                                   delegate:self resultBlock:^(id<ILKSubDeviceChannel>  _Nullable subChannel, NSError * _Nullable error) {
    
                                       LinkkitLogDebug(@"subDevice logout add to gateway : %@", error);
                                       weakSelf.subChannel = subChannel;
                                       dispatch_async(dispatch_get_main_queue(), ^{
                                           weakSelf.lableSubState.text = @ "Associated with the gateway";
                                           [weakSelf ims_showHUDWithMessage:[NSString stringWithFormat:@ "Add the sub-device to the gateway :%@", error? @ "Failure":@ "Success"]];
                                       });
                                   }];
    
    // For more information about how to configure a signer, see protocol ILKSubDeviceSigner in the LinkkitGateway.h header file.
                        

Remove sub-devices from a gateway

Removing a sub-device indicates deleting the topological relationship between the sub-device and the gateway.

    __weak typeof (self) weakSelf = self;

    LinkkitDeviceBase * devBase = [[LinkkitDeviceBase alloc] init];
    devBase.productKey = @"sub device productKey";
    devBase.deviceName = @"sub device deviceName";

    [self.gatewayInterface deleteSubDevice:devBase
                               resultBlock:^(BOOL succeeded, NSError * _Nullable error) {
                                   LinkkitLogDebug(@"subDevice delete from gateway error : %@", error);
                                   weakSelf.subChannel = nil;
                                   dispatch_async(dispatch_get_main_queue(), ^{
                                       weakSelf.lableSubState.text = @ "Unassociated with the gateway";
                                       [weakSelf ims_showHUDWithMessage:[NSString stringWithFormat:@ "Remove the sub-device from the gateway :%@", error? @ "Failure":@ "Success"]];
                                   });
    }];
            

Connect sub-devices to IoT Platform

You can use a gateway to connect a sub-device to IoT Platform. You can subscribe to topics and publish messages to topics only after the sub-device is connected to IoT Platform.




    __weak typeof (self) weakSelf = self;
    [self.subChannel login:^(BOOL succeeded, NSError * _Nullable error) {
        LinkkitLogDebug(@"subDevice login error : %@", error);
        dispatch_async(dispatch_get_main_queue(), ^{
            weakSelf.lableSubState.text = @ "The sub-device is online";
            [weakSelf ims_showHUDWithMessage:[NSString stringWithFormat:@ "Connect the sub-device to IoT Platform :%@", error? @ "Failure":@ "Success"]];
        });
    }];
            

Disconnect sub-devices from IoT Platform

After a sub-device is disconnected, you cannot subscribe to topics, publish messages to topics, or unsubscribe from topics.

    __weak typeof (self) weakSelf = self;
    [self.subChannel logout:^(BOOL succeeded, NSError * _Nullable error) {
        LinkkitLogDebug(@"subDevice logout error : %@", error);
        dispatch_async(dispatch_get_main_queue(), ^{
            weakSelf.lableSubState.text = @ "The sub-device is offline";
            [weakSelf ims_showHUDWithMessage:[NSString stringWithFormat:@ "Disconnect the sub-device from IoT Platform :%@", error? @ "Failure":@ "Success"]];
        });
    }];
            

Listen to messages about disabling and removing sub-devices

You can use a gateway to enable and disable sub-devices, and remove sub-devices from the on-premises topology of the gateway. IoT Platform can send only the downstream messages about disabling sub-devices. When you disable a sub-device, the sub-device is disconnected from IoT Platform. Then, the gateway cannot be used a proxy of the sub-device to communicate with IoT Platform. You can set a stateListener to listen to messages about disabling and removing sub-devices.




    self.subChannel.stateListener = self;
            

Forward upstream and downstream data

You can use a gateway to forward upstream data to IoT Platform and downstream data to sub-devices.

The following sample code can be used to forward upstream data:

- (IBAction)onClickUpload:(id)sender {


    if (self.subChannel == nil) {
        [self ims_showHUDWithMessage:@ "Add the sub-device and connect it to IoT Platform"];
        return;
    }
    __weak typeof (self) weakSelf = self;

    NSString * topic = self.textFieldPubTopic.text;
    NSData * upData = [self.textViewPubContent.text dataUsingEncoding:NSUTF8StringEncoding];
    int qos = [self.textFieldQos.text intValue];
    [self.subChannel publish:topic data:upData qos:qos
                resultBlock:^(BOOL succeeded, NSError * _Nullable error) {
                    LinkkitLogDebug(@"subDevice upload error : %@", error);
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [weakSelf ims_showHUDWithMessage:[NSString stringWithFormat:@ "Forward upstream data to IoT Platform :%@", error? @ "Failure":@ "Success"]];
                    });
    }];
}
            

Note: 1. You can set the quality of service (QoS) level to only 0 or 1. You cannot set the QoS level to 2.

To receive downstream data, you must subscribe to topics. The following sample code can be used:

- (IBAction)onClickSubscribe:(id)sender {

    if (self.subChannel == nil) {
        [self ims_showHUDWithMessage:@ "Add the sub-device and connect it to IoT Platform"];
        return;
    }

    __weak typeof (self) weakSelf = self;

    NSString * topic = self.textFieldSubTopic.text;
    [self.subChannel subscribe:topic
                   resultBlock:^(BOOL succeeded, NSError * _Nullable error) {
                       LinkkitLogDebug(@"subDevice subscribe error : %@", error);
                       dispatch_async(dispatch_get_main_queue(), ^{
                           [weakSelf ims_showHUDWithMessage:[NSString stringWithFormat:@ "Subscribe to a topic:%@", error? @ "Failure":@ "Success"]];
                       });
    }];
}
            

When you add a sub-device to the gateway, you must import the ILKSubDeviceDelegate instance. The following sample code can be used:

/// Listen to the status of the connection between the sub-device and IoT Platform.
- (void)onConnectResult:(BOOL)success
                  error:(NSError * _Nullable)err
       subDeviceChannel:(nonnull id<ILKSubDeviceChannel>)subDeviceChannel {
    if ([self.subChannel.subDeviceProfile.deviceBaseId
         isEqualToString:subDeviceChannel.subDeviceProfile.deviceBaseId]) {

        //__weak typeof (self) weakSelf = self;
        dispatch_async(dispatch_get_main_queue(), ^{

        });
    } else {

    }
}

/// Listen to downstream messages.
- (void)onDataPush:(nonnull NSString *)topic data:(nonnull NSData *)data {
    NSString * downData = [NSString stringWithFormat:@ "The downstream message is received, topic :%@ \r\n", topic];
    downData = [downData stringByAppendingString:[NSString stringWithFormat:@ "\r \ndata :%@", data]];

    LinkkitLogDebug(@"subDevice recv topic : %@", topic);
    dispatch_async(dispatch_get_main_queue(), ^{
        self.textViewDownData.text = downData;
    });
}
            

You can unsubscribe from a topic to block messages that have been received. The following code can be used:




- (IBAction)onClickUnsubscribe:(id)sender {
    if (self.subChannel == nil) {
        [self ims_showHUDWithMessage:@ "Add the sub-device and connect it to IoT Platform"];
        return;
    }

    __weak typeof (self) weakSelf = self;

    NSString * topic = self.textFieldSubTopic.text;
    [self.subChannel unsubscribe:topic
                   resultBlock:^(BOOL succeeded, NSError * _Nullable error) {
                       LinkkitLogDebug(@"subDevice unsubscribe error : %@", error);
                       dispatch_async(dispatch_get_main_queue(), ^{
                           [weakSelf ims_showHUDWithMessage:[NSString stringWithFormat:@ "Unsubscribe from a topic:%@", error? @ "Failure":@ "Success"]];
                       });
                   }];
}