跳到主要内容

设备管理

更新时间:2025-04-22 14:25:13

包括设备绑定,设备解绑,设备列表

// 导入设备管理SDK头文件
#import <RTCXDeviceCenter/RTCXDeviceCenter.h>

设备绑定

总体介绍参考设备绑定开发指南

  • 设备绑定流程
  1. App调用prepareAddDevice方法后,当监听到RTCXDeviceAddStatus_Prepared状态时可获取bindToken (有效时长30分钟)。
  2. 将bindToken传递给设备(二维码、蓝牙等),设备保证网络连通情况下,通过DeviceSDK进行设备绑定
  3. 在RTCXDeviceAddStatus_Prepared状态下,App只需要调用startAddDevice方法实时监听绑定状态回调即可(超时自行控制,最大超时依赖bindToken的有效时长)。
注意
  1. startAddDevice方法需要等添加状态为RTCXDeviceAddStatus_Prepared时才可以调用,所以可以在- (void)deviceAddListener:(RTCXDeviceAddStatus)status callbackData:(nullable id)data error:(nullable NSError *)error回调状态为RTCXDeviceAddStatus_Prepared调用开始添加方法
  2. 设备绑定详细流程说明请点击
@protocol RTCXDeviceAddProtocol <NSObject>

#pragma mark - 设备添加步骤 -
/**
* 准备添加设备,成功才可以进行下一步
*
* **@param addType 添加类型
*/
- (void)prepareAddDevice:(RTCXDeviceAddType)addType;
/**
* 开始添加设备,成功才可以进行下一步
*
* @param req 配网模式对应入参
*/
- (void)startAddDevice:(nullable RTCXDeviceAddReq *)req;
/**
* 停止添加设备
*
*/
- (void)stopAddDevice;

@end
  • 获取设备配网bindToken
@protocol RTCXDeviceAddProtocol <NSObject>
/**
* 获取配网所需随机数(需要RTCXDeviceAddStatus_Prepared状态才能获取到)
*/
- (nullable NSString *)getBindToken
@end
  • 通过注册监听对象,实现设备绑定过程状态回调实时监听
注意
  1. 需要prepareAddDevice:方法之前注册监听
/**
* 注册设备添加状态回调代理对象
*
* @param delegate 代理对象
*/
- (void)registerDelegate:(id<RTCXDeviceAddDelegate>_Nullable)delegate;
// 配网过程中的状态
typedef NS_ENUM(NSUInteger, RTCXDeviceAddStatus) {
/// 就绪,可以发起添加
RTCXDeviceAddStatus_Prepared = 1,
/// 成功 回调新添加的设备信息Model
RTCXDeviceAddStatus_Success,
/// 失败 错误信息见代理回调方法deviceAddListener中返回的error
RTCXDeviceAddStatus_Failed,
};

@protocol RTCXDeviceAddDelegate <NSObject>

// 设备添加状态代理回调方法,回调过程中状态、数据、错误信息
- (void)deviceAddListener:(RTCXDeviceAddStatus)status callbackData:(nullable id)data error:(nullable NSError *)error;

@end
  • 通过二维码绑定方式,生成带有 WiFi 名和密码的二维码内容
/**
* 生成二维码字符串数组
*
* @param req RTCXDeviceAddQRReq
*/
- (nullable NSArray <NSString *> *)getQRCodeData:(nullable RTCXDeviceAddQRReq *)req;
  • 使用 RTCXDeviceSDK 单例宏对象调用示例如下:
// 注册绑定状态监听
[RTCXDeviceService(RTCXDeviceAddProtocol) registerDelegate:self];
// 二维码方式绑定设备
[RTCXDeviceService(RTCXDeviceAddProtocol) prepareAddDevice:RTCXDeviceAddType_QR];
// 获取二维码内容
RTCXDeviceAddQRReq *req = [[RTCXDeviceAddQRReq alloc] init];
req.ssid = ssidName;
req.wifiPwd = password;
NSArray *qrCodeStrings = [RTCXDeviceService(RTCXDeviceAddProtocol) getQRCodeData:req];
// 开始绑定设备,需要在RTCXDeviceAddStatus_Prepared状态时调用
RTCXDeviceAddQRReq *qrReq = [[RTCXDeviceAddQRReq alloc] init];
qrReq.productKey = self.productKeyTextField.text;
qrReq.deviceName = self.deviceNameTextField.text;
[RTCXDeviceService(RTCXDeviceAddProtocol) startAddDevice:qrReq];
// 结束绑定设备
[RTCXDeviceService(RTCXDeviceAddProtocol) stopAddDevice];
// 监听绑定状态
#pragma mark -- RTCXDeviceAddDelegate --
- (void)deviceAddListener:(RTCXDeviceAddStatus)status callbackData:(nullable id)data error:(nullable NSError *)error {
COMMON_PRINTF(@"device add status: %d, %@, %@",status,data,error);
if (status == RTCXDeviceAddStatus_Prepared) {
COMMON_PRINTF(@"device add prepared: %d, %@, %@",status,data,error);
NSString *bindToken = [RTCXDeviceService(RTCXDeviceAddProtocol) getBindToken];
COMMON_PRINTF(@"bindToken: %@",bindToken);
// 此状态下才可以调用startAddDevice
RTCXDeviceAddReq *req = [[RTCXDeviceAddReq alloc] init];
[RTCXDeviceService(RTCXDeviceAddProtocol) startAddDevice:req];
} else if (status == RTCXDeviceAddStatus_Success) {
[self.navigationController.viewControllers enumerateObjectsUsingBlock:^(__kindof UIViewController * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj isKindOfClass:NSClassFromString(@"DeviceListViewController")]) {
[self.navigationController popToViewController:obj animated:YES];
}
}];
} else if (status == RTCXDeviceAddStatus_Failed) {
[self stopLoading];
[self showToast:@"添加设备失败"];
}
}

设备解绑

@protocol RTCXDeviceMgrProtocol <NSObject>
/**
* 解绑用户的设备
*
* @param req 请求参数对象
* @param onSuccess 成功回调
* @param onError 失败回调
*/
- (void)deviceUnbindWithReq:(nonnull RTCXDeviceUnbindReq *)req onSuccess:(nullable RTCXDeviceMgrOnSuccess)onSuccess onError:(nullable RTCXDeviceMgrOnError)onError;

@end

使用 RTCXDeviceSDK 单例宏对象调用示例如下:

RTCXDeviceUnbindReq *req = [[RTCXDeviceUnbindReq alloc] init];
req.iotId = cameraDevice.iotId;
[RTCXDeviceService(RTCXDeviceMgrProtocol) deviceUnbindWithReq:req onSuccess:^(id _Nullable data, id _Nullable rawData) {
[weakSelf showToast:@"设备解绑成功"];
[weakSelf onGetDeviceListButtonClicked:nil];
} onError:^(NSError * _Nullable error) {
[weakSelf showToast:@"设备解绑失败"];
}];

设备列表

@protocol RTCXDeviceMgrProtocol <NSObject>
/**
* 获取设备列表
*
* @param req 请求参数对象
* @param onSuccess 成功回调
* @param onError 失败回调
*/
- (void)getDeviceListWithReq:(nonnull RTCXQueryDeviceListReq *)req onSuccess:(nullable RTCXDeviceMgrOnSuccess)onSuccess onError:(nullable RTCXDeviceMgrOnError)onError;
/**
* 获取网关的子设备列表
*
* @param req 请求参数对象
* @param onSuccess 成功回调
* @param onError 失败回调
*/
- (void)getSubDeviceListWithReq:(nonnull RTCXQuerySubDeviceListReq *)req onSuccess:(nullable RTCXDeviceMgrOnSuccess)onSuccess onError:(nullable RTCXDeviceMgrOnError)onError;
@end

使用 RTCXDeviceSDK 单例宏对象调用示例如下:

RTCXQueryDeviceListReq *req = [[RTCXQueryDeviceListReq alloc] init];
req.pageNo = 1;
req.pageSize = 10;
[RTCXDeviceService(RTCXDeviceMgrProtocol) getDeviceListWithReq:req onSuccess:^(id _Nullable data, id _Nullable rawData) {
[weakSelf stopLoading];
weakSelf.devicelist = [NSMutableArray arrayWithArray:((RTCXDeviceInfoList *)data).data];
[weakSelf.tableView reloadData];
} onError:^(NSError * _Nullable error) {
[weakSelf stopLoading];
[weakSelf showToast:@"获取列表失败"];
}];
  • 网关子设备列表调用示例
RTCXQuerySubDeviceListReq *req = [[RTCXQuerySubDeviceListReq alloc] init];
req.iotId = self.gatewayInfo.iotId;
req.pageNo = 1;
req.pageSize = 100;
[RTCXDeviceService(RTCXDeviceMgrProtocol) getSubDeviceListWithReq:req onSuccess:^(id _Nullable data, id _Nullable rawData) {
[weakSelf getDeviceListSuccessHandle:data];
} onError:^(NSError * _Nullable error) {
[weakSelf getDeviceListFailHandle:error];
}];

修改设备昵称

@protocol RTCXDeviceMgrProtocol <NSObject>
/**
* 设置设备昵称
*
* @param req 请求参数对象
* @param onSuccess 成功回调
* @param *onError 失败回调
*/
- (void)setDeviceNickNameWithReq:(nonnull RTCXDeviceNickdNameSetReq *)req onSuccess:(nullable RTCXDeviceMgrOnSuccess)onSuccess onError:(nullable RTCXDeviceMgrOnError)onError;
@end

使用 RTCXDeviceSDK 单例宏对象调用示例如下:

RTCXDeviceNickdNameSetReq *req = [[RTCXDeviceNickdNameSetReq alloc] init];
req.iotId = self.device.iotId;
req.nickName = text;
[RTCXDeviceService(RTCXDeviceMgrProtocol) setDeviceNickNameWithReq:req onSuccess:^(id _Nullable data, id _Nullable rawData) {
self.device.nickName = text;
[self showToast:@"设置昵称成功"];
[self queryProperties];
} onError:^(NSError * _Nullable error) {
[self showToast:@"设置昵称失败"];
}];

设备缩略图

使用物模型获取设备缩略图

@protocol RTCXThingActions <NSObject>
/**
调用物提供的服务

@param serviceIdentifier 服务的唯一标识符
@param params 调用服务的入参,请参考物的模型 tsl,形如 {"arg1":"val1", "arg2":"val2"}
@param extraData 附加控制属性
key:@"IotPerformanceId" 性能测试
key:@"callType" "async":异步, "sync"同步调用
key:@"Channel", value: ChannelPolicyCloud ChannelPolicyLocal ChannelPolicyLocalPrefer
key:@"QosLevel", value: Qos_CON Qos_NON
key:@"NeedRsp", value: value:TRUE FALSE

@param handler 结果回调函数
*/
- (void)invokeServiceV1:(NSString * _Nonnull)serviceIdentifier
params:(NSDictionary* _Nullable)params
extraData:(NSDictionary* _Nullable)extraData
responseHandler:(RTCXThingActionsResponseHandler _Nullable)handler;
@end

使用 kRTCXThingManager 单例宏对象调用示例如下:

- (NSString *)queryThumnail:(NSString *)iotId {
NSString *picUrl = [self.thumnailDic valueForKey:iotId];
// if (!picUrl) {
if ([[kRTCXThingManager buildThing:iotId] getThingProfile]) {
[[[kRTCXThingManager buildThing:iotId] getThingActions] invokeServiceV1:@"GetDevPicture" params:@{@"definition":@(1),@"picType":@"jpg"} extraData:@{} responseHandler:^(RTCXThingActionsResponse * _Nullable response) {
if (response.success) {
NSString *picUrl = [response.dataObject valueForKey:@"downloadUrl"];
[self.thumnailDic setObject:picUrl forKey:iotId];

__block NSUInteger index = 0;
[self.devicelist enumerateObjectsUsingBlock:^(RTCXDeviceInfo *_Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj.iotId isEqualToString:iotId]) {
index = idx;
*stop = YES;
}
}];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
});
} else {
NSString *errorMsg = response.responseError.userInfo[NSLocalizedFailureReasonErrorKey];
// [self showToast:errorMsg];
}
}];
}
// }
return picUrl;
}

保存设备配置

@protocol RTCXDeviceMgrProtocol <NSObject>
/**
* 保存设备配置
*
* @param req 请求参数对象
* @param onSuccess 成功回调
* @param onError 失败回调
*/
- (void)setDeviceConfigWithReq:(nonnull RTCXSetDeviceConfigReq *)req onSuccess:(nullable RTCXDeviceMgrOnSuccess)onSuccess onError:(nullable RTCXDeviceMgrOnError)onError;
@end

使用 RTCXDeviceSDK 单例宏对象调用示例如下:

RTCXSetDeviceConfigReq *configReq = [[RTCXSetDeviceConfigReq alloc] init];
configReq.iotId = device.iotId;
configReq.attributeList = @[@{@"id":@1004,@"value":[rsp iotyy_modelToJSONString]}];
[RTCXDeviceService(RTCXDeviceMgrProtocol) setDeviceConfigWithReq:req onSuccess:^(id _Nullable data, id _Nullable rawData) {
RTCXDeviceConfigRsp *rsp = data;
} onError:^(NSError * _Nullable error) {
[weakSelf showToast:@"获取设备配置失败"];
}];

获取设备配置

@protocol RTCXDeviceMgrProtocol <NSObject>
/**
* 获取设备配置
*
* @param req 请求参数对象
* @param onSuccess 成功回调
* @param onError 失败回调
*/
- (void)getDeviceConfigWithReq:(nonnull RTCXDeviceConfigReq *)req onSuccess:(nullable RTCXDeviceMgrOnSuccess)onSuccess onError:(nullable RTCXDeviceMgrOnError)onError;
@end

使用 RTCXDeviceSDK 单例宏对象调用示例如下:

RTCXDeviceConfigReq *req = [[RTCXDeviceConfigReq alloc] init];
req.iotId = cameraDevice.iotId;
req.attributeIdList = @[@(1000)];// 例如 1000:直播策略
[RTCXDeviceService(RTCXDeviceMgrProtocol) getDeviceConfigWithReq:req onSuccess:^(id _Nullable data, id _Nullable rawData) {
RTCXDeviceConfigRsp *rsp = data;
} onError:^(NSError * _Nullable error) {
[weakSelf showToast:@"获取获取设备配置失败"];
}];

设备预置位

@protocol RTCXDeviceMgrProtocol <NSObject>
/**
* 保存预置位
*
* @param req 请求参数对象
* @param onSuccess 成功回调
* @param onError 失败回调
*/
- (void)savePtzPresetPositionWithReq:(nonnull RTCXSavePtzPresetPositionReq *)req onSuccess:(nullable RTCXDeviceMgrOnSuccess)onSuccess onError:(nullable RTCXDeviceMgrOnError)onError;
/**
* 获取预置位列表
*
* @param req 请求参数对象
* @param onSuccess 成功回调
* @param onError 失败回调
*/
- (void)getPtzPresetPositionListWithReq:(nonnull RTCXGetPtzPresetPositionListReq *)req onSuccess:(nullable RTCXDeviceMgrOnSuccess)onSuccess onError:(nullable RTCXDeviceMgrOnError)onError;
/**
* 删除预置位
*
* @param req 请求参数对象
* @param onSuccess 成功回调
* @param onError 失败回调
*/
- (void)deletePtzPresetPositionWithReq:(nonnull RTCXDeletePtzPresetPositionReq *)req onSuccess:(nullable RTCXDeviceMgrOnSuccess)onSuccess onError:(nullable RTCXDeviceMgrOnError)onError;
/**
* 更新预置位名称
*
* @param req 请求参数对象
* @param onSuccess 成功回调
* @param onError 失败回调
*/
- (void)updatePtzPresetPositionWithReq:(nonnull RTCXUpdatePtzPresetPositionReq *)req onSuccess:(nullable RTCXDeviceMgrOnSuccess)onSuccess onError:(nullable RTCXDeviceMgrOnError)onError;
@end

使用 RTCXDeviceSDK 单例宏对象调用示例如下:

  • 新增预置位
RTCXSavePtzPresetPositionReq *req = [[RTCXSavePtzPresetPositionReq alloc] init];
req.iotId = weakSelf.curDevice.iotId;
req.name = name;
req.ptz = [positionDic[@"Position"] iotyy_modelToJSONString];
req.imageData = UIImagePNGRepresentation(screenshotImage);
[RTCXDeviceService(RTCXDeviceMgrProtocol) savePtzPresetPositionWithReq:req onSuccess:^(id _Nullable data, id _Nullable rawData) {
[CURRENT_VIEW_CONTROLLER() hideLoadingView];
[weakSelf queryPresetPositionList];
} onError:^(NSError * _Nullable error) {
[CURRENT_VIEW_CONTROLLER() hideLoadingView];
}];
  • 删除预置位
RTCXDeletePtzPresetPositionReq *req = [[RTCXDeletePtzPresetPositionReq alloc] init];
req.iotId = weakSelf.curDevice.iotId;
req.picId = model.picId;
[RTCXDeviceService(RTCXDeviceMgrProtocol) deletePtzPresetPositionWithReq:req onSuccess:^(id _Nullable data, id _Nullable rawData) {
[weakSelf queryPresetPositionList];
} onError:^(NSError * _Nullable error) {
}];
  • 修改预置位名称
RTCXUpdatePtzPresetPositionReq *req = [[RTCXUpdatePtzPresetPositionReq alloc] init];
req.iotId = weakSelf.curDevice.iotId;
req.picId = model.picId;
req.name = name;
[RTCXDeviceService(RTCXDeviceMgrProtocol) updatePtzPresetPositionWithReq:req onSuccess:^(id _Nullable data, id _Nullable rawData) {
[weakSelf queryPresetPositionList];
} onError:^(NSError * _Nullable error) {
}];
  • 获取预置位列表
RTCXGetPtzPresetPositionListReq *req = [[RTCXGetPtzPresetPositionListReq alloc] init];
req.iotId = self.curDevice.iotId;
[RTCXDeviceService(RTCXDeviceMgrProtocol) getPtzPresetPositionListWithReq:req onSuccess:^(id _Nullable data, id _Nullable rawData) {
RTCXGetPtzPresetPositionListRsp *rsp = data;
[rsp.presetPositionList enumerateObjectsUsingBlock:^(RTCXGetPtzPresetPositionInfoRsp *_Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
PresetPositionModel *model = [[PresetPositionModel alloc] init];
model.iotId = self.curDevice.iotId;
model.presetPositionDic = [obj.ptz xs_jsonToDic];
model.picId = obj.picId;
model.name = obj.name;
model.url = obj.url;
[self.dataArray addObject:model];
}];
[self.collectionView reloadData];
} onError:^(NSError * _Nullable error) {
}];

获取设备额外信息

基于上层App不调用RTCXSDK的设备列表接口,而是使用他们自己平台的设备列表,导致在调用RTCX播放器时,缺失了部分播放必要设备信息字段(如:播放策略、设备属性、当前套餐等)

所以需要App在获获取到他们自己设备列表成功后,触发RTCX的设备额外信息接口,帮助播放器提前获取部分播放必要字段,App只需要触发该接口即可,不需要任何其他操作。

如果App不触发,在播放的时候,播放器内部也会主动触发该接口,可能影响播放响应速度

@protocol RTCXDeviceExtraInfoProtocol <NSObject>
/**
* 请求设备额外信息(App未调用设备列表接口时需要调用此接口,获取设备播放需要的必要信息)
*
* @param req 请求参数对象, 设备iotId数组 eg:【xxx】
* @param onSuccess 成功回调
* @param onError 失败回调
*/
- (void)queryExtraInfoWithIotIds:(nonnull RTCXDeviceExtraInfoReq *)req onSuccess:(nullable RTCXDeviceExtraInfoMgrOnSuccess)onSuccess onError:(nullable RTCXDeviceExtraInfoMgrOnError)onError;
@end

使用 RTCXDeviceSDK 单例宏对象调用示例如下:

RTCXDeviceExtraInfoReq *req = [[RTCXDeviceExtraInfoReq alloc] init];
req.iotIds = @[cameraDevice.iotId];
[RTCXDeviceService(RTCXDeviceExtraInfoProtocol) queryExtraInfoWithIotIds:req onSuccess:^(id _Nullable data, id _Nullable rawData) {
NSArray *array = data;
} onError:^(NSError * _Nullable error) {
}];

低功耗设备唤醒

@protocol RTCXDeviceMgrProtocol <NSObject>
/**
* 休眠设备唤醒
*
* @param req 请求参数对象
* @param onSuccess 成功回调
* @param onError 失败回调
*/
- (void)wakeupDeviceWithReq:(nonnull RTCXWakeupDeviceReq *)req onSuccess:(nullable RTCXDeviceMgrOnSuccess)onSuccess onError:(nullable RTCXDeviceMgrOnError)onError;
@end

使用 RTCXDeviceSDK 单例宏对象调用示例如下:

// 低功耗设备需要先唤醒,再播放
RTCXWakeupDeviceReq *req = [[RTCXWakeupDeviceReq alloc] init];
req.iotId = self.curDevice.iotId;
[RTCXDeviceService(RTCXDeviceMgrProtocol) wakeupDeviceWithReq:req onSuccess:^(id _Nullable data, id _Nullable rawData) {
[self playerStart];// 唤醒之后直播
} onError:^(NSError * _Nullable error) {
[self showToast:[NSString stringWithFormat:@"%ld : %@",error.code,error.userInfo[NSLocalizedFailureReasonErrorKey]]];
}];