Getting Node ID

Each device has its unique identifier, namely the node ID. After the device is provisioned, it can be bound to the cloud server via its node ID by calling a binding request. The purpose of binding is to ensure subsequent remote control.

Getting Node ID in Android

📝 Source code

For the source code of getting node ID in Android, please refer to book-esp32c3-iot-projects/phone_app/app_android/app/src/main/java/com/espressif/ui/activites/ProvisionActivity.java.

To create the request for node ID, use:

EspRmakerUserMapping.CmdSetUserMapping deviceSecretRequest =
EspRmakerUser Mapping.CmdSetUserMapping.newBuilder()
                    .setUserID(ApiManager.userId)
                    .setSecretKey(secretKey)
                    .build();
EspRmakerUserMapping.RMakerConfigMsgType msgType = EspRmakerUserMapping.
                    RMakerConfigMsgType.TypeCmdSetUserMapping;
EspRmakerUserMapping.RMakerConfigPayload payload = EspRmakerUserMapping.
                    RMakerConfigPayload.newBuilder()
                    .setMsg(msgType)
                    .setCmdSetUserMapping(deviceSecretRequest)
                    .build();

To initiate the request, use:

private void associateDevice() {
    provisionManager.getEspDevice().sendDataToCustomEndPoint(AppConstants.HANDLER_RM_USER_MAPPING, 
                                                    payload.toByteArray(), new ResponseListener() {
        @Override
        public void onSuccess(byte[] returnData) {
            processDetails(returnData, secretKey);
        }
        @Override
        public void onFailure(Exception e) {
            //Code Omitted
        }
    });
}

To parse the device's response, use:

private void processDetails(byte[] responseData, String secretKey) {

    try {
        EspRmakerUserMapping.RMakerConfigPayload payload = EspRmakerUserMapping.
                                RMakerConfigPayload.parseFrom(responseData);
        EspRmakerUserMapping.RespSetUserMapping response = payload.getRespSetUserMapping();

        if (response.getStatus() == EspRmakerUserMapping.RMakerConfigStatus.Success) {
            //Node ID received. Ready for device provisioning.
            receivedNodeId = response.getNodeId();
        }
    } catch (InvalidProtocolBufferException e) {
        //Code Omitted
    }
}

Getting Node ID in iOS

📝 Source code

For the source code of getting node ID in iOS, please refer to book-esp32c3-iot-projects/phone_app/app_ios/ESPRainMaker/ESPRainMaker/AWSCognito/DeviceAssociation.swift.

private func createAssociationConfigRequest() throws -> Data? {
    var configRequest = Rainmaker_CmdSetUserMapping()
    configRequest.secretKey = secretKey
    configRequest.userID = User.shared.userInfo.userID
    var payload = Rainmaker_RMakerConfigPayload()
    payload.msg = Rainmaker_RMakerConfigMsgType.typeCmdSetUserMapping
    payload.cmdSetUserMapping = configRequest
    return try payload.serializedData()
}

To initiate the request, use:

func associateDeviceWithUser() {
    do {
        let payloadData = try createAssociationConfigRequest()
        if let data = payloadData {
            device.sendData(path: Constants.associationPath, data: data){ response, error in
                guard error == nil, response ! = nil else {
                    self.delegate?.deviceAssociationFinishedWith(success: false, nodeID: nil,
                            error: AssociationError.runtimeError(error!.localizedDescription))
                    return
                }
                self.processResponse(responseData: response!)
            }
        } else {
            delegate?.deviceAssociationFinishedWith(success: false, nodeID: nil, 
                error: AssociationError.runtimeError("Unable to fetch request payload."))
        }
    } catch {
        delegate?.deviceAssociationFinishedWith(success: false, nodeID: nil,
            error: AssociationError.runtimeError("Unable to fetch request payload."))
    }
}

To parse the device's response, use:

func processResponse(responseData: Data) {
    do {
        let response = try Rainmaker_RMakerConfigPayload(serializedData: response Data)
        if response.respSetUserMapping.status == .success {
            //Node ID received. Ready for device provisioning.
            delegate?.deviceAssociationFinishedWith(success: true, nodeID: response.respSetUserMapping.nodeID, error: nil)
        } else {
            delegate?.deviceAssociationFinishedWith(success: false, nodeID: nil, 
                error: AssociationError.runtimeError("User node mapping failed."))
        }
    } catch {
        delegate?.deviceAssociationFinishedWith(success: false, nodeID: nil,
                            error: AssociationError.runtimeError(error.localizedDescription))
    }
}