设备管理
包括设备绑定,设备解绑,设备列表
// 导入头文件
import 'package:airtc_engine/src/device_center/rtcx_add_device.dart';
import 'package:airtc_engine/src/device_center/rtcx_add_device_controller.dart';
import 'package:airtc_engine/src/device_center/rtcx_device.dart';
设备绑定
设备绑定方式提供二维码、蓝牙配网绑定、4G绑定、AP配网绑定方式
总体介绍参考设备绑定开发指南。
- 设备绑定流程
- App调用prepareAddDevice方法后,当监听到RTCXFluDeviceAddStatus_Prepared状态时可获取bindToken (有效时长30分钟)。
- 将bindToken传递给设备(二维码、蓝牙等),设备保证网络连通情况下,通过DeviceSDK进行设备绑定
- 在RTCXFluDeviceAddStatus_Prepared状态下,App只需要调用startAddDevice方法实时监听绑定状态回调即可(超时自行控制,最大超时依赖bindToken的有效时长)。
class RTCXFluAddDeviceApi {
/// 添加设备
/// 准备添加设备,成功才可以进行下一步
void prepareAddDevice(RTCXFluDeviceAddType deviceAddType);
/// 添加事件回调
void onDeviceAddListener();
/// 开始添加设备,成功才可以进行下一步
void startAddDevice(RTCXFluDeviceAddReq req);
/// 开始添加设备, 有线方式
void startAddWRDevice(RTCXFluDeviceAddWRReq req);
/// 开始添加设备, 二维码方式
void startAddQRDevice(RTCXFluDeviceAddQRReq req);
/// 开始添加设备, 4G方式
void startAdd4GDevice(RTCXFluDeviceAdd4GReq req);
/// 开始添加设备, 蓝牙绑定方式
void startAddBTDevice(RTCXFluDeviceAddBTReq req);
/// 开始添加设备, AP绑定方式
void startAddAPDevice(RTCXFluDeviceAddAPReq req);
/// 停止添加设备
void stopAddDevice();
/// 获取二维码内容
@async
List<String> getQRCodeData(RTCXFluDeviceAddQRReq req);
/// 获取蓝牙授权权限
@async
RTCXFluBTAuthorizeStatus getBluetoothAuthorizeStatus();
/// 开始扫描蓝牙设备
@async
List<RTCXFluBTLinkDevInfoRsp> startScanBTDevices(RTCXFluBTLinkScanReq req);
/// 停止扫描蓝牙设备
void stopScanBTDevices();
/// 连接蓝牙设备
@async
RTCXFluBTLinkResult connectLinkBTDevice(RTCXFluBTLinkNetworkingReq req);
/// 向蓝牙设备发送配网信息
@async
RTCXFluBTLinkResult sendNetworkingBTDevice(RTCXFluBTLinkNetworkingReq req);
/// 获取蓝牙设备扫描的WI-FI列表
@async
RTCXFluBTDeviceWifiListRsp getBTDeviceWifiList(
RTCXFluBTDeviceWifiListReq req);
/// 获取蓝牙设备的PK、DN信息
@async
RTCXFluBTGetDeviceInfoRsp getBTDeviceInfo(
RTCXFluBTGetDeviceInfoReq req);
/// AP开始连接
@async
RTCXFluAPLinkResult startAPLinkConnect(RTCXFluAPLinkConnectReq req);
/// AP发送配网信息
@async
RTCXFluAPLinkResult sendAPLinkNetworking(RTCXFluAPLinkNetworkingReq req);
}
- 需要prepareAddDevice:方法之前注册监听
二维码绑定
调用示例如下:
- 注册监听,并准备绑定
final addDeviceApi = RTCXFluAddDeviceController();
@override
void initState() {
super.initState();
addDeviceApi.onDeviceAddListener();
addDeviceApi.onDeviceAdd.listen((data) {
if (data.status ==
RTCXFluDeviceAddStatus.RTCXFluDeviceAddStatus_Success) {
Fluttertoast.showToast(msg: "绑定成功");
} else if (data.status ==
RTCXFluDeviceAddStatus.RTCXFluDeviceAddStatus_Prepared) {
Fluttertoast.showToast(msg: "已准备好添加设备");
debugPrint("error : ${data.error.code} -- ${data.error.message}");
} else {
Fluttertoast.showToast(
msg: "绑定结果:${data.status.name} + error:$data.error",
);
}
});
// 准备二维码绑定
addDeviceApi.prepareAddDevice(RTCXFluDeviceAddType.RTCXFluDeviceAddType_QR);
}
- 通过二维码绑定方式,生成带有 WiFi 名和密码的二维码内容
// 需要传递productKey、deviceName、ssid、wifiPwd
void getQRCodeData() async {
try {
final String productKey = "";
final String deviceName = "";
RTCXFluDeviceAddQRReq req = RTCXFluDeviceAddQRReq(productKey: productKey, deviceName: deviceName, ssid: "", wifiPwd: "");
addDeviceApi.getQRCodeData(req).then((List<String>? qrCodeStrings) {
if (qrCodeStrings!.isNotEmpty) {
setState(() {
qrcodeString = qrCodeStrings.first;
});
Fluttertoast.showToast(msg: 'qrcodeString:${qrcodeString}');
}
});
} catch (e) {
Fluttertoast.showToast(msg: '解析二维码失败: $e');
}
}
- 开始二维码绑定
void _startQRAddDevice() {
// 开始添加设备
addDeviceApi.startAddQRDevice(
RTCXFluDeviceAddQRReq(
productKey: "productKey",
deviceName: "deviceName",
),
);
}
- 结束绑定
// 在diapose中调用stopAddDevice与destroy方法
@override
void dispose() {
super.dispose();
addDeviceApi.stopAddDevice();
addDeviceApi.destroy();
}
有线绑定
设备已配有有线网络,通过有线方式进行绑定。 调用示例如下:
- 注册监听,并准备绑定
final addDeviceApi = RTCXFluAddDeviceController();
@override
void initState() {
super.initState();
addDeviceApi.onDeviceAddListener();
addDeviceApi.onDeviceAdd.listen((data) {
if (data.status ==
RTCXFluDeviceAddStatus.RTCXFluDeviceAddStatus_Success) {
Fluttertoast.showToast(msg: "绑定成功");
} else if (data.status ==
RTCXFluDeviceAddStatus.RTCXFluDeviceAddStatus_Prepared) {
Fluttertoast.showToast(msg: "已准备好添加设备");
debugPrint("error : ${data.error.code} -- ${data.error.message}");
} else {
Fluttertoast.showToast(
msg: "绑定结果:${data.status.name} + error:$data.error",
);
}
});
// 准备绑定
addDeviceApi.prepareAddDevice(RTCXFluDeviceAddType.RTCXFluDeviceAddType_WR);
_addDeviceByWR();
}
- 开始绑定
// 调用startAddWRDevice,等待绑定结果状态监听回调
void _addDeviceByWR() {
RTCXFluDeviceAddWRReq req = RTCXFluDeviceAddWRReq(productKey: '填写设备的productKey', deviceName: '填写设备的deviceName');
//请不要更改req的deviceAddType类型。
addDeviceApi.startAddWRDevice(req);
}
- 结束绑定
// 在diapose中调用stopAddDevice与destroy方法
@override
void dispose() {
super.dispose();
addDeviceApi.stopAddDevice();
addDeviceApi.destroy();
}
4G绑定
设备已配有4G网,通过4G绑定方式进行绑定。 调用示例如下:
- 注册监听,并准备绑定
final addDeviceApi = RTCXFluAddDeviceController();
@override
void initState() {
super.initState();
addDeviceApi.onDeviceAddListener();
addDeviceApi.onDeviceAdd.listen((data) {
if (data.status ==
RTCXFluDeviceAddStatus.RTCXFluDeviceAddStatus_Success) {
Fluttertoast.showToast(msg: "绑定成功");
} else if (data.status ==
RTCXFluDeviceAddStatus.RTCXFluDeviceAddStatus_Prepared) {
Fluttertoast.showToast(msg: "已准备好添加设备");
debugPrint("error : ${data.error.code} -- ${data.error.message}");
} else {
Fluttertoast.showToast(
msg: "绑定结果:${data.status.name} + error:$data.error",
);
}
});
// 准备4G绑定
addDeviceApi.prepareAddDevice(RTCXFluDeviceAddType.RTCXFluDeviceAddType_4G);
_addDeviceBy4G();
}
- 开始4G绑定
// 调用startAdd4GDevice,等待绑定结果状态监听回调
void _addDeviceBy4G() {
RTCXFluDeviceAdd4GReq req = RTCXFluDeviceAdd4GReq(productKey: '填写设备的productKey', deviceName: '填写设备的deviceName');
//请不要更改req的deviceAddType类型。
addDeviceApi.startAdd4GDevice(req);
}
- 结束绑定
// 在diapose中调用stopAddDevice与destroy方法
@override
void dispose() {
super.dispose();
addDeviceApi.stopAddDevice();
addDeviceApi.destroy();
}
蓝牙配网绑定
通过蓝牙配网方式,将WI-FI及WI-FI密码发给设备,进行绑定设备方式。 蓝牙绑定前需要配置权限,详细配置权限请见配置权限
扫描到蓝牙设备之后,选择蓝牙设备,首先连接蓝牙设备,连接成功后才可以获取蓝牙设备扫描的WI-FI列表与蓝牙设备的productKey、deviceName信息,最后通过调用startAddBTDevice与sendNetworkingBTDevice进行发送配网信息进行蓝牙设备绑定。
调用示例如下:
- 注册监听,并准备绑定
var addDeviceApi = RTCXFluAddDeviceController();
@override
void initState() {
super.initState();
addDeviceApi.onDeviceAddListener();
addDeviceApi.onDeviceAdd.listen((data) {
print("绑定结果:data: ${data.toString()}");
if (data.status ==
RTCXFluDeviceAddStatus.RTCXFluDeviceAddStatus_Success) {
Fluttertoast.showToast(msg: "绑定成功");
} else if (data.status ==
RTCXFluDeviceAddStatus.RTCXFluDeviceAddStatus_Prepared) {
Fluttertoast.showToast(msg: "已准备好添加设备");
debugPrint("error : ${data.error.code} -- ${data.error.message}");
} else {
Fluttertoast.showToast(
msg: "绑定结果:${data.status.name} + error:$data.error",
);
}
});
_prepare();
}
void _prepare() {
addDeviceApi.prepareAddDevice(RTCXFluDeviceAddType.RTCXFluDeviceAddType_BT);
}
- 获取蓝牙权限
void _getBluetoothAuthorizeStatus() {
addDeviceApi.getBluetoothAuthorizeStatus().then((RTCXFluBTAuthorizeStatus status) {
if (RTCXFluBTAuthorizeStatus.RTCXFluBTAuthorizeStatus_PoweredOn == status) {
_startScanDevices();
} else {
Fluttertoast.showToast(msg: '获取蓝牙权限status: $status');
}
}).catchError((error) {
Fluttertoast.showToast(msg: '获取蓝牙权限失败: $error');
});
}
- 获取蓝牙权限后,开始扫描设备
// 获取蓝牙权限后,开始扫描设备
void _startScanDevices() {
RTCXFluBTLinkScanReq req = RTCXFluBTLinkScanReq(
namePrefixs: ["XSDEV_", "XS_"],
);
addDeviceApi.startScanBTDevices(req, (ScanBTDevicesResult result) {
if (result.error != null) {
print('BT扫描设备失败: ${result.error?.message}');
Fluttertoast.showToast(msg: '扫描设备失败: ${result.error?.message}');
_stopScanBTDevices();
setState(() {
errorString = "扫描设备失败: ${result.error?.message}";
});
} else {
if (result.devices.isNotEmpty) {
List<RTCXFluBTLinkDevInfoRsp> deviceList = result;
} else {
print('BT未搜索到设备');
Fluttertoast.showToast(msg: '未搜索到设备');
}
}
})
// 停止扫描设备
void _stopScanBTDevices() {
addDeviceApi.stopScanBTDevices();
}
- 连接蓝牙设备
连接选择要绑定的设备,进行连接蓝牙设备。
Future<void> connectTheBTDevice() async {
RTCXFluBTLinkNetworkingReq req = RTCXFluBTLinkNetworkingReq(sn: '设备的SN');
addDeviceApi
.connectLinkBTDevice(req)
.then((RTCXFluBTLinkResult result) {
if (true == result.success) {
// 连接成功,可以调用获取信息
getBTWifiAndDeviceInfo();
} else {
Fluttertoast.showToast(msg: '连接设备失败');
}
})
.catchError((error) {
Fluttertoast.showToast(msg: '连接设备失败: $error');
});
}
- 获取WI-FI列表与设备信息productKey、deviceName
连接选择要绑定的设备,进行连接蓝牙设备。
Future<void> getBTWifiAndDeviceInfo() async {
// 获取设备扫描的 Wi-Fi 列表
await getBTDeviceWifiList();
// 获得后可进行展示
await getTheBTDeviceInfo();
/// 设备的productKey、deviceName信息
}
Future<void> getBTDeviceWifiInfoList() async {
try {
final rsp = await addDeviceApi.getBTDeviceWifiList(
RTCXFluBTDeviceWifiListReq(timeout: 20),
);
if(true == rsp.success) {
/// 获取的WI-FI列表rsp.wifiList
} else {
debugPrint('获取蓝牙设备 Wi-Fi 列表失败');
}
return;
} catch (e) {
debugPrint('获取蓝牙设备 Wi-Fi 列表异常: $e');
return;
}
}
Future<void> getTheBTDeviceInfo() async {
try {
final rsp = await addDeviceApi.getBTDeviceInfo(
RTCXFluBTGetDeviceInfoReq(timeout: 20),
);
if(true == rsp.success) {
///rsp.deviceInfo 获取设备的PK、DN信息
} else {
debugPrint('获取蓝牙设备的productKey、deviceName信息失败');
}
return;
} catch (e) {
debugPrint('获取蓝牙设备的productKey、deviceName信息异常: $e');
return;
}
}
- 开始添加设备并发送配网信息
Future<void> sendNetworkingToBTDevice() async {
// 先调用
await startAddBTDevice();
// 最后调用发送配网信息
// 如果没有获取到productKey、deviceName或者设备不支持获取设备的productKey、deviceName时,这里productKey、deviceName传空字符串
RTCXFluDeviceAddQRReq req = RTCXFluDeviceAddQRReq(
productKey: "获得设备的productKey",
deviceName: '获得设备的deviceName',
ssid: "Wi-Fi名",
wifiPwd: "Wi-Fi密码",
);
addDeviceApi
.getQRCodeData(req)
.then((List<String>? qrCodeStrings) {
if (qrCodeStrings!.isNotEmpty) {
String qrcodeString = qrCodeStrings.first;
RTCXFluBTLinkNetworkingReq req = RTCXFluBTLinkNetworkingReq(
sn: _bindingSn,
content: qrcodeString,
);
addDeviceApi
.sendNetworkingBTDevice(req)
.then((RTCXFluBTLinkResult result) {
if (true == result.success) {
// 发送成功,等待addDeviceApi.onDeviceAdd.listen绑定结果
// 可以设置定时器如2分钟,超时则认为绑定失败。addDeviceApi.onDeviceAdd.listen返回后关闭定时器。
} else {
Fluttertoast.showToast(msg: '连接设备失败');
}
})
.catchError((error) {
Fluttertoast.showToast(msg: '连接设备失败: $error');
});
} else {
Fluttertoast.showToast(msg: '获取content失败');
}
})
.catchError((error) {
Fluttertoast.showToast(msg: '获取content失败: $error');
});
}
Future<void> startAddBTDevice() async {
// 如果没有获取到productKey、deviceName或者设备不支持获取设备的productKey、deviceName时,这里productKey、deviceName传空字符串
RTCXFluDeviceAddBTReq btReq = RTCXFluDeviceAddBTReq(
productKey: "获得设备的productKey",
deviceName: '获得设备的deviceName',
);
return addDeviceApi.startAddBTDevice(btReq);
}
- 结束绑定
// 在diapose中调用stopAddDevice与destroy方法
@override
void dispose() {
super.dispose();
addDeviceApi.stopAddDevice();
addDeviceApi.destroy();
}
AP配网绑定
设备AP配网时,待设备重置后,等待设备待连接状态,连接设备的热点,通过App传输Wi-Fi的SSID和密码,使设备加入目标网络。
调用示例如下:
- 注册监听,并准备绑定
var addDeviceApi = RTCXFluAddDeviceController();
@override
void initState() {
super.initState();
addDeviceApi.onDeviceAddListener();
addDeviceApi.onDeviceAdd.listen((data) {
print("绑定结果:data: ${data.toString()}");
if (data.status ==
RTCXFluDeviceAddStatus.RTCXFluDeviceAddStatus_Success) {
Fluttertoast.showToast(msg: "绑定成功");
} else if (data.status ==
RTCXFluDeviceAddStatus.RTCXFluDeviceAddStatus_Prepared) {
Fluttertoast.showToast(msg: "已准备好添加设备");
debugPrint("error : ${data.error.code} -- ${data.error.message}");
} else {
Fluttertoast.showToast(
msg: "绑定结果:${data.status.name} + error:$data.error",
);
}
});
_prepare();
}
void _prepare() {
// 先添加代理 在调用
addDeviceApi.prepareAddDevice(RTCXFluDeviceAddType.RTCXFluDeviceAddType_AP);
}
- AP连接与发送配网信息
手机连接设备的热点后,调用startAPLinkConnect接口
// 调用AP连接
Future<void> _startAPLinkConnect() async {
try {
RTCXFluAPLinkConnectReq req = RTCXFluAPLinkConnectReq();
RTCXFluAPLinkResult result = await addDeviceApi.startAPLinkConnect(req);
if (true == result.success) {
// 连接成功
} else {
Fluttertoast.showToast(msg: 'AP连接失败: $e');
}
} catch(e) {
Fluttertoast.showToast(msg: 'AP连接失败: $e');
}
}
// 发送WI-FI、WI-FI密码给设备
Future<void> _sendNetworking() async {
try {
RTCXFluAPLinkNetworkingReq req = RTCXFluAPLinkNetworkingReq(ssid: 'wifi名', pwd: 'wifi密码');
RTCXFluAPLinkResult result = await addDeviceApi.sendAPLinkNetworking(req);
if (true == result.success) {
// 连接成功
} else {
Fluttertoast.showToast(msg: 'AP配网信息失败');
}
} catch(e) {
Fluttertoast.showToast(msg: 'AP配网信息失败: $e');
}
发送WiFi名称、WiFi密码后,设备连接上WIFI后,设备会主动断开热点。 设备主动断开热点后,APP会断开网络后重新连接其他网络。
- 绑定设备
APP会断开网络后重新连接其他网络后进行绑定
Future<void> addAPDevice() async {
try {
RTCXFluDeviceAddAPReq req = RTCXFluDeviceAddAPReq(productKey: '设备的productKey', deviceName: '设备的deviceName');
await addDeviceApi.startAddAPDevice(req);
} catch(e) {
Fluttertoast.showToast(msg: 'AP配网信息失败: $e');
}
}
- 结束绑定
// 在diapose中调用stopAddDevice与destroy方法
@override
void dispose() {
super.dispose();
addDeviceApi.stopAddDevice();
addDeviceApi.destroy();
}
设备解绑
final deviceApi = RTCXFluDeviceApi();
// 解绑设备
try {
final result = await deviceApi.deviceUnbind('iotId');
if (result.success == true) {
Fluttertoast.showToast(msg: '解绑成功');
} else {
Fluttertoast.showToast(msg: '解绑失败');
}
} catch (e) {
Fluttertoast.showToast(msg: '解绑失败: $e');
}
设备列表
class RTCXFluDeviceApi {
/// 获取设备列表信息
@async
RTCXFluDeviceInfoList getDeviceList(RTCXFluQueryDeviceListReq req);
/// 获取子设备列表
@async
RTCXFluDeviceInfoList getSubDeviceList(RTCXFluQuerySubDeviceListReq req);
}
获取设备列表调用示例
try {
final req = RTCXFluQueryDeviceListReq(pageNo: 1, pageSize: 10);
RTCXFluDeviceInfoList result = await deviceApi.getDeviceList(req);
setState(() {
dataList = result.data;
// 判断是否还有更多
bool hasMore = (result.data?.length ?? 0) < (result.total ?? 0);
});
} catch (e) {
Fluttertoast.showToast(msg: "获取设备列表失败: $e");
}
获取设备的子设备列表调用示例
try {
final req = RTCXFluQuerySubDeviceListReq(
iotId: "iotId",
productKey: "productKey",
deviceName: "deviceName",
pageNo: 1,
pageSize: 10,
);
RTCXFluDeviceInfoList result = await deviceApi.getSubDeviceList(req);
setState(() {
dataList = result.data;
// 判断是否还有更多
bool hasMore = (result.data?.length ?? 0) < (result.total ?? 0);
});
} catch (e) {
Fluttertoast.showToast(msg: "获取子设备列表失败: $e");
}
设备详细信息
class RTCXFluDeviceApi {
/// 获取设备列表信息
@async
RTCXFluDeviceInfoList getDeviceDetail(RTCXFluQueryDeviceDetailListReq req);
}
void _getDeviceDetail() {
RTCXFluQueryDeviceDetailReq req = RTCXFluQueryDeviceDetailReq(
iotId: widget.iotId,
productKey: widget.productKey,
deviceName: widget.deviceName,
);
List<RTCXFluQueryDeviceDetailReq> iotIds = [];
iotIds.add(req);
RTCXFluQueryDeviceDetailListReq listReq = RTCXFluQueryDeviceDetailListReq(
list: iotIds,
);
deviceApi.getDeviceDetail(listReq).then((RTCXFluDeviceInfoList data) {
print('查询设备详情成功:\n\n${data.toString()}');
}).catchError((error) {
print('调用异常:${error.toString()}');
});
}
获取设备额外信息
基于上层App不调用RTCXSDK的设备列表接口,而是使用他们自己平台的设备列表,导致在调用AIRTC播放器时,缺失了部分播放必要设备信息字段(如:播放策略、设备属性、当前套餐等)
所以需要App在获获取到他们自己设备列表成功后,触发AIRTC的设备额外信息接口,帮助播放器提前获取部分播放必要字段,App只需要触发该接口即可,不需要任何其他操作。
如果App不触发,在播放的时候,播放器内部也会主动触发该接口,可能影响播放响应速度
class RTCXFluDeviceApi {
/// 请求设备额外信息(App未调用设备列表接口时需要调用此接口,获取设备播放需要的必要信息)
@async
RTCXFluDeviceExtraInfoRsp getDeviceExtraInfo(RTCXFluDeviceExtraInfoReq req);
}
void _getDeviceExtraInfo() {
RTCXFluDeviceExtraInfoReq req = RTCXFluDeviceExtraInfoReq(iotId: widget.iotId, productKey: widget.productKey, deviceName: widget.deviceName);
deviceApi.getDeviceExtraInfo(req).then((RTCXFluDeviceExtraInfoRsp infoRsp) {
final buffer = StringBuffer();
buffer.writeln('查询设备额外信息');
buffer.writeln('infoRsp: ${infoRsp.iotId}');
buffer.writeln('playStrategy: ${infoRsp.playStrategy}');
buffer.writeln('thingProperties: ${infoRsp.thingProperties}');
buffer.writeln('cloudServices status: ${infoRsp.cloudServices?.status}');
buffer.writeln('cloudServices commodityName: ${infoRsp.cloudServices?.commodityName}');
buffer.writeln('cloudServices recordType: ${infoRsp.cloudServices?.recordType}');
buffer.writeln('cloudServices lifecycle: ${infoRsp.cloudServices?.lifecycle}');
buffer.writeln('cloudServices months: ${infoRsp.cloudServices?.months}');
buffer.writeln('cloudServices startTime: ${infoRsp.cloudServices?.startTime}');
buffer.writeln('cloudServices endTime: ${infoRsp.cloudServices?.endTime}');
buffer.writeln('playDurationConfig: ${infoRsp.playDurationConfig.toString()}');
buffer.writeln('');
Fluttertoast.showToast(msg: "查询设备额外信息结果Result:\n\n${buffer.toString()}");
}).catchError((error) {
Fluttertoast.showToast(msg: "查询设备额外信息失败: $e");
});
}
设备排序
class RTCXFluDeviceApi {
/// 设备排序
@async
RTCXFluDeviceResult deviceSort(RTCXFluDeviceSortReq req);
}
Future<void> _saveDeviceSort() async {
try {
List<int> sortIdList = [];
for (int i = 0; i < deviceList.length; i++) {
final info = deviceList[i];
if (info.sortId != null) {
sortIdList.add(info.sortId!);
}
}
final req = RTCXFluDeviceSortReq(sortedIdList: sortIdList);
final result = await deviceApi.deviceSort(req);
if (result.success) {
Fluttertoast.showToast(msg: "排序成功");
} else {
Fluttertoast.showToast(msg: "排序失败");
}
} catch (e) {
Fluttertoast.showToast(msg: "排序失败: $e");
}
}
修改设备昵称
class RTCXFluDeviceApi {
/// 设置设备昵称
@async
RTCXFluDeviceResult setDeviceNickName(RTCXFluDeviceNickdNameSetReq req);
}
修改设备昵称调用示例
try {
RTCXFluDeviceNickdNameSetReq req = RTCXFluDeviceNickdNameSetReq(iotId: '', nickName: '');
final result = await deviceApi.setDeviceNickName(req);
if (result.success == true) {
Fluttertoast.showToast(msg: '修改成功');
} else {
Fluttertoast.showToast(msg: '修改失败');
}
} catch (e) {
Fluttertoast.showToast(msg: '修改失败: $e');
}
设备配置
class RTCXFluDeviceApi {
/// 获取设备配置
@async
RTCXFluDeviceConfigRsp getDeviceConfig(RTCXFluGetDeviceConfigReq req);
/// 保存设备配置
@async
RTCXFluDeviceResult setDeviceConfig(RTCXFluSetDeviceConfigReq req);
}
获取设备配置
void _getDeviceConfig() {
RTCXFluGetDeviceConfigReq configReq = RTCXFluGetDeviceConfigReq(iotId: widget.iotId, attributeIdList: [1004]);
deviceApi.getDeviceConfig(configReq).then((RTCXFluDeviceConfigRsp configRsp) {
final buffer = StringBuffer();
buffer.writeln('获取设备配置');
buffer.writeln('maxUpdateTimeValue: ${configRsp.maxUpdateTimeValue}');
buffer.writeln('attributeMap: ${configRsp.attributeMap}');
if (configRsp.attributeMap != null) {
Map map = configRsp.attributeMap!["1004"] as Map;
configValue = map["value"];
}
buffer.writeln('configValue: ${configValue}');
print('Result:\n\n${buffer.toString()}');
}).catchError((error) {
print('调用异常:${error.toString()}');
});
}
保存设备配置
void _setDeviceConfig() {
if (configValue == null) {
return;
}
Map<String, Object> attribute = {
"id": "1004",
"value":configValue!,
};
RTCXFluSetDeviceConfigReq configReq = RTCXFluSetDeviceConfigReq(iotId: widget.iotId, attributeList: [attribute]);
deviceApi.setDeviceConfig(configReq).then((RTCXFluDeviceResult result) {
final buffer = StringBuffer();
buffer.writeln('保存设备配置');
buffer.writeln('result: ${result.success}');
print('Result:\n\n${buffer.toString()}');
}).catchError((error) {
print('调用异常:${error.toString()}');
});
}
云台预置位
class RTCXFluDeviceApi {
/// 保存预置位
@async
RTCXFluDeviceResult savePtzPresetPosition(
RTCXFluSavePtzPresetPositionReq req,
);
/// 获取预置位列表
@async
RTCXFluGetPtzPresetPositionListRsp getPtzPresetPositionList(
RTCXFluGetPtzPresetPositionListReq req,
);
/// 删除预置位
@async
RTCXFluDeviceResult deletePtzPresetPosition(
RTCXFluDeletePtzPresetPositionReq req,
);
/// 更新预置位名称
@async
RTCXFluDeviceResult updatePtzPresetPosition(
RTCXFluUpdatePtzPresetPositionReq req,
);
}
新增预置位
Future<void> _savePtzPresetPosition() async {
// ptz位置信息, 格式{"X":1054,"Y":2500}
String ptz = '';
// 图片的Uint8List
Uint8List data = await getAssetAsUint8List("assets/avatar1.png");
RTCXFluSavePtzPresetPositionReq positionReq = RTCXFluSavePtzPresetPositionReq(iotId: widget.iotId, ptz: ptz, name: "新预置名称", imageData: data);
deviceApi.savePtzPresetPosition(positionReq).then((RTCXFluDeviceResult result) {
final buffer = StringBuffer();
buffer.writeln('保存预置位');
buffer.writeln('result: ${result.success}');
print('Result:\n\n${buffer.toString()}');
}).catchError((error) {
print('调用异常:${error.toString()}');
});
}
删除预置位
void _deletePtzPresetPosition() {
// 预置位的picId
String picId = '';
RTCXFluDeletePtzPresetPositionReq positionReq = RTCXFluDeletePtzPresetPositionReq(iotId: widget.iotId, picId: picId);
deviceApi.deletePtzPresetPosition(positionReq).then((RTCXFluDeviceResult result) {
final buffer = StringBuffer();
buffer.writeln('删除预置位');
buffer.writeln('result: ${result.success}');
print('Result:\n\n${buffer.toString()}');
}).catchError((error) {
print('调用异常:${error.toString()}');
});
}
修改预置位名称
void _updatePtzPresetPosition() {
// 预置位的picId
String picId = '';
RTCXFluUpdatePtzPresetPositionReq positionReq = RTCXFluUpdatePtzPresetPositionReq(iotId: widget.iotId, picId: picId, name: '预置位新名称');
deviceApi.updatePtzPresetPosition(positionReq).then((RTCXFluDeviceResult result) {
final buffer = StringBuffer();
buffer.writeln('更新预置位');
buffer.writeln('result: ${result.success}');
print('Result:\n\n${buffer.toString()}');
}).catchError((error) {
print('调用异常:${error.toString()}');
});
}
获取预置位列表
void _getPtzPresetPositionList() {
RTCXFluGetPtzPresetPositionListReq listReq = RTCXFluGetPtzPresetPositionListReq(iotId: widget.iotId);
deviceApi.getPtzPresetPositionList(listReq).then((RTCXFluGetPtzPresetPositionListRsp listRsp) {
final buffer = StringBuffer();
buffer.writeln('获取预置位列表');
buffer.writeln('');
if (listRsp.presetPositionList != null) {
presetPositionList = listRsp.presetPositionList!;
for (int i = 0; i < listRsp.presetPositionList!.length; i++) {
final item = listRsp.presetPositionList![i];
buffer.writeln('[$i]');
buffer.writeln('name: ${item.name}');
buffer.writeln('picId: ${item.picId}');
buffer.writeln('ptz: ${item.ptz}');
buffer.writeln('url: ${item.url}');
buffer.writeln('');
}
}
print('Result:\n\n${buffer.toString()}');
}).catchError((error) {
print('调用异常:${error.toString()}');
});
}
获取设备电量信息
class RTCXFluDeviceApi {
/// 获取电池电量列表
@async
RTCXFluBatteryPowerListRsp getBatteryPowerList(
RTCXFluBatteryPowerListReq req,
);
}
void _getBatteryPowerList() {
final now = DateTime.now();
final yesterday = now.subtract(const Duration(hours: 24));
RTCXFluBatteryPowerListReq req = RTCXFluBatteryPowerListReq(iotId: widget.iotId, startTime: yesterday.millisecondsSinceEpoch, endTime: now.millisecondsSinceEpoch, limit: 100);
deviceApi.getBatteryPowerList(req).then((RTCXFluBatteryPowerListRsp listRsp) {
final buffer = StringBuffer();
buffer.writeln('获取电池电量列表');
buffer.writeln('');
if (listRsp.electricQuantityList != null) {
for (int i = 0; i < listRsp.electricQuantityList!.length; i++) {
final item = listRsp.electricQuantityList![i];
buffer.writeln('[$i]');
buffer.writeln('timestamp: ${item.timestamp}--value: ${item.value}');
buffer.writeln('');
}
}
print('Result:\n\n${buffer.toString()}');
}).catchError((error) {
print('调用异常:${error.toString()}');
});
}
设备缩略图
- 获取设备缩略图
void getDeviceThumb(RTCXFluDeviceInfoModel info) {
RTCXFluGetDeviceThumbnailReq req = RTCXFluGetDeviceThumbnailReq(
productKey: '${info.productKey}',
deviceName: '${info.deviceName}',
definition: 1,
picType: 'jpg',
isPrivatized: false);
String iotId = "${info.iotId}";
deviceApi.getDeviceThumbnail(req).then((RTCXFluGetDeviceThumbnailRsp thumbRsp) {
StringBuffer buffer = StringBuffer();
buffer.writeln('RTCXFluGetDeviceThumbnailRsp thumbRsp');
buffer.writeln('productKey: ${thumbRsp.productKey}');
buffer.writeln('deviceName: ${thumbRsp.productKey}');
buffer.writeln('设备缩略图地址 downloadUrl: ${thumbRsp.downloadUrl}');
buffer.writeln('设备缩略图过期时间: ${thumbRsp.expiredTime}');
buffer.writeln('');
print("getDeviceThumb thumbRsp :${buffer.toString()}");
if(thumbRsp.productKey != null && thumbRsp.deviceName != null) {
setState(() {
thumbData[iotId] = thumbRsp;
});
}
}).catchError((error){
print("getDeviceThumb catchError:$error");
});
}
- 通过物模型服务获取设备缩略图
// 导入物模型头文件
import 'package:airtc_engine/src/thing/rtcx_thing.dart';
import 'package:airtc_engine/src/thing/rtcx_thing_controller.dart';
late RTCXFluThingController _thingApi;
@override
void initState() {
super.initState();
// 物模型
RTCXFluThingReq req = RTCXFluThingReq(
productKey: widget.productKey,
deviceName: widget.deviceName,
iotId: widget.iotId,
deviceType: widget.deviceType,
);
_thingApi = RTCXFluThingController();
_thingApi.buildThing(req);
_thingApi.registerThingObserver();
_thingApi.onStatusChange.listen((data) {
print("onStatusChange:"+data.toString());
});
_thingApi.onDeviceTransferMessage.listen((RTCXFluThingObserver observer) {
print("onDeviceTransferMessage:"+observer.toString());
});
}
Future<void> getDeviceThumb() async {
try {
final result = await _thingApi.invokeService(
RTCXFluThingCommand(
command: "GetDevPicture",
params: {
"definition": 1,
"picType": "jpg",
},
),
);
if(result.success && result.dataObject != null) {
Map<String, dynamic> dataObjectMap = jsonDecode(result.dataObject!);
// 获取的设备缩略图
String? picUrl = dataObjectMap["downloadUrl"];
}
Fluttertoast.showToast(msg: "获取缩略图${result == true ? "成功" : "失败"}, ${result.dataObject}");
} catch(e) {
Fluttertoast.showToast(msg: "获取缩略图失败:${e.toString()}");
}
}
// 不需要的时候需要做destroy释放操作
@override
void dispose() {
super.dispose();
_thingApi.destroy();
}
低功耗设备唤醒
class RTCXFluDeviceApi {
/// 休眠设备唤醒,可以通过定时器循环调用唤醒设备,唤醒成功后关闭定时器,并且进行播放
@async
RTCXFluDeviceResult wakeupDevice(String iotId);
}
低功耗设备唤醒调用示例
Future<void> _wakeupDevice(String iotId) async {
try {
final result = await deviceApi.wakeupDevice(iotId);
if (result.success == true) {
Fluttertoast.showToast(msg: '调用成功');
} else {
Fluttertoast.showToast(msg: '调用失败');
}
} catch (e) {
Fluttertoast.showToast(msg: '调用失败: $e');
}
}
- 调用该接口只代表触发了低功耗设备唤醒,其返回成功结果并不代表设备已经唤醒上线(因为唤醒需要一定的时间)
- 针对低功耗设备的播放,APP需要按如下逻辑实现:
- 调用唤醒接口触发设备唤醒
- 监听设备上线,监听方式有两种:a. 定时器轮询物模型的RTCXFluThingResult getStatus()接口 b. 或者代理协议监听物对象的void onStatusChange(RTCXFluThingObserver value)协议方法
- 设备上线后再调用播放器进行播放
- 为了防止低功耗设备在播放过程中休眠(比如从播放页进入设置页去设置一些参数,此时如果设备休眠,是无法成功设置参数的),App需要在播放界面使用定时器调用物模型,向设备发送物服务WakeupHeartbeat心跳(间隔可控制10秒一次),保持低功耗设备不休眠,播放界面销毁时,停止定时器