fix:完善对讲流程、增加监控功能

This commit is contained in:
liyi 2025-01-09 14:10:10 +08:00
parent 7943aef0c2
commit 323c99b27e
28 changed files with 528 additions and 284 deletions

View File

@ -1,5 +1,6 @@
//
import 'dart:convert';
import 'dart:typed_data';
import 'package:star_lock/app_settings/app_settings.dart';
@ -49,12 +50,19 @@ class GatewayConfiguringWifiCommand extends SenderProtocol {
//gatewayConfigurationStr
final int clientIdLength = utf8.encode(gatewayConfigurationStr!).length;
final double clientIdLengthDouble = clientIdLength / 256;
final int clientIdLengthDoubleType1 = clientIdLengthDouble.toInt();
final int clientIdLengthDoubleType2 = clientIdLength % 256;
// AppLog.log('gatewayConfigurationStr!:$gatewayConfigurationStr! clientIdLength:$clientIdLength clientIdLengthDouble:$clientIdLengthDouble clientIdLengthDoubleType1:$clientIdLengthDoubleType1 clientIdLengthDoubleType2:$clientIdLengthDoubleType2');
data.add(clientIdLengthDoubleType1);
data.add(clientIdLengthDoubleType2);
Uint8List lengthBytes = Uint8List(2);
ByteData byteData = ByteData.view(lengthBytes.buffer);
byteData.setUint16(0, clientIdLength, Endian.little); // 使big-endian
// subData
subData.addAll(lengthBytes);
// subData.add(clientIdLength);
// final double clientIdLengthDouble = clientIdLength / 256;
// final int clientIdLengthDoubleType1 = clientIdLengthDouble.toInt();
// final int clientIdLengthDoubleType2 = clientIdLength % 256;
// // AppLog.log('gatewayConfigurationStr!:$gatewayConfigurationStr! clientIdLength:$clientIdLength clientIdLengthDouble:$clientIdLengthDouble clientIdLengthDoubleType1:$clientIdLengthDoubleType1 clientIdLengthDoubleType2:$clientIdLengthDoubleType2');
// data.add(clientIdLengthDoubleType1);
// data.add(clientIdLengthDoubleType2);
subData.addAll(utf8.encode(gatewayConfigurationStr!));
// subData = getFixedLengthList(subData, 20 - clientIdLength);

View File

@ -0,0 +1,64 @@
class DeviceNetwork {
DeviceNetwork({
this.description,
this.errorCode,
this.data,
this.errorMsg,});
DeviceNetwork.fromJson(dynamic json) {
description = json['description'];
errorCode = json['errorCode'];
data = json['data'] != null ? DeviceNetworkInfo.fromJson(json['data']) : null;
errorMsg = json['errorMsg'];
}
String? description;
int? errorCode;
DeviceNetworkInfo? data;
String? errorMsg;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['description'] = description;
map['errorCode'] = errorCode;
if (data != null) {
map['data'] = data!.toJson();
}
map['errorMsg'] = errorMsg;
return map;
}
}
class DeviceNetworkInfo {
DeviceNetworkInfo({
this.wifiName,
this.networkMac,
this.secretKey,
this.peerId,
});
DeviceNetworkInfo.fromJson(dynamic json) {
wifiName = json['wifiName'];
networkMac = json['networkMac'];
secretKey = json['secretKey'];
peerId = json['peerId'];
}
String? wifiName;
String? networkMac;
String? secretKey;
String? peerId;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['wifiName'] = wifiName;
map['networkMac'] = networkMac;
map['secretKey'] = secretKey;
map['peerId'] = peerId;
return map;
}
}

View File

@ -7,12 +7,19 @@ import 'package:get/get.dart';
import 'package:intl/intl.dart' as intl;
import 'package:star_lock/app_settings/app_colors.dart';
import 'package:star_lock/flavors.dart';
import 'package:star_lock/main/lockDetail/lockDetail/device_network_info.dart';
import 'package:star_lock/main/lockDetail/lockDetail/lockDetail_state.dart';
import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
import 'package:star_lock/main/lockMian/lockMain/lockMain_logic.dart';
import 'package:star_lock/mine/gateway/addGateway/gatewayConfigurationWifi/getGatewayConfiguration_entity.dart';
import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/talk/startChart/start_chart_manage.dart';
import 'package:star_lock/tools/aliyunRealNameAuth/aliyunRealNameAuthHandle.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import 'package:star_lock/tools/bugly/bugly_tool.dart';
import 'package:star_lock/tools/showCupertinoAlertView.dart';
import 'package:star_lock/tools/showTipView.dart';
import 'package:star_lock/tools/storage.dart';
import 'package:star_lock/widget/flavors_img.dart';
import '../../../appRouters.dart';
@ -1154,11 +1161,26 @@ class _LockDetailPageState extends State<LockDetailPage>
if (state.keyInfos.value.lockFeature!.videoIntercom == 1) {
showWidgetArr.add(
bottomItem('images/main/icon_catEyes.png', '监控'.tr,
state.bottomBtnisEable.value, () {
Get.toNamed(Routers.realTimePicturePage, arguments: <String, Object?>{
'lockName': state.keyInfos.value.lockName,
'isMonitoring': true
});
state.bottomBtnisEable.value, () async {
final lockId = state.keyInfos.value.lockId;
final LockSetInfoEntity entity =
await ApiRepository.to.getLockSettingInfoData(
lockId: lockId.toString(),
);
if (entity.errorCode!.codeIsSuccessful) {
final LockSetInfoData data = entity.data!;
final mac = data.lockBasicInfo?.mac;
if (mac != null && mac.isNotEmpty) {
final DeviceNetwork deviceNetworkInfo = await ApiRepository.to
.getDeviceNetwork(deviceType: 2, deviceMac: mac);
final peerId = deviceNetworkInfo?.data?.peerId;
if (peerId == null || peerId.isEmpty) {
throw Exception('设备peerId为空');
}
StartChartManage()
.startCallRequestMessageTimer(ToPeerId: peerId ?? '');
}
}
}),
);
}

View File

@ -1,13 +1,19 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
import 'package:network_info_plus/network_info_plus.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:star_lock/app_settings/app_settings.dart';
import 'package:star_lock/blue/io_gateway/io_gateway_configuringWifi.dart';
import 'package:star_lock/login/login/entity/LoginEntity.dart';
import 'package:star_lock/main/lockDetail/lockSet/configuringWifi/configuringWifi/configuringWifiEntity.dart';
import 'package:star_lock/mine/gateway/addGateway/gatewayConfigurationWifi/getGatewayConfiguration_entity.dart';
import 'package:star_lock/talk/startChart/entity/star_chart_register_node_entity.dart';
import 'package:star_lock/talk/startChart/start_chart_manage.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import '../../../../../blue/blue_manage.dart';
@ -32,10 +38,20 @@ class ConfiguringWifiLogic extends BaseGetXController {
}
}
Future<void> updateNetworkInfo() async {
final LoginEntity entity = await ApiRepository.to.updateNetworkInfo(
lockId: state.lockSetInfoData.value.lockId!,
network: state.wifiNameController.text,
Future<void> updateNetworkInfo({
required String peerId,
required String wifiName,
required String secretKey,
required String deviceMac,
required String networkMac,
}) async {
final LoginEntity entity = await ApiRepository.to.settingDeviceNetwork(
deviceType: 2,
deviceMac: deviceMac,
wifiName: wifiName,
networkMac: networkMac,
secretKey: secretKey,
peerId: peerId,
);
if (entity.errorCode!.codeIsSuccessful) {
showToast('配网成功'.tr, something: () {
@ -53,92 +69,64 @@ class ConfiguringWifiLogic extends BaseGetXController {
_replySubscription =
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async {
// WIFI配网结果
if (reply is SenderConfiguringWifiReply) {
_replySenderConfiguringWifi(reply);
if (reply is GatewayConfiguringWifiResultReply) {
_replySenderConfiguringWifiResult(reply);
}
});
}
// WIFI配网结果
Future<void> _replySenderConfiguringWifi(Reply reply) async {
final int status = reply.data[5];
Future<void> _replySenderConfiguringWifiResult(Reply reply) async {
final int status = reply.data[2];
state.sureBtnState.value = 0;
switch (status) {
case 0x00:
//
state.sureBtnState.value = 0;
cancelBlueConnetctToastTimer();
dismissEasyLoading();
updateNetworkInfo();
break;
case 0x06:
//
final List<String>? privateKey =
await Storage.getStringList(saveBluePrivateKey);
final List<int> getPrivateKeyList =
changeStringListToIntList(privateKey!);
final int secretKeyJsonLength = (reply.data[4] << 8) + reply.data[3];
final List<String>? publicKey =
await Storage.getStringList(saveBluePublicKey);
final List<int> publicKeyDataList =
changeStringListToIntList(publicKey!);
final List<int> secretKeyList =
reply.data.sublist(5, 5 + secretKeyJsonLength);
String result = utf8String(secretKeyList);
// JSON Map
Map<String, dynamic> jsonMap = json.decode(result);
final List<int> tokenData = reply.data.sublist(7, 10);
final List<String> saveStrList = changeIntListToStringList(tokenData);
Storage.setStringList(saveBlueToken, saveStrList);
// peerId
String? peerId = jsonMap['peerId'];
String? wifiName = jsonMap['wifiName'];
String? secretKey = jsonMap['secretKey'];
String? deviceMac = jsonMap['deviceMac'];
String? networkMac = jsonMap['networkMac'];
final List<int> serversList = <int>[];
for (int i = 0;
i < state.configuringWifiEntity.value.data!.serviceList!.length;
i++) {
final ServiceList item =
state.configuringWifiEntity.value.data!.serviceList![i];
final List<String> itemList = item.serviceIp!.split('.');
for (String element in itemList) {
serversList.add(int.parse(element));
}
/// ,peerId
StartChartManage().lockPeerId = peerId ?? '';
final double typeDouble = int.parse(item.port!) / 256;
final int type1 = typeDouble.toInt();
final int type2 = int.parse(item.port!) % 256;
serversList.add(type1);
serversList.add(type2);
}
//
final loginData = await Storage.getLoginData();
// app用户的peerId
String appPeerId = loginData?.starchart?.starchartId ?? '';
final List<String> uidList = <String>[Storage.getUid().toString()];
IoSenderManage.senderConfiguringWifiCommand(
keyID: state.lockSetInfoData.value.lockBasicInfo!.keyId.toString(),
userID: await Storage.getUid(),
ssid: state.wifiNameController.text,
password: state.wifiPWDController.text,
numberOfServers: state.configuringWifiEntity.value.data!.serviceNum,
listOfServers: serversList,
numberOfPhone: uidList.length,
listOfPhone: uidList,
token: tokenData,
needAuthor: 1,
publicKey: publicKeyDataList,
privateKey: getPrivateKeyList,
peerId: appPeerId,
);
break;
case 0xff:
//
showToast('配网失败'.tr);
//
await Storage.saveLockNetWorkInfo(jsonMap);
//
updateNetworkInfo(
peerId: peerId ?? '',
wifiName: wifiName ?? '',
secretKey: secretKey ?? '',
deviceMac: deviceMac ?? '',
networkMac: networkMac ?? '');
break;
default:
//
dismissEasyLoading();
cancelBlueConnetctToastTimer();
showToast('配网失败'.tr);
break;
}
}
// JSON
String prettyPrintJson(String jsonString) {
var jsonObject = json.decode(jsonString);
return JsonEncoder.withIndent(' ').convert(jsonObject);
}
// wifi
Future<void> senderConfiguringWifiAction() async {
if (state.wifiNameController.text.isEmpty) {
@ -146,6 +134,10 @@ class ConfiguringWifiLogic extends BaseGetXController {
return;
}
if (state.wifiPWDController.text.isEmpty) {
showToast('请输入WiFi密码'.tr);
return;
}
if (state.sureBtnState.value == 1) {
return;
}
@ -156,71 +148,61 @@ class ConfiguringWifiLogic extends BaseGetXController {
dismissEasyLoading();
state.sureBtnState.value = 0;
});
final GetGatewayConfigurationEntity entity =
await ApiRepository.to.getGatewayConfiguration(timeout: 60);
if (entity.errorCode!.codeIsSuccessful) {
state.getGatewayConfigurationStr = entity.data ?? '';
}
//
final loginData = await Storage.getLoginData();
// app用户的peerId
String appPeerId = loginData?.starchart?.starchartId ?? '';
//
if (state.getGatewayConfigurationStr.isNotEmpty) {
// JSON Map
Map<String, dynamic> jsonMap =
json.decode(state.getGatewayConfigurationStr);
//
jsonMap.remove("starCloudUrl");
jsonMap.remove("starLockPeerId");
//
jsonMap['userPeerld'] = appPeerId;
// Map JSON
state.getGatewayConfigurationStr =
json.encode(jsonMap).replaceAll(',', ',\n');
//
state.getGatewayConfigurationStr =
prettyPrintJson(state.getGatewayConfigurationStr);
} else {
//
state.getGatewayConfigurationStr = "{\"userPeerld\": \"$appPeerId\"}";
}
// JSON
// if (state.getGatewayConfigurationStr.isNotEmpty) {
// //
// state.getGatewayConfigurationStr =
// state.getGatewayConfigurationStr.replaceAll(
// RegExp(r'}\s*$'),
// ',\n{\"userPeerld\": \"$appPeerId\"}',
// );
// } else {
// //
// state.getGatewayConfigurationStr = "{\"userPeerld\": \"$appPeerId\"}";
// }
BlueManage().blueSendData(BlueManage().connectDeviceName,
(BluetoothConnectionState connectionState) async {
if (connectionState == BluetoothConnectionState.connected) {
final List<String>? privateKey =
await Storage.getStringList(saveBluePrivateKey);
final List<int> getPrivateKeyList =
changeStringListToIntList(privateKey!);
final List<String>? publicKey =
await Storage.getStringList(saveBluePublicKey);
final List<int> publicKeyDataList =
changeStringListToIntList(publicKey!);
final List<String>? token = await Storage.getStringList(saveBlueToken);
final List<int> getTokenList = changeStringListToIntList(token!);
final List<int> serversList = <int>[];
for (int i = 0;
i < state.configuringWifiEntity.value.data!.serviceList!.length;
i++) {
final ServiceList item =
state.configuringWifiEntity.value.data!.serviceList![i];
if (item.serviceIp!.contains('192')) {
final List<String> itemList = item.serviceIp!.split('.');
for (String element in itemList) {
serversList.add(int.parse(element));
}
} else {
final List<InternetAddress> addresses =
await InternetAddress.lookup(item.serviceIp!);
final List<String> itemList = addresses.first.address.split('.');
for (String element in itemList) {
serversList.add(int.parse(element));
}
}
final double typeDouble = int.parse(item.port!) / 256;
final int type1 = typeDouble.toInt();
final int type2 = int.parse(item.port!) % 256;
serversList.add(type1);
serversList.add(type2);
}
final String? uidStr = await Storage.getUid();
final List<String> uidList = <String>[uidStr.toString()];
//
final loginData = await Storage.getLoginData();
// app用户的peerId
String appPeerId = loginData?.starchart?.starchartId ?? '';
IoSenderManage.senderConfiguringWifiCommand(
keyID: state.lockSetInfoData.value.lockBasicInfo!.keyId.toString(),
userID: await Storage.getUid(),
IoSenderManage.gatewayConfiguringWifiCommand(
ssid: state.wifiNameController.text,
password: state.wifiPWDController.text,
peerId: appPeerId,
numberOfServers: state.configuringWifiEntity.value.data!.serviceNum,
listOfServers: serversList,
numberOfPhone: uidList.length,
listOfPhone: uidList,
token: getTokenList,
needAuthor: 1,
publicKey: publicKeyDataList,
privateKey: getPrivateKeyList,
gatewayConfigurationStr: state.getGatewayConfigurationStr,
);
} else if (connectionState == BluetoothConnectionState.disconnected) {
dismissEasyLoading();
@ -230,7 +212,7 @@ class ConfiguringWifiLogic extends BaseGetXController {
showBlueConnetctToast();
}
}
});
}, isAddEquipment: true);
}
final NetworkInfo _networkInfo = NetworkInfo();

View File

@ -25,5 +25,5 @@ class ConfiguringWifiState{
TextEditingController wifiNameController = TextEditingController();
TextEditingController wifiPWDController = TextEditingController();
String getGatewayConfigurationStr = '';
}

View File

@ -1,9 +1,10 @@
import 'dart:async';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
import 'package:star_lock/blue/io_gateway/io_gateway_getWifiList.dart';
import 'package:star_lock/blue/io_protocol/io_getWifiList.dart';
import 'package:star_lock/talk/startChart/start_chart_manage.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import '../../../../../blue/blue_manage.dart';
@ -19,13 +20,15 @@ class WifiListLogic extends BaseGetXController {
//
late StreamSubscription<Reply> _replySubscription;
void _initReplySubscription() {
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((Reply reply) {
if(reply is SenderGetWifiReply) {
_replySubscription =
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) {
if (reply is GatewayGetWifiReply) {
_replySendGetWifiParameters(reply);
}
if(reply is SenderGetWifiListReply) {
if (reply is GatewayGetWifiListReply) {
_replyGetWifiListParameters(reply);
}
});
@ -34,7 +37,7 @@ class WifiListLogic extends BaseGetXController {
// wifi列表数据解析
Future<void> _replySendGetWifiParameters(Reply reply) async {
final int status = reply.data[2];
switch(status){
switch (status) {
case 0x00:
//
showEasyLoading();
@ -43,42 +46,24 @@ class WifiListLogic extends BaseGetXController {
break;
case 0x06:
//
// var token = await Storage.getStringList(saveBlueToken);
// List<int> getTokenList = changeStringListToIntList(token!);
//
// var privateKey = await Storage.getStringList(saveBluePrivateKey);
// List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
//
// var publicKey = await Storage.getStringList(saveBluePublicKey);
// List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
//
// IoSenderManage.getWifiListCommand(
// keyID: state.lockSetInfoData.value.lockBasicInfo!.keyId.toString(),
// userID: await Storage.getUid(),
// token: getTokenList,
// needAuthor: 1,
// publicKey: publicKeyDataList,
// privateKey: getPrivateKeyList,
// );
break;
default:
break;
}
}
//
// WiFi数据解析
Future<void> _replyGetWifiListParameters(Reply reply) async {
final int status = reply.data[2];
switch(status){
switch (status) {
case 0x00:
//
// showEasyLoading();
dismissEasyLoading();
state.sureBtnState.value = 0;
if (reply.data[6] > 0) {
reply.data.removeRange(0, 7);
if (reply.data[3] > 0) {
reply.data.removeRange(0, 4);
// 33
final List<List<int>> getList = splitList(reply.data, 33);
final List<Map<String, String>> uploadList = <Map<String, String>>[];
@ -92,7 +77,6 @@ class WifiListLogic extends BaseGetXController {
state.wifiNameDataList.value = uploadList;
}
}
break;
default:
break;
@ -101,44 +85,31 @@ class WifiListLogic extends BaseGetXController {
// wifi列表
Future<void> senderGetWifiListWifiAction() async {
if(state.sureBtnState.value == 1){
if (state.sureBtnState.value == 1) {
return;
}
state.sureBtnState.value = 1;
showEasyLoading();
showBlueConnetctToastTimer(action: (){
showBlueConnetctToastTimer(action: () {
dismissEasyLoading();
state.sureBtnState.value = 0;
});
BlueManage().blueSendData(BlueManage().connectDeviceName, (BluetoothConnectionState connectionState) async {
if (connectionState == BluetoothConnectionState.connected){
final List<String>? token = await Storage.getStringList(saveBlueToken);
final List<int> getTokenList = changeStringListToIntList(token!);
final List<String>? privateKey = await Storage.getStringList(saveBluePrivateKey);
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
final List<String>? publicKey = await Storage.getStringList(saveBluePublicKey);
final List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
IoSenderManage.getWifiListCommand(
keyID: state.lockSetInfoData.value.lockBasicInfo!.keyId.toString(),
BlueManage().blueSendData(BlueManage().connectDeviceName,
(BluetoothConnectionState connectionState) async {
if (connectionState == BluetoothConnectionState.connected) {
IoSenderManage.gatewayGetWifiCommand(
userID: await Storage.getUid(),
token: getTokenList,
needAuthor: 1,
publicKey: publicKeyDataList,
privateKey: getPrivateKeyList,
);
} else if (connectionState == BluetoothConnectionState.disconnected) {
dismissEasyLoading();
state.sureBtnState.value = 0;
cancelBlueConnetctToastTimer();
if(state.ifCurrentScreen.value == true){
if (state.ifCurrentScreen.value == true) {
showBlueConnetctToast();
}
}
});
}, isAddEquipment: true);
}
@override
@ -160,5 +131,4 @@ class WifiListLogic extends BaseGetXController {
super.onClose();
_replySubscription.cancel();
}
}
}

View File

@ -1,4 +1,3 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
@ -28,31 +27,39 @@ class _WifiListPageState extends State<WifiListPage> {
return Scaffold(
backgroundColor: Colors.white,
appBar: TitleAppBar(
barTitle: 'WIFI列表'.tr,
haveBack: true,
actionsList: <Widget>[
TextButton(
child: Text(
'刷新'.tr, style: TextStyle(color: Colors.white, fontSize: 24.sp),
),
onPressed: logic.senderGetWifiListWifiAction,
),
],
backgroundColor: AppColors.mainColor),
barTitle: 'WIFI列表'.tr,
haveBack: true,
actionsList: <Widget>[
TextButton(
child: Text(
'刷新'.tr,
style: TextStyle(color: Colors.white, fontSize: 24.sp),
),
onPressed: logic.senderGetWifiListWifiAction,
),
],
backgroundColor: AppColors.mainColor),
body: Column(
children: <Widget>[
Expanded(
child: Obx(() => state.wifiNameDataList.value.isNotEmpty ? ListView.builder(
itemCount: state.wifiNameDataList.value.length,
itemBuilder: (BuildContext c, int index) {
Map wifiNameStr = state.wifiNameDataList.value[index];
return _messageListItem(wifiNameStr['wifiName'], wifiNameStr['rssi'], () {
Get.toNamed(Routers.configuringWifiPage, arguments: {
'lockSetInfoData': state.lockSetInfoData.value,
'wifiName': wifiNameStr['wifiName'],
});
});
}) : NoData(noDataHeight: 1.sh - ScreenUtil().statusBarHeight - ScreenUtil().bottomBarHeight - 64.h)),
child: Obx(() => state.wifiNameDataList.value.isNotEmpty
? ListView.builder(
itemCount: state.wifiNameDataList.value.length,
itemBuilder: (BuildContext c, int index) {
Map wifiNameStr = state.wifiNameDataList.value[index];
return _messageListItem(
wifiNameStr['wifiName'], wifiNameStr['rssi'], () {
Get.toNamed(Routers.configuringWifiPage, arguments: {
'lockSetInfoData': state.lockSetInfoData.value,
'wifiName': wifiNameStr['wifiName'],
});
});
})
: NoData(
noDataHeight: 1.sh -
ScreenUtil().statusBarHeight -
ScreenUtil().bottomBarHeight -
64.h)),
),
SubmitBtn(
btnName: '手动配网'.tr,
@ -60,16 +67,16 @@ class _WifiListPageState extends State<WifiListPage> {
borderRadius: 20.w,
padding: EdgeInsets.only(top: 25.w, bottom: 25.w),
onClick: () {
Get.toNamed(Routers.configuringWifiPage, arguments: <String, LockSetInfoData>{
'lockSetInfoData': state.lockSetInfoData.value
});
Get.toNamed(Routers.configuringWifiPage,
arguments: <String, LockSetInfoData>{
'lockSetInfoData': state.lockSetInfoData.value
});
}),
SizedBox(
height: 64.h,
)
],
)
);
));
}
Widget _messageListItem(String wifiName, String rssi, Function() action) {
@ -91,7 +98,7 @@ class _WifiListPageState extends State<WifiListPage> {
children: <Widget>[
SizedBox(
height: 79.h,
width: 1.sw - 20.w*2,
width: 1.sw - 20.w * 2,
child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[

View File

@ -1,5 +1,8 @@
import 'dart:typed_data';
import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import 'package:video_thumbnail/video_thumbnail.dart';
import 'videoLog_state.dart';
class VideoLogLogic extends BaseGetXController {
@ -11,10 +14,33 @@ class VideoLogLogic extends BaseGetXController {
);
if (entity.errorCode!.codeIsSuccessful) {
state.videoLogList.value = entity.data!;
state.videoLogList.refresh();
// state.videoLogList.forEach((element) {
// final recordList = element.recordList;
// if (recordList != null && recordList.isNotEmpty) {
// recordList.forEach((item) {
// if (item.videoUrl != null && item.videoUrl!.isNotEmpty) {
// final coverImage = aw handleVideoCoverImage(item.videoUrl);
// state.videoCoverList.add(coverImage);
// }
// });
// }
// });
}
}
Future<Uint8List?> handleVideoCoverImage(videoUrl) async {
final uint8list = await VideoThumbnail.thumbnailData(
video: videoUrl,
imageFormat: ImageFormat.JPEG,
maxWidth: 128,
// specify the width of the thumbnail, let the height auto-scaled to keep the source aspect ratio
quality: 25,
);
return uint8list;
}
@override
onReady() {
super.onReady();

View File

@ -1,4 +1,3 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
@ -11,7 +10,7 @@ import 'package:star_lock/tools/noData.dart';
import '../../../../app_settings/app_colors.dart';
import '../../../../tools/titleAppBar.dart';
import 'videoLog_logic.dart';
import 'videoLog_logic.dart';import 'package:video_thumbnail/video_thumbnail.dart';
class VideoLogPage extends StatefulWidget {
const VideoLogPage({Key? key}) : super(key: key);
@ -293,11 +292,7 @@ class _VideoLogPageState extends State<VideoLogPage> {
color: Colors.white,
child: ClipRRect(
borderRadius: BorderRadius.circular(10.w),
child: Image(
fit: BoxFit.cover,
image: Image.network(recordData.imagesUrl ??
'images/icon_video_placeholder.jpg')
.image),
child: _buildImageOrVideoItem(recordData),
),
),
SizedBox(height: 5.h),
@ -310,4 +305,30 @@ class _VideoLogPageState extends State<VideoLogPage> {
),
);
}
_buildImageOrVideoItem(RecordListData recordData) {
if (recordData.videoUrl != null && recordData.videoUrl!.isNotEmpty) {
return _buildVideoItem(recordData);
} else {
return _buildImageItem(recordData);
}
}
_buildVideoItem(RecordListData recordData) async {
final uint8list = await VideoThumbnail.thumbnailData(
video: recordData.videoUrl!,
imageFormat: ImageFormat.JPEG,
maxWidth: 128,
// specify the width of the thumbnail, let the height auto-scaled to keep the source aspect ratio
quality: 25,
);
return Image.memory(uint8list!);
}
_buildImageItem(RecordListData recordData) {
return Image.network(
recordData.imagesUrl!,
fit: BoxFit.cover,
);
}
}

View File

@ -1,3 +1,5 @@
import 'dart:typed_data';
import 'package:get/get.dart';
import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart';
@ -6,6 +8,7 @@ class VideoLogState {
var localList = [];
var getLockId = 0.obs;
var videoLogList = <CloudStorageData>[].obs;
var videoCoverList = <Uint8List>[].obs;
VideoLogState() {
Map map = Get.arguments;

View File

@ -67,7 +67,10 @@ abstract class Api {
final String getWifiServiceIpURL = '/wifiLock/getWifiServiceIp'; // Wifi锁服务器
final String updateLockSettingUrl =
'/v2/lockSetting/updateLockSetting'; //
final String deviceNetworkConfiguration =
'/deviceNetwork/setting'; //
final String getDeviceNetworkConfiguration =
'/deviceNetwork/getNetworkInfo'; //
final String roomQueryDateUrl = '/room/queryDate'; //
final String lockDiagnoseUrl = '/room/uploadLockInfo'; //
final String getServerDatetimeUrl = '/check/getServerDatetime'; //

View File

@ -2714,6 +2714,38 @@ class ApiProvider extends BaseProvider {
}),
isUnShowLoading: true,
isShowNetworkErrorMsg: false);
///
Future<Response> settingDeviceNetwork(
int deviceType,
String deviceMac,
String wifiName,
String networkMac,
String secretKey,
String peerId,
) =>
post(
deviceNetworkConfiguration.toUrl,
jsonEncode({
'deviceType': deviceType,
'deviceMac': deviceMac,
'wifiName': wifiName,
'networkMac': networkMac,
'secretKey': secretKey,
'peerId': peerId,
}));
///
Future<Response> getDeviceNetwork(
int deviceType,
String deviceMac,
) =>
post(
getDeviceNetworkConfiguration.toUrl,
jsonEncode({
'deviceType': deviceType,
'deviceMac': deviceMac,
}));
}
extension ExtensionString on String {

View File

@ -12,6 +12,7 @@ import 'package:star_lock/main/lockDetail/electronicKey/massSendElectronicKey/ma
import 'package:star_lock/main/lockDetail/electronicKey/sendEmailNotification/sendEmailNotification_entity.dart';
import 'package:star_lock/main/lockDetail/face/addFace/addFace_entity.dart';
import 'package:star_lock/main/lockDetail/fingerprint/fingerprintList/fingerprint_entity.dart';
import 'package:star_lock/main/lockDetail/lockDetail/device_network_info.dart';
import 'package:star_lock/main/lockDetail/lockSet/basicInformation/basicInformation/KeyDetailEntity.dart';
import 'package:star_lock/main/lockDetail/lockSet/lockEscalation/updateLockInfo_entity.dart';
import 'package:star_lock/main/lockDetail/lockSet/lockEscalation/version_entity.dart';
@ -2712,4 +2713,30 @@ class ApiRepository {
return LoginEntity.fromJson(res.body);
}
//
Future<LoginEntity> settingDeviceNetwork({
required int deviceType,
required String deviceMac,
required String wifiName,
required String networkMac,
required String secretKey,
required String peerId,
}) async {
final res = await apiProvider.settingDeviceNetwork(
deviceType, deviceMac, wifiName, networkMac, secretKey, peerId);
return LoginEntity.fromJson(res.body);
}
//
Future<DeviceNetwork> getDeviceNetwork({
required int deviceType,
required String deviceMac,
}) async {
final res = await apiProvider.getDeviceNetwork(
deviceType,
deviceMac,
);
return DeviceNetwork.fromJson(res.body);
}
}

View File

@ -1,6 +1,7 @@
enum TalkStatus {
none, //
waitingAnswer, //
proactivelyCallWaitingAnswer, //
passiveCallWaitingAnswer, //
answeredSuccessfully, //
waitingData, //
hangingUpDuring, //

View File

@ -5,6 +5,7 @@ import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:star_lock/appRouters.dart';
import 'package:star_lock/app_settings/app_settings.dart';
import 'package:star_lock/blue/reciver_data.dart';
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
@ -25,10 +26,8 @@ class UdpBlePassThroughHandler extends ScpMessageBaseHandle
@override
void handleResp(ScpMessage scpMessage) {
final BleResp bleResp = scpMessage.Payload;
//
// if (bleResp.status == BleResp_StatusE.SUCCESS) {
AppLog.log('收到蓝牙消息回复:${bleResp.structData}');
// }
AppLog.log('收到蓝牙消息回复:${bleResp.structData}');
final data = CommandReciverManager.parseData(bleResp.structData);
}
@override

View File

@ -32,7 +32,7 @@ class UdpTalkDataHandler extends ScpMessageBaseHandle
@override
void handleRealTimeData(ScpMessage scpMessage) {
//
// talkDataOverTimeTimerManager.renew();
talkDataOverTimeTimerManager.renew();
if (scpMessage.Payload != null) {
final TalkData talkData = scpMessage.Payload;
//

View File

@ -5,6 +5,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
import 'package:star_lock/talk/startChart/constant/talk_status.dart';
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
@ -37,10 +38,22 @@ class UdpTalkExpectHandler extends ScpMessageBaseHandle
// print('收到预期音视频数据回复,scpMessage:$scpMessage');
//
startChartManage.stopTalkExpectMessageTimer();
//
startChartManage.stopCallRequestMessageTimer();
talkViewState.rotateAngle.value = talkExpectResp.rotate ?? 0;
//
// x秒内没有收到通话保持则执行的操作;
talkePingOverTimeTimerManager.start();
//
talkDataOverTimeTimerManager.start();
if (talkStatus.status == TalkStatus.proactivelyCallWaitingAnswer) {
//
stopRingtone();
//
talkStatus.setAnsweredSuccessfully();
// ping
startChartManage.startTalkPingMessageTimer();
}
}
}

View File

@ -24,20 +24,26 @@ class UdpTalkHangUpHandler extends ScpMessageBaseHandle
replySuccessMessage(scpMessage);
talkStatus.setHangingUpDuring();
stopRingtone();
StartChartManage().stopTalkExpectMessageTimer();
StartChartManage().stopTalkPingMessageTimer();
startChartManage.stopTalkExpectMessageTimer();
startChartManage.stopTalkPingMessageTimer();
//
talkeRequestOverTimeTimerManager.cancel();
talkePingOverTimeTimerManager.cancel();
talkDataOverTimeTimerManager.cancel();
}
@override
void handleResp(ScpMessage scpMessage) {
talkStatus.setHangingUpDuring();
stopRingtone();
startChartManage.stopTalkExpectMessageTimer();
startChartManage.stopTalkPingMessageTimer();
//
talkeRequestOverTimeTimerManager.renew();
talkeRequestOverTimeTimerManager.cancel();
talkePingOverTimeTimerManager.renew();
talkePingOverTimeTimerManager.cancel();
talkDataOverTimeTimerManager.cancel();
}
@override

View File

@ -22,10 +22,15 @@ class UdpTalkRejectHandler extends ScpMessageBaseHandle
replySuccessMessage(scpMessage);
//
stopRingtone();
StartChartManage().stopTalkExpectMessageTimer();
StartChartManage().stopTalkPingMessageTimer();
startChartManage.stopTalkPingMessageTimer();
startChartManage.stopTalkExpectMessageTimer();
//
talkStatus.setRejected();
//
talkeRequestOverTimeTimerManager.cancel();
talkePingOverTimeTimerManager.cancel();
talkDataOverTimeTimerManager.cancel();
}
@override
@ -35,10 +40,9 @@ class UdpTalkRejectHandler extends ScpMessageBaseHandle
stopRingtone();
//
talkeRequestOverTimeTimerManager.renew();
talkeRequestOverTimeTimerManager.cancel();
talkePingOverTimeTimerManager.renew();
talkePingOverTimeTimerManager.cancel();
talkDataOverTimeTimerManager.cancel();
}
@override

View File

@ -24,26 +24,29 @@ class UdpTalkRequestHandler extends ScpMessageBaseHandle
replySuccessMessage(scpMessage);
//
final loginData = await Storage.getLoginData();
if (loginData == null ||
talkStatus.status == TalkStatus.waitingAnswer ||
talkStatus.status == TalkStatus.answeredSuccessfully) {
//
return;
if (loginData != null &&
talkStatus.status != TalkStatus.passiveCallWaitingAnswer) {
//
final TalkReq talkReq = scpMessage.Payload;
startChartManage.FromPeerId = scpMessage.ToPeerId!;
startChartManage.ToPeerId = scpMessage.FromPeerId!;
//
_talkRequestEvent(talkObjectName: talkReq.callerName);
}
//
final TalkReq talkReq = scpMessage.Payload;
startChartManage.FromPeerId = scpMessage.ToPeerId!;
startChartManage.ToPeerId = scpMessage.FromPeerId!;
//
_talkRequestEvent(talkObjectName: talkReq.callerName);
}
@override
void handleResp(ScpMessage scpMessage) {
//
final GenericResp genericResp = scpMessage.Payload;
if (genericResp.code == 0) {
print('发送对讲成功,已经收到对方的回复');
if (checkGenericRespSuccess(genericResp)) {
//
startChartManage.FromPeerId = scpMessage.ToPeerId!;
startChartManage.ToPeerId = scpMessage.FromPeerId!;
//
startChartManage.startTalkExpectTimer();
//
startChartManage.stopCallRequestMessageTimer();
}
}
@ -62,7 +65,7 @@ class UdpTalkRequestHandler extends ScpMessageBaseHandle
//
_showTalkRequestNotification(talkObjectName: talkObjectName);
//
talkStatus.setWaitingAnswer();
talkStatus.setPassiveCallWaitingAnswer();
//
talkeRequestOverTimeTimerManager.start();
//

View File

@ -2,12 +2,12 @@ import 'dart:async';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:star_lock/talk/other/audio_player_manager.dart';
import 'package:star_lock/talk/startChart/constant/talk_constant.dart';
import 'package:star_lock/talk/startChart/constant/talk_status.dart';
import 'package:star_lock/talk/startChart/start_chart_manage.dart';
import 'package:star_lock/talk/startChart/status/start_chart_talk_status.dart';
class TalkDataOverTimeTimerManager {
//
static final TalkDataOverTimeTimerManager _instance =
@ -29,22 +29,24 @@ class TalkDataOverTimeTimerManager {
//
static void _handleTalkeDataOverTime() {
EasyLoading.showToast('通话连接失败', duration: 2000.milliseconds);
//
StartChartManage().sendTalkHangupMessage();
StartChartManage().stopTalkPingMessageTimer();
StartChartManage().stopTalkExpectMessageTimer();
talkStatus.setNotTalkData();
talkStatus.setEnd();
AudioPlayerManager().stopRingtone();
}
//
void start() {
_timer = Timer(timeout, onTimeout);
_timer ??= Timer(timeout, onTimeout);
}
//
void renew() {
_timer?.cancel();
_timer = null;
start();
}
//

View File

@ -27,7 +27,8 @@ class TalkeRequestOverTimeTimerManager {
//
static void _handleTalkeRequestOverTime() {
if (talkStatus.status == TalkStatus.waitingAnswer) {
if (talkStatus.status == TalkStatus.passiveCallWaitingAnswer ||
talkStatus.status == TalkStatus.proactivelyCallWaitingAnswer) {
EasyLoading.showToast('通话未接通,以挂断', duration: 2000.milliseconds);
//
StartChartManage().sendTalkRejectMessage();

View File

@ -1,6 +1,9 @@
import 'dart:async';
import 'package:fixnum/fixnum.dart';
import 'dart:io';
import 'package:fixnum/fixnum.dart';
import 'package:get/get.dart';
import 'package:star_lock/appRouters.dart';
import 'package:star_lock/app_settings/app_settings.dart';
import 'package:star_lock/flavors.dart';
import 'package:star_lock/login/login/entity/LoginData.dart';
@ -69,6 +72,7 @@ class StartChartManage {
String ToPeerId = ''; // ID
String FromPeerId = ''; // ID
String lockPeerId = '';
// echo测试peer对端
final String echoPeerId = '3phX8Ng2cZHz5NtP8xAf6nYy2z1BYytoejgjoHrWMGhH';
@ -82,6 +86,8 @@ class StartChartManage {
int _defaultIntervalTime = 1; // (s)
Timer? talkDataTimer; //
Timer? rbcuInfoTimer; // p2p地址交换定时器
Timer? talkRequestTimer; //
final int maxAttempts = 15; //
final int _maxPayloadSize = 8 * 1024; //
@ -300,12 +306,35 @@ class StartChartManage {
await _sendMessage(message: message);
}
///
void startCallRequestMessageTimer({required String ToPeerId}) async {
//
if (talkStatus.status != TalkStatus.proactivelyCallWaitingAnswer) {
//
AudioPlayerManager().playRingtone();
Get.toNamed(
Routers.starChartTalkView,
);
}
talkRequestTimer ??= Timer.periodic(
Duration(
seconds: _defaultIntervalTime,
),
(Timer timer) async {
await sendCallRequestMessage(ToPeerId: ToPeerId);
},
);
talkStatus.setProactivelyCallWaitingAnswer();
}
///
void stopCallRequestMessageTimer() async {
talkRequestTimer?.cancel();
talkRequestTimer = null;
}
//
Future<void> sendCallRequestMessage({required String ToPeerId}) async {
if (talkStatus.status == TalkStatus.answeredSuccessfully) {
_log(text: '已经在通话中,请勿重复发送对讲请求');
return;
}
// 线
final message = MessageCommand.talkRequestMessage(
FromPeerId: FromPeerId,
@ -432,10 +461,6 @@ class StartChartManage {
//
void sendTalkRejectMessage() async {
if (talkStatus.status != TalkStatus.waitingAnswer) {
_log(text: '当前未处于等待接听状态, 无法发送拒绝接听消息');
return;
}
final message = MessageCommand.talkRejectMessage(
ToPeerId: ToPeerId,
FromPeerId: FromPeerId,
@ -450,8 +475,11 @@ class StartChartManage {
//
stopTalkExpectMessageTimer();
stopTalkPingMessageTimer();
stopCallRequestMessageTimer();
//
talkePingOverTimeTimerManager.cancel();
talkDataOverTimeTimerManager.cancel();
}
//
@ -508,10 +536,6 @@ class StartChartManage {
//
Future<void> sendTalkHangupMessage() async {
if (talkStatus.status != TalkStatus.answeredSuccessfully) {
_log(text: '当前未处于接听状态, 无法发送通话中挂断消息');
return;
}
final message = MessageCommand.talkHangupMessage(
ToPeerId: ToPeerId,
FromPeerId: FromPeerId,
@ -526,8 +550,10 @@ class StartChartManage {
//
stopTalkExpectMessageTimer();
stopTalkPingMessageTimer();
stopCallRequestMessageTimer();
//
talkePingOverTimeTimerManager.cancel();
talkDataOverTimeTimerManager.cancel();
}
// 线

View File

@ -38,7 +38,8 @@ class StartChartTalkStatus {
}
//
void setWaitingAnswer() => _setStatus(TalkStatus.waitingAnswer);
void setPassiveCallWaitingAnswer() => _setStatus(TalkStatus.passiveCallWaitingAnswer);
void setProactivelyCallWaitingAnswer() => _setStatus(TalkStatus.proactivelyCallWaitingAnswer);
void setWaitingData() => _setStatus(TalkStatus.waitingData);

View File

@ -40,7 +40,7 @@ import '../../../../tools/baseGetXController.dart';
class TalkViewLogic extends BaseGetXController {
final TalkViewState state = TalkViewState();
final LockDetailState lockDetailState = Get.find<LockDetailLogic>().state;
final LockDetailState lockDetailState = Get.put(LockDetailLogic()).state;
Timer? _syncTimer; //
int _startTime = 0; //
final int bufferSize = 20; //

View File

@ -280,7 +280,8 @@ class _TalkViewPageState extends State<TalkViewPage>
logic.stopProcessingAudio();
},
onClick: () async {
if (state.talkStatus.value == TalkStatus.waitingAnswer) {
if (state.talkStatus.value ==
TalkStatus.passiveCallWaitingAnswer) {
//
logic.initiateAnswerCommand();
}
@ -298,12 +299,12 @@ class _TalkViewPageState extends State<TalkViewPage>
'开锁',
AppColors.mainColor,
onClick: () {
if (UDPManage().remoteUnlock == 1) {
// if (UDPManage().remoteUnlock == 1) {
logic.udpOpenDoorAction();
// showDeletPasswordAlertDialog(context);
} else {
logic.showToast('请在锁设置中开启远程开锁'.tr);
}
// } else {
// logic.showToast('请在锁设置中开启远程开锁'.tr);
// }
},
)
]);
@ -311,9 +312,10 @@ class _TalkViewPageState extends State<TalkViewPage>
String getAnswerBtnImg() {
switch (state.talkStatus.value) {
case TalkStatus.waitingAnswer:
case TalkStatus.passiveCallWaitingAnswer:
return 'images/main/icon_lockDetail_monitoringAnswerCalls.png';
case TalkStatus.answeredSuccessfully:
case TalkStatus.proactivelyCallWaitingAnswer:
return 'images/main/icon_lockDetail_monitoringUnTalkback.png';
default:
return 'images/main/icon_lockDetail_monitoringAnswerCalls.png';
@ -322,8 +324,9 @@ class _TalkViewPageState extends State<TalkViewPage>
String getAnswerBtnName() {
switch (state.talkStatus.value) {
case TalkStatus.waitingAnswer:
case TalkStatus.passiveCallWaitingAnswer:
return '接听'.tr;
case TalkStatus.proactivelyCallWaitingAnswer:
case TalkStatus.answeredSuccessfully:
return '长按说话'.tr;
default:

View File

@ -33,6 +33,7 @@ const String automaticLockOffTime = 'automaticLockOffTime'; //自动关锁时间
const String associationUrl = 'associationUrl'; //ios跳转微信的 url
const String starChartRegisterNodeInfo = 'starChartRegisterNodeInfo'; //
const String relayInfo = 'relayInfo'; //
const String lockNetWorkInfo = 'lockNetWorkInfo'; //
class Storage {
factory Storage() => _instance;
@ -273,6 +274,23 @@ class Storage {
await Storage.setString(relayInfo, jsonEncode(relayInfoEntity));
}
//
static Future<void> saveLockNetWorkInfo(Map<String, dynamic> info) async {
await Storage.setString(lockNetWorkInfo, json.encode(info));
}
//
static Future<Map<String, dynamic>?> getLockNetWorkInfo() async {
Map<String, dynamic>? info = null;
final String? data = await Storage.getString(lockNetWorkInfo);
if (data == null || data.isEmpty) {
return null;
}
// JSON Map
info = json.decode(data);
return info;
}
//
static Future<RelayInfoEntity?> getRelayInfo() async {
RelayInfoEntity? relayInfoEntity;

View File

@ -261,6 +261,8 @@ dependencies:
#图库保存
gallery_saver: ^2.3.2
fixnum: ^1.1.1
# 获取视频封面
video_thumbnail: ^0.5.3