调试协议

This commit is contained in:
魏少阳 2023-09-04 15:00:42 +08:00
parent c84a03dad5
commit 87ac11f3f9
26 changed files with 1537 additions and 34 deletions

View File

@ -40,7 +40,7 @@
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"

View File

@ -241,11 +241,29 @@ class BlueManage{
// }
// ,
var allData = <int>[];
_subScribeToCharacteristic(QualifiedCharacteristic characteristic) {
_flutterReactiveBle!.subscribeToCharacteristic(characteristic).listen((data) {
// code to handle incoming data
print("subscribeToCharacteristic: deviceId = ${characteristic.deviceId} characteristicId =${characteristic.characteristicId}---上报来的数据data = $data");
CommandReciverManager.appDataReceive(data);
var dataLen = data[8] * 256 + data[9];// 16
if((data[0] != 0xEF)&&(data[1] != 0x01)&&(data[2] != 0xEE)&&(data[3] != 0x02)){
//
allData.addAll(data);
}else{
allData = <int>[];
//
if(dataLen > (data.length - 12)){
// ,
allData.addAll(data);
return;
}else{
//
allData = data;
}
}
CommandReciverManager.appDataReceive(allData);
}, onError: (dynamic error) {
EasyLoading.dismiss();
print("subscribeToCharacteristic error:$error");

View File

@ -0,0 +1,81 @@
import 'dart:convert';
import '../io_tool/io_tool.dart';
import '../sm4Encipher/sm4.dart';
import '../io_reply.dart';
import '../io_sender.dart';
import '../io_type.dart';
import 'package:crypto/crypto.dart' as crypto;
//TODO:
class AutomaticPadlockCommand extends SenderProtocol {
String? lockID;
String? userID;
int? autoLockFlag;
List<int>? token;
int? needAuthor;
List<int>? signKey;
List<int>? privateKey;
AutomaticPadlockCommand({
this.lockID,
this.userID,
this.autoLockFlag,
this.token,
this.needAuthor,
this.signKey,
this.privateKey
}) : super(CommandType.generalExtendedCommond);
@override
List<int> messageDetail() {
List<int> data = [];
List<int> subData = [];
List<int> ebcData = [];
//
int type = commandType!.typeValue;
double typeDouble = type / 256;
int type1 = typeDouble.toInt();
int type2 = type % 256;
data.add(type1);
data.add(type2);
//
data.add(4);
//lockID 40
int lockIDLength = utf8.encode(lockID!).length;
subData.addAll(utf8.encode(lockID!));
subData = getFixedLengthList(subData, 40 - lockIDLength);
//userID useid 20
int userIDLength = utf8.encode(userID!).length;
print("openDoorUserId:${utf8.encode(userID!)} utf8.encode(userID!).length:${utf8.encode(userID!).length}");
subData.addAll(utf8.encode(userID!));
subData = getFixedLengthList(subData, 20 - userIDLength);
// autoLockFlag 01
subData.add(autoLockFlag!);
data.add(subData.length);
data.addAll(subData);
print("data:$data data.length:${data.length} (data.length % 16):${(data.length % 16)}");
if ((data.length % 16) != 0) {
int add = (16 - data.length % 16);
for (int i = 0; i < add; i++) {
data.add(0);
}
}
print("${commandType!.typeName} SM4Data:$data");
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
return ebcData;
}
}
class AutomaticPadlockReply extends Reply {
AutomaticPadlockReply.parseData(CommandType commandType, List<int> dataDetail)
: super.parseData(commandType, dataDetail) {
data = dataDetail;
}
}

View File

@ -0,0 +1,119 @@
//TODO:
import 'dart:convert';
import '../io_reply.dart';
import '../io_sender.dart';
import '../io_tool/io_tool.dart';
import '../io_type.dart';
import '../sm4Encipher/sm4.dart';
import 'package:crypto/crypto.dart' as crypto;
class SenderCheckingCardStatusCommand extends SenderProtocol {
String? keyID;
String? userID;
int? role;
int? cardCount;
int? cardNo;
List<int>? token;
int? needAuthor;
List<int>? publicKey;
List<int>? privateKey;
SenderCheckingCardStatusCommand({
this.keyID,
this.userID,
this.role,
this.cardCount,
this.cardNo,
this.token,
this.needAuthor,
this.publicKey,
this.privateKey,
}) : super(CommandType.generalExtendedCommond);
@override
List<int> messageDetail() {
List<int> data = [];
List<int> subData = [];
List<int> ebcData = [];
//
int type = commandType!.typeValue;
double typeDouble = type / 256;
int type1 = typeDouble.toInt();
int type2 = type % 256;
data.add(type1);
data.add(type2);
//
data.add(20);
// keyID 40
int keyIDLength = utf8.encode(keyID!).length;
subData.addAll(utf8.encode(keyID!));
subData = getFixedLengthList(subData, 40 - keyIDLength);
//userID 20
int userIDLength = utf8.encode(userID!).length;
subData.addAll(utf8.encode(userID!));
subData = getFixedLengthList(subData, 20 - userIDLength);
// role
subData.add(role!);
// CardCount
subData.add(cardCount!);
// CardNo
subData.add(cardNo!);
if(needAuthor == 0){
//AuthCodeLen 1
subData.add(0);
} else {
List<int> authCodeData = [];
//authUserID
authCodeData.addAll(utf8.encode(userID!));
//KeyID
authCodeData.addAll(utf8.encode(keyID!));
//token 4 Token 0
authCodeData.addAll(token!);
authCodeData.addAll(publicKey!);
print("${commandType!.typeValue}-authCodeData:$authCodeData");
// KeyIDauthUserIDmd5加密之后就是authCode
var authCode = crypto.md5.convert(authCodeData);
subData.add(authCode.bytes.length);
subData.addAll(authCode.bytes);
}
data.add(subData.length);
data.addAll(subData);
if ((data.length % 16) != 0) {
int add = (16 - data.length % 16);
for (int i = 0; i < add; i++) {
data.add(0);
}
}
print("${commandType!.typeName} SM4Data:$data");
// LockId进行SM4 ECB加密 key:544d485f633335373034383064613864
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
return ebcData;
}
}
class SenderCheckingCardStatusReply extends Reply {
SenderCheckingCardStatusReply.parseData(CommandType commandType, List<int> dataDetail)
: super.parseData(commandType, dataDetail) {
data = dataDetail;
}
}

View File

@ -57,6 +57,19 @@ class OpenLockCommand extends SenderProtocol {
// OpenTime 4
int? d1 = openTime;
// var testData = [];
// testData.add((d1! & 0xff000000) >> 24);
// testData.add((d1 & 0xff0000) >> 16);
// testData.add((d1 & 0xff00) >> 8);
// testData.add((d1 & 0xff));
//
// int value = (
// (0xff & testData[(0)]) << 24 |
// (0xff & testData[1]) << 16 |
// (0xff & testData[2]) << 8 |
// (0xFF & testData[3]));
// print("d1:$d1 testData:$testData value$value");
data.add((d1! & 0xff000000) >> 24);
data.add((d1 & 0xff0000) >> 16);
data.add((d1 & 0xff00) >> 8);

View File

@ -0,0 +1,119 @@
//TODO:
import 'dart:convert';
import '../io_reply.dart';
import '../io_sender.dart';
import '../io_tool/io_tool.dart';
import '../io_type.dart';
import '../sm4Encipher/sm4.dart';
import 'package:crypto/crypto.dart' as crypto;
class SenderQueryingFingerprintStatusCommand extends SenderProtocol {
String? keyID;
String? userID;
int? role;
int? fingerCount;
int? fingerNo;
List<int>? token;
int? needAuthor;
List<int>? publicKey;
List<int>? privateKey;
SenderQueryingFingerprintStatusCommand({
this.keyID,
this.userID,
this.role,
this.fingerCount,
this.fingerNo,
this.token,
this.needAuthor,
this.publicKey,
this.privateKey,
}) : super(CommandType.generalExtendedCommond);
@override
List<int> messageDetail() {
List<int> data = [];
List<int> subData = [];
List<int> ebcData = [];
//
int type = commandType!.typeValue;
double typeDouble = type / 256;
int type1 = typeDouble.toInt();
int type2 = type % 256;
data.add(type1);
data.add(type2);
//
data.add(30);
// keyID 40
int keyIDLength = utf8.encode(keyID!).length;
subData.addAll(utf8.encode(keyID!));
subData = getFixedLengthList(subData, 40 - keyIDLength);
//userID 20
int userIDLength = utf8.encode(userID!).length;
subData.addAll(utf8.encode(userID!));
subData = getFixedLengthList(subData, 20 - userIDLength);
// role
subData.add(role!);
// fingerCount
subData.add(fingerCount!);
// FingerNo
subData.add(fingerNo!);
if(needAuthor == 0){
//AuthCodeLen 1
subData.add(0);
} else {
List<int> authCodeData = [];
//authUserID
authCodeData.addAll(utf8.encode(userID!));
//KeyID
authCodeData.addAll(utf8.encode(keyID!));
//token 4 Token 0
authCodeData.addAll(token!);
authCodeData.addAll(publicKey!);
print("${commandType!.typeValue}-authCodeData:$authCodeData");
// KeyIDauthUserIDmd5加密之后就是authCode
var authCode = crypto.md5.convert(authCodeData);
subData.add(authCode.bytes.length);
subData.addAll(authCode.bytes);
}
data.add(subData.length);
data.addAll(subData);
if ((data.length % 16) != 0) {
int add = (16 - data.length % 16);
for (int i = 0; i < add; i++) {
data.add(0);
}
}
print("${commandType!.typeName} SM4Data:$data");
// LockId进行SM4 ECB加密 key:544d485f633335373034383064613864
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
return ebcData;
}
}
class SenderQueryingFingerprintStatusReply extends Reply {
SenderQueryingFingerprintStatusReply.parseData(CommandType commandType, List<int> dataDetail)
: super.parseData(commandType, dataDetail) {
data = dataDetail;
}
}

View File

@ -0,0 +1,117 @@
//TODO:()
import 'dart:convert';
import '../io_reply.dart';
import '../io_sender.dart';
import '../io_tool/io_tool.dart';
import '../io_type.dart';
import '../sm4Encipher/sm4.dart';
import 'package:crypto/crypto.dart' as crypto;
class SenderReferEventRecordNumberCommand extends SenderProtocol {
String? keyID;
String? userID;
int? logsCount;
int? logsNo;
List<int>? token;
int? needAuthor;
List<int>? publicKey;
List<int>? privateKey;
SenderReferEventRecordNumberCommand({
this.keyID,
this.userID,
this.logsCount,
this.logsNo,
this.token,
this.needAuthor,
this.publicKey,
this.privateKey,
}) : super(CommandType.generalExtendedCommond);
@override
List<int> messageDetail() {
List<int> data = [];
List<int> subData = [];
List<int> ebcData = [];
//
int type = commandType!.typeValue;
double typeDouble = type / 256;
int type1 = typeDouble.toInt();
int type2 = type % 256;
data.add(type1);
data.add(type2);
//
data.add(40);
// keyID 40
int keyIDLength = utf8.encode(keyID!).length;
subData.addAll(utf8.encode(keyID!));
subData = getFixedLengthList(subData, 40 - keyIDLength);
//userID 20
int userIDLength = utf8.encode(userID!).length;
subData.addAll(utf8.encode(userID!));
subData = getFixedLengthList(subData, 20 - userIDLength);
// logsCount
subData.add(logsCount!);
// logsNo
subData.add(logsNo!);
// token
// subData.addAll(token!);
if(needAuthor == 0){
//AuthCodeLen 1
subData.add(0);
} else {
List<int> authCodeData = [];
//authUserID
authCodeData.addAll(utf8.encode(userID!));
//KeyID
authCodeData.addAll(utf8.encode(keyID!));
//token 4 Token 0
authCodeData.addAll(token!);
authCodeData.addAll(publicKey!);
print("${commandType!.typeValue}-authCodeData:$authCodeData");
// KeyIDauthUserIDmd5加密之后就是authCode
var authCode = crypto.md5.convert(authCodeData);
subData.add(authCode.bytes.length);
subData.addAll(authCode.bytes);
}
data.add(subData.length);
data.addAll(subData);
if ((data.length % 16) != 0) {
int add = (16 - data.length % 16);
for (int i = 0; i < add; i++) {
data.add(0);
}
}
print("${commandType!.typeName} SM4Data:$data");
// LockId进行SM4 ECB加密 key:544d485f633335373034383064613864
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
return ebcData;
}
}
class SenderReferEventRecordNumberReply extends Reply {
SenderReferEventRecordNumberReply.parseData(CommandType commandType, List<int> dataDetail)
: super.parseData(commandType, dataDetail) {
data = dataDetail;
}
}

View File

@ -0,0 +1,120 @@
//TODO:()
import 'dart:convert';
import '../io_reply.dart';
import '../io_sender.dart';
import '../io_tool/io_tool.dart';
import '../io_type.dart';
import '../sm4Encipher/sm4.dart';
import 'package:crypto/crypto.dart' as crypto;
class SenderReferEventRecordNumberTimeCommand extends SenderProtocol {
String? keyID;
String? userID;
int? logsCount;
int? time;
List<int>? token;
int? needAuthor;
List<int>? publicKey;
List<int>? privateKey;
SenderReferEventRecordNumberTimeCommand({
this.keyID,
this.userID,
this.logsCount,
this.time,
this.token,
this.needAuthor,
this.publicKey,
this.privateKey,
}) : super(CommandType.generalExtendedCommond);
@override
List<int> messageDetail() {
List<int> data = [];
List<int> subData = [];
List<int> ebcData = [];
//
int type = commandType!.typeValue;
double typeDouble = type / 256;
int type1 = typeDouble.toInt();
int type2 = type % 256;
data.add(type1);
data.add(type2);
//
data.add(41);
// keyID 40
int keyIDLength = utf8.encode(keyID!).length;
subData.addAll(utf8.encode(keyID!));
subData = getFixedLengthList(subData, 40 - keyIDLength);
//userID 20
int userIDLength = utf8.encode(userID!).length;
subData.addAll(utf8.encode(userID!));
subData = getFixedLengthList(subData, 20 - userIDLength);
// logsCount
subData.add(logsCount!);
// time
subData.add((time! & 0xff000000) >> 24);
subData.add((time! & 0xff0000) >> 16);
subData.add((time! & 0xff00) >> 8);
subData.add((time! & 0xff));
// token
// subData.addAll(token!);
if(needAuthor == 0){
//AuthCodeLen 1
subData.add(0);
} else {
List<int> authCodeData = [];
//authUserID
authCodeData.addAll(utf8.encode(userID!));
//KeyID
authCodeData.addAll(utf8.encode(keyID!));
//token 4 Token 0
authCodeData.addAll(token!);
authCodeData.addAll(publicKey!);
print("${commandType!.typeValue}-authCodeData:$authCodeData");
// KeyIDauthUserIDmd5加密之后就是authCode
var authCode = crypto.md5.convert(authCodeData);
subData.add(authCode.bytes.length);
subData.addAll(authCode.bytes);
}
data.add(subData.length);
data.addAll(subData);
if ((data.length % 16) != 0) {
int add = (16 - data.length % 16);
for (int i = 0; i < add; i++) {
data.add(0);
}
}
print("${commandType!.typeName} SM4Data:$data");
// LockId进行SM4 ECB加密 key:544d485f633335373034383064613864
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
return ebcData;
}
}
class SenderReferEventRecordNumberTimeReply extends Reply {
SenderReferEventRecordNumberTimeReply.parseData(CommandType commandType, List<int> dataDetail)
: super.parseData(commandType, dataDetail) {
data = dataDetail;
}
}

View File

@ -24,7 +24,7 @@ class TimingCommand extends SenderProtocol {
this.needAuthor,
this.signKey,
this.privateKey
}) : super(CommandType.openLock);
}) : super(CommandType.calibrationTime);
@override
List<int> messageDetail() {
@ -52,6 +52,7 @@ class TimingCommand extends SenderProtocol {
// nowTime 4
int? d1 = nowTime;
print("timing d1:$d1");
data.add((d1! & 0xff000000) >> 24);
data.add((d1 & 0xff0000) >> 16);
data.add((d1 & 0xff00) >> 8);

View File

@ -14,9 +14,13 @@ import 'package:star_lock/blue/io_protocol/io_transferPermissions.dart';
import '../tools/storage.dart';
import 'io_protocol/io_addFingerprint.dart';
import 'io_protocol/io_addUser.dart';
import 'io_protocol/io_automaticPadlock.dart';
import 'io_protocol/io_checkingCardStatus.dart';
import 'io_protocol/io_getPrivateKey.dart';
import 'io_protocol/io_getPublicKey.dart';
import 'io_protocol/io_openLock.dart';
import 'io_protocol/io_queryingFingerprintStatus.dart';
import 'io_protocol/io_referEventRecordNumber.dart';
import 'io_reply.dart';
import 'io_protocol/io_senderCustomPasswords.dart';
import 'io_type.dart';
@ -32,15 +36,17 @@ class CommandReciverManager {
if(data.isEmpty){
return;
}
int data_size = data.length;
int dataSize = data.length;
// 13
if(data_size < 13){
if(dataSize < 13){
return;
}
// print("appDataReceiveData:$data"); // &&(data[4] == 0x11)
print("appDataReceiveData:$data"); // &&(data[4] == 0x11)
if((data[0] == 0xEF)&&(data[1] == 0x01)&&(data[2] == 0xEE)&&(data[3] == 0x02)){
var tmpType = (data[7] & 0x0f);//
print("temType:$tmpType");
var dataLen = data[8] * 256 + data[9];// 16
var oriLen = data[10] * 256 + data[11];// 16
print("dataLen:$dataLen oriLen:$oriLen");
@ -162,6 +168,24 @@ class CommandReciverManager {
reply = SenderCustomPasswordsReply.parseData(commandType, data);
}
break;
case 4:
{
//
reply = AutomaticPadlockReply.parseData(commandType, data);
}
break;
case 20:
{
//
reply = SenderCheckingCardStatusReply.parseData(commandType, data);
}
break;
case 30:
{
//
reply = SenderQueryingFingerprintStatusReply.parseData(commandType, data);
}
break;
case 31:
{
//
@ -180,6 +204,12 @@ class CommandReciverManager {
reply = SenderAddFingerprintProcessReply.parseData(commandType, data);
}
break;
case 40:
{
//
reply = SenderReferEventRecordNumberReply.parseData(commandType, data);
}
break;
}
}
break;

View File

@ -4,12 +4,18 @@ import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart';
import 'io_protocol/io_addFingerprint.dart';
import 'io_protocol/io_addUser.dart';
import 'io_protocol/io_automaticPadlock.dart';
import 'io_protocol/io_checkingCardStatus.dart';
import 'io_protocol/io_editUser.dart';
import 'io_protocol/io_factoryDataReset.dart';
import 'io_protocol/io_getPrivateKey.dart';
import 'io_protocol/io_getPublicKey.dart';
import 'io_protocol/io_openLock.dart';
import 'io_protocol/io_queryingFingerprintStatus.dart';
import 'io_protocol/io_referEventRecordNumber.dart';
import 'io_protocol/io_referEventRecordNumberTime.dart';
import 'io_protocol/io_senderCustomPasswords.dart';
import 'io_protocol/io_timing.dart';
import 'io_protocol/io_transferPermissions.dart';
import 'sender_data.dart';
@ -280,4 +286,148 @@ class IoSenderManage {
privateKey: privateKey,
), callBack:callBack);
}
//todo:
static void senderTimingCommand({
required String? lockID,
required String? userID,
required int? nowTime,
required List<int>? token,
required int? needAuthor,
required List<int>? signKey,
required List<int>? privateKey,
CommandSendCallBack? callBack}) {
CommandSenderManager().managerSendData(
command: TimingCommand(
lockID: lockID,
userID: userID,
nowTime: nowTime,
token: token,
needAuthor: needAuthor,
signKey: signKey,
privateKey: privateKey,
), callBack:callBack);
}
//todo:
static void senderAutomaticPadlockCommand({
required String? lockID,
required String? userID,
required int? autoLockFlag,
required List<int>? token,
required int? needAuthor,
required List<int>? signKey,
required List<int>? privateKey,
CommandSendCallBack? callBack}) {
CommandSenderManager().managerSendData(
command: AutomaticPadlockCommand(
lockID: lockID,
userID: userID,
autoLockFlag: autoLockFlag,
token: token,
needAuthor: needAuthor,
signKey: signKey,
privateKey: privateKey,
), callBack:callBack);
}
//todo:()
static void senderReferEventRecordNumberCommand({
required String? keyID,
required String? userID,
required int? logsCount,
required int? logsNo,
required List<int>? token,
required int? needAuthor,
required List<int>? publicKey,
required List<int>? privateKey,
CommandSendCallBack? callBack}) {
CommandSenderManager().managerSendData(
command: SenderReferEventRecordNumberCommand(
keyID: keyID,
userID: userID,
logsCount: logsCount,
logsNo: logsNo,
token: token,
needAuthor: needAuthor,
publicKey: publicKey,
privateKey: privateKey,
), callBack:callBack);
}
//todo:()
static void senderReferEventRecordNumberTimeCommand({
required String? keyID,
required String? userID,
required int? logsCount,
required int? time,
required List<int>? token,
required int? needAuthor,
required List<int>? publicKey,
required List<int>? privateKey,
CommandSendCallBack? callBack}) {
CommandSenderManager().managerSendData(
command: SenderReferEventRecordNumberTimeCommand(
keyID: keyID,
userID: userID,
logsCount: logsCount,
time: time,
token: token,
needAuthor: needAuthor,
publicKey: publicKey,
privateKey: privateKey,
), callBack:callBack);
}
//todo:
static void senderQueryingFingerprintStatusCommand({
required String? keyID,
required String? userID,
required int? role,
required int? fingerCount,
required int? fingerNo,
required List<int>? token,
required int? needAuthor,
required List<int>? publicKey,
required List<int>? privateKey,
CommandSendCallBack? callBack}) {
CommandSenderManager().managerSendData(
command: SenderQueryingFingerprintStatusCommand(
keyID: keyID,
userID: userID,
role: role,
fingerCount: fingerCount,
fingerNo: fingerNo,
token: token,
needAuthor: needAuthor,
publicKey: publicKey,
privateKey: privateKey,
), callBack:callBack);
}
//todo:
static void senderCheckingCardStatusCommand({
required String? keyID,
required String? userID,
required int? role,
required int? cardCount,
required int? cardNo,
required List<int>? token,
required int? needAuthor,
required List<int>? publicKey,
required List<int>? privateKey,
CommandSendCallBack? callBack}) {
CommandSenderManager().managerSendData(
command: SenderCheckingCardStatusCommand(
keyID: keyID,
userID: userID,
role: role,
cardCount: cardCount,
cardNo: cardNo,
token: token,
needAuthor: needAuthor,
publicKey: publicKey,
privateKey: privateKey,
), callBack:callBack);
}
}

View File

@ -0,0 +1,168 @@
import 'dart:async';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import '../../../../blue/blue_manage.dart';
import '../../../../blue/io_protocol/io_automaticPadlock.dart';
import '../../../../blue/io_protocol/io_getLockStatu.dart';
import '../../../../blue/io_reply.dart';
import '../../../../blue/io_tool/io_manager.dart';
import '../../../../blue/io_tool/io_tool.dart';
import '../../../../blue/io_tool/manager_event_bus.dart';
import '../../../../blue/sender_manage.dart';
import '../../../../tools/storage.dart';
import 'automaticBlocking_state.dart';
class AutomaticBlockingLogic extends BaseGetXController{
final AutomaticBlockingState automaticBlockingState = AutomaticBlockingState();
//
late StreamSubscription<Reply> _replySubscription;
void _initReplySubscription() {
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((reply) {
if(reply is AutomaticPadlockReply) {
_replyAutomaticPadlock(reply);
}
//
if(reply is GetLockStatuReply) {
_replyGetLockStatus(reply);
}
});
}
//
Future<void> _replyGetLockStatus(Reply reply) async {
int status = reply.data[2];
switch(status){
case 0x00:
//
print("${reply.commandType}数据解析成功");
//
break;
case 0x06:
//
print("${reply.commandType}需要鉴权");
break;
case 0x07:
//
print("${reply.commandType}用户无权限");
break;
case 0x09:
//
print("${reply.commandType}权限校验错误");
break;
default:
//
print("${reply.commandType}失败");
break;
}
}
//
Future<void> _replyAutomaticPadlock(Reply reply) async {
int status = reply.data[2];
switch(status){
case 0x00:
//
print("${reply.commandType}数据解析成功");
// _getLockStatus();
break;
case 0x06:
//
print("${reply.commandType}需要鉴权");
break;
case 0x07:
//
print("${reply.commandType}用户无权限");
break;
case 0x09:
//
print("${reply.commandType}权限校验错误");
break;
default:
//
print("${reply.commandType}失败");
break;
}
}
//
Future<void> _getLockStatus() async {
//
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
if (state == DeviceConnectionState.connected) {
var privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
IoSenderManage.senderGetLockStatu(
lockID:BlueManage().connectDeviceName,
userID:await Storage.getUid(),
privateKey:getPrivateKeyList,
);
}
});
}
//
Future<void> sendTiming() async {
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
if (state == DeviceConnectionState.connected) {
var privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
var token = await Storage.getStringList(saveBlueToken);
List<int> getTokenList = changeStringListToIntList(token!);
var signKey = await Storage.getStringList(saveBlueSignKey);
List<int> getSignKeyList = changeStringListToIntList(signKey!);
print("automaticBlockingState.isOpen.value:${automaticBlockingState.isOpen.value}");
IoSenderManage.senderAutomaticPadlockCommand(
lockID:BlueManage().connectDeviceName,
userID:await Storage.getUid(),
autoLockFlag:automaticBlockingState.isOpen.value ? 1 : 0,
token:getTokenList,
needAuthor:1,
signKey:getSignKeyList,
privateKey:getPrivateKeyList,
);
}
});
}
@override
void onReady() {
// TODO: implement onReady
super.onReady();
print("onReady()");
_initReplySubscription();
}
@override
void onInit() {
// TODO: implement onInit
super.onInit();
print("onInit()");
_getLockStatus();
}
@override
void onClose() {
// TODO: implement onClose
super.onClose();
_replySubscription.cancel();
}
}

View File

@ -10,6 +10,7 @@ import '../../../../tools/commonItem.dart';
import '../../../../tools/showBottomSheetTool.dart';
import '../../../../tools/titleAppBar.dart';
import '../../../../translations/trans_lib.dart';
import 'automaticBlocking_logic.dart';
class AutomaticBlockingPage extends StatefulWidget {
const AutomaticBlockingPage({Key? key}) : super(key: key);
@ -20,6 +21,8 @@ class AutomaticBlockingPage extends StatefulWidget {
class _AutomaticBlockingPageState extends State<AutomaticBlockingPage> {
final TextEditingController _timeController = TextEditingController();
final logic = Get.put(AutomaticBlockingLogic());
final state = Get.find<AutomaticBlockingLogic>().automaticBlockingState;
@override
Widget build(BuildContext context) {
@ -28,16 +31,27 @@ class _AutomaticBlockingPageState extends State<AutomaticBlockingPage> {
appBar: TitleAppBar(
barTitle: TranslationLoader.lanKeys!.automaticBlocking!.tr,
haveBack: true,
actionsList: [
TextButton(
child: Text(
TranslationLoader.lanKeys!.save!.tr,
style: TextStyle(color: Colors.white, fontSize: 24.sp),
),
onPressed: () {
logic.sendTiming();
},
),
],
backgroundColor: AppColors.mainColor),
body: ListView(
children: [
CommonItem(
Obx(() => CommonItem(
leftTitel: TranslationLoader.lanKeys!.automaticBlocking!.tr,
rightTitle: "",
rightTitle: "${state.automaticBlockingTime}s",
isHaveLine: false,
isHaveRightWidget: true,
rightWidget:
SizedBox(width: 60.w, height: 50.h, child: _switch())),
SizedBox(width: 60.w, height: 50.h, child: _switch())),),
Container(
height: 10.h,
),
@ -49,11 +63,11 @@ class _AutomaticBlockingPageState extends State<AutomaticBlockingPage> {
isHaveDirection: true,
action: () {
var list = [
"5S",
"10S",
"15S",
"30S",
"60S",
"5",
"10",
"15",
"30",
"60",
TranslationLoader.lanKeys!.custom!.tr
];
ShowBottomSheetTool().showSingleRowPicker(
@ -69,14 +83,20 @@ class _AutomaticBlockingPageState extends State<AutomaticBlockingPage> {
//adapter: PickerAdapter(),
data: list,
//
clickCallBack: (int index, var str) {});
clickCallBack: (int index, var str) {
if(index != 5){
state.automaticBlockingTime.value = str.toString();
}else{
state.isCustomLockTime.value = true;
}
});
});
}),
Container(
height: 10.h,
),
Visibility(
visible: true,
Obx(() => Visibility(
visible: state.isCustomLockTime.value,
child: Container(
color: Colors.white,
padding: EdgeInsets.only(
@ -99,9 +119,9 @@ class _AutomaticBlockingPageState extends State<AutomaticBlockingPage> {
decoration: InputDecoration(
//
contentPadding:
const EdgeInsets.only(top: 12.0, bottom: 8.0),
const EdgeInsets.only(top: 12.0, bottom: 8.0),
hintText:
"${TranslationLoader.lanKeys!.pleaseEnter!.tr}${TranslationLoader.lanKeys!.time!.tr}(S)",
"${TranslationLoader.lanKeys!.pleaseEnter!.tr}${TranslationLoader.lanKeys!.time!.tr}(S)",
hintStyle: TextStyle(fontSize: 24.sp),
//线
border: InputBorder.none,
@ -113,7 +133,7 @@ class _AutomaticBlockingPageState extends State<AutomaticBlockingPage> {
),
],
),
)),
))),
Container(
padding: EdgeInsets.all(30.w),
child: Row(
@ -132,15 +152,14 @@ class _AutomaticBlockingPageState extends State<AutomaticBlockingPage> {
}
CupertinoSwitch _switch() {
bool _isOn = false;
return CupertinoSwitch(
activeColor: CupertinoColors.activeBlue,
trackColor: CupertinoColors.systemGrey5,
thumbColor: CupertinoColors.white,
value: _isOn,
value: state.isOpen.value,
onChanged: (value) {
setState(() {
_isOn = value;
state.isOpen.value = value;
});
},
);

View File

@ -0,0 +1,8 @@
import 'package:get/get.dart';
class AutomaticBlockingState {
var isOpen = false.obs;
var automaticBlockingTime = "5".obs;
var isCustomLockTime = false.obs;
}

View File

@ -0,0 +1,183 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import '../../../../blue/blue_manage.dart';
import '../../../../blue/io_protocol/io_getLockStatu.dart';
import '../../../../blue/io_protocol/io_timing.dart';
import '../../../../blue/io_reply.dart';
import '../../../../blue/io_tool/io_manager.dart';
import '../../../../blue/io_tool/io_tool.dart';
import '../../../../blue/io_tool/manager_event_bus.dart';
import '../../../../blue/sender_manage.dart';
import '../../../../tools/baseGetXController.dart';
import '../../../../tools/dateTool.dart';
import '../../../../tools/storage.dart';
import '../../../../tools/toast.dart';
import 'lockTime_state.dart';
class LockTimeLogic extends BaseGetXController{
final LockTimeState state = LockTimeState();
//
late StreamSubscription<Reply> _replySubscription;
void _initReplySubscription() {
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((reply) {
if(reply is TimingReply) {
_replyTiming(reply);
}
//
if(reply is GetLockStatuReply) {
_replyGetLockStatus(reply);
}
});
}
//
Future<void> _replyGetLockStatus(Reply reply) async {
int status = reply.data[2];
switch(status){
case 0x00:
//
print("${reply.commandType}数据解析成功");
//
var lockTime = reply.data.sublist(60, 64);
int value = (
(0xff & lockTime[(0)]) << 24 |
(0xff & lockTime[1]) << 16 |
(0xff & lockTime[2]) << 8 |
(0xFF & lockTime[3]));
String dataEime = DateTool().dateToString("${value}000");
state.dateTime.value = dataEime;
print("lockTime:$lockTime value:$value dataEime:$dataEime");
break;
case 0x06:
//
print("${reply.commandType}需要鉴权");
break;
case 0x07:
//
print("${reply.commandType}用户无权限");
break;
case 0x09:
//
print("${reply.commandType}权限校验错误");
break;
default:
//
print("${reply.commandType}失败");
break;
}
}
//
Future<void> _replyTiming(Reply reply) async {
int status = reply.data[2];
switch(status){
case 0x00:
//
print("${reply.commandType}数据解析成功");
// _getLockStatus();
Toast.show(msg:"锁时间更新成功");
break;
case 0x06:
//
print("${reply.commandType}需要鉴权");
break;
case 0x07:
//
print("${reply.commandType}用户无权限");
break;
case 0x09:
//
print("${reply.commandType}权限校验错误");
break;
default:
//
print("${reply.commandType}失败");
break;
}
}
//
Future<void> _getLockStatus() async {
//
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
if (state == DeviceConnectionState.connected) {
var privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
IoSenderManage.senderGetLockStatu(
lockID:BlueManage().connectDeviceName,
userID:await Storage.getUid(),
privateKey:getPrivateKeyList,
);
}
});
}
//
Future<void> sendTiming() async {
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
if (state == DeviceConnectionState.connected) {
var privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
var token = await Storage.getStringList(saveBlueToken);
List<int> getTokenList = changeStringListToIntList(token!);
var signKey = await Storage.getStringList(saveBlueSignKey);
List<int> getSignKeyList = changeStringListToIntList(signKey!);
IoSenderManage.senderTimingCommand(
lockID:BlueManage().connectDeviceName,
userID:await Storage.getUid(),
nowTime:DateTime.now().millisecondsSinceEpoch~/1000,
token:getTokenList,
needAuthor:1,
signKey:getSignKeyList,
privateKey:getPrivateKeyList,
);
}
});
}
@override
void onReady() {
// TODO: implement onReady
super.onReady();
print("onReady()");
_initReplySubscription();
}
@override
void onInit() {
// TODO: implement onInit
super.onInit();
print("onInit()");
_getLockStatus();
}
@override
void onClose() {
// TODO: implement onClose
super.onClose();
_replySubscription.cancel();
}
}

View File

@ -6,6 +6,7 @@ import '../../../../app_settings/app_colors.dart';
import '../../../../tools/submitBtn.dart';
import '../../../../tools/titleAppBar.dart';
import '../../../../translations/trans_lib.dart';
import 'lockTime_logic.dart';
class LockTimePage extends StatefulWidget {
const LockTimePage({Key? key}) : super(key: key);
@ -15,6 +16,9 @@ class LockTimePage extends StatefulWidget {
}
class _LockTimePageState extends State<LockTimePage> {
final logic = Get.put(LockTimeLogic());
final state = Get.find<LockTimeLogic>().state;
@override
Widget build(BuildContext context) {
return Scaffold(
@ -30,14 +34,14 @@ class _LockTimePageState extends State<LockTimePage> {
SizedBox(
height: 50.h,
),
Row(
Obx(() => Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("2023.07.10 11.47.33",
Text(state.dateTime.value,
style: TextStyle(
fontSize: 26.sp, color: AppColors.blackColor)),
],
),
),),
SizedBox(
height: 60.h,
),
@ -47,7 +51,10 @@ class _LockTimePageState extends State<LockTimePage> {
fontSize: 32.sp,
// margin: EdgeInsets.only(left: 03.w, right: 30.w, top: 20.w),
padding: EdgeInsets.only(top: 20.w, bottom: 20.w),
onClick: () {}),
onClick: () {
print("1111111");
logic.sendTiming();
}),
SizedBox(
height: 40.h,
),

View File

@ -0,0 +1,7 @@
import 'package:get/get.dart';
class LockTimeState{
var dateTime = "".obs;
}

View File

@ -318,17 +318,12 @@ class LockDetailLogic extends BaseGetXController{
List<int> getTokenList = changeStringListToIntList(token!);
print("openDoorTokenPubToken:$getTokenList");
// String? userId = '';
// final data = await Storage.getString('userLoginData');
// if (data != null && data.isNotEmpty) {
// userId = LoginEntity.fromJson(jsonDecode(data)).data!.userid.toString();
// }
// print("userId:$userId");
print("millisecondsSinceEpoch/1000:${DateTime.now().millisecondsSinceEpoch~/1000}");
IoSenderManage.senderOpenLock(
keyID: "1",
userID: await Storage.getUid(),
openMode: 1,
openTime: DateTime.now().millisecondsSinceEpoch,
openTime: DateTime.now().millisecondsSinceEpoch~/1000,
token: getTokenList,
needAuthor: 1,
signKey: signKeyDataList,

View File

@ -0,0 +1,140 @@
import 'dart:async';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import '../../../blue/blue_manage.dart';
import '../../../blue/io_protocol/io_referEventRecordNumber.dart';
import '../../../blue/io_reply.dart';
import '../../../blue/io_tool/io_manager.dart';
import '../../../blue/io_tool/io_tool.dart';
import '../../../blue/io_tool/manager_event_bus.dart';
import '../../../blue/sender_manage.dart';
import '../../../tools/baseGetXController.dart';
import '../../../tools/storage.dart';
import 'lockOperatingRecord_state.dart';
class LockOperatingRecordLogic extends BaseGetXController{
LockOperatingRecordState state = LockOperatingRecordState();
//
late StreamSubscription<Reply> _replySubscription;
void _initReplySubscription() {
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((reply) {
if(reply is SenderReferEventRecordNumberReply) {
_replyReferEventRecordNumber(reply);
}
});
}
//
Future<void> _replyReferEventRecordNumber(Reply reply) async {
int status = reply.data[2];
switch(status){
case 0x00:
//
print("${reply.commandType}数据解析成功");
// _getLockStatus();
break;
case 0x06:
//
print("${reply.commandType}需要鉴权");
break;
case 0x07:
//
print("${reply.commandType}用户无权限");
break;
case 0x09:
//
print("${reply.commandType}权限校验错误");
break;
default:
//
print("${reply.commandType}失败");
break;
}
}
// ()
Future<void> senderReferEventRecordNumber() async {
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
if (state == DeviceConnectionState.connected) {
var privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
var token = await Storage.getStringList(saveBlueToken);
List<int> getTokenList = changeStringListToIntList(token!);
var publicKey = await Storage.getStringList(saveBluePublicKey);
List<int> getPublicKeyList = changeStringListToIntList(publicKey!);
IoSenderManage.senderReferEventRecordNumberCommand(
keyID:BlueManage().connectDeviceName,
userID:await Storage.getUid(),
logsCount:20,
logsNo:1,
token:getTokenList,
needAuthor:1,
publicKey:getPublicKeyList,
privateKey:getPrivateKeyList,
);
}
});
}
// ()
Future<void> senderReferEventRecordNumberTime() async {
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
if (state == DeviceConnectionState.connected) {
var privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
var token = await Storage.getStringList(saveBlueToken);
List<int> getTokenList = changeStringListToIntList(token!);
var publicKey = await Storage.getStringList(saveBluePublicKey);
List<int> getPublicKeyList = changeStringListToIntList(publicKey!);
IoSenderManage.senderReferEventRecordNumberTimeCommand(
keyID:BlueManage().connectDeviceName,
userID:await Storage.getUid(),
logsCount:20,
time:DateTime.now().millisecondsSinceEpoch~/1000,
token:getTokenList,
needAuthor:1,
publicKey:getPublicKeyList,
privateKey:getPrivateKeyList,
);
}
});
}
@override
void onReady() {
// TODO: implement onReady
super.onReady();
print("onReady()");
_initReplySubscription();
}
@override
void onInit() {
// TODO: implement onInit
super.onInit();
print("onInit()");
senderReferEventRecordNumberTime();
}
@override
void onClose() {
// TODO: implement onClose
super.onClose();
_replySubscription.cancel();
}
}

View File

@ -10,6 +10,7 @@ import '../../../app_settings/app_colors.dart';
import '../../../tools/jh_pop_menus.dart';
import '../../../tools/titleAppBar.dart';
import '../../../translations/trans_lib.dart';
import 'lockOperatingRecord_logic.dart';
class LockOperatingRecordPage extends StatefulWidget {
const LockOperatingRecordPage({Key? key}) : super(key: key);
@ -20,6 +21,9 @@ class LockOperatingRecordPage extends StatefulWidget {
}
class _LockOperatingRecordPageState extends State<LockOperatingRecordPage> {
final logic = Get.put(LockOperatingRecordLogic());
final state = Get.find<LockOperatingRecordLogic>().state;
late KeyInfos keyInfo;
late LockMainEntity lockMainEntity;

View File

@ -0,0 +1,4 @@
class LockOperatingRecordState{
}

View File

@ -0,0 +1,181 @@
import 'dart:async';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import '../../../../blue/blue_manage.dart';
import '../../../../blue/io_protocol/io_checkingCardStatus.dart';
import '../../../../blue/io_protocol/io_queryingFingerprintStatus.dart';
import '../../../../blue/io_reply.dart';
import '../../../../blue/io_tool/io_manager.dart';
import '../../../../blue/io_tool/io_tool.dart';
import '../../../../blue/io_tool/manager_event_bus.dart';
import '../../../../blue/sender_manage.dart';
import '../../../../tools/baseGetXController.dart';
import '../../../../tools/storage.dart';
import 'otherTypeKeyList_state.dart';
class OtherTypeKeyListLogic extends BaseGetXController{
OtherTypeKeyListState state = OtherTypeKeyListState();
//
late StreamSubscription<Reply> _replySubscription;
void _initReplySubscription() {
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((reply) {
if(reply is SenderQueryingFingerprintStatusReply) {
//
_replyQueryingFingerprintStatus(reply);
}
if(reply is SenderCheckingCardStatusReply) {
_replyReferEventRecordNumber(reply);
}
});
}
//
Future<void> _replyQueryingFingerprintStatus(Reply reply) async {
int status = reply.data[2];
switch(status){
case 0x00:
//
print("${reply.commandType}数据解析成功");
// _getLockStatus();
break;
case 0x06:
//
print("${reply.commandType}需要鉴权");
break;
case 0x07:
//
print("${reply.commandType}用户无权限");
break;
case 0x09:
//
print("${reply.commandType}权限校验错误");
break;
default:
//
print("${reply.commandType}失败");
break;
}
}
//
Future<void> _replyReferEventRecordNumber(Reply reply) async {
int status = reply.data[2];
switch(status){
case 0x00:
//
print("${reply.commandType}数据解析成功");
// _getLockStatus();
break;
case 0x06:
//
print("${reply.commandType}需要鉴权");
break;
case 0x07:
//
print("${reply.commandType}用户无权限");
break;
case 0x09:
//
print("${reply.commandType}权限校验错误");
break;
default:
//
print("${reply.commandType}失败");
break;
}
}
//
Future<void> senderQueryingFingerprintStatus() async {
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
if (state == DeviceConnectionState.connected) {
var privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
var token = await Storage.getStringList(saveBlueToken);
List<int> getTokenList = changeStringListToIntList(token!);
var publicKey = await Storage.getStringList(saveBluePublicKey);
List<int> getPublicKeyList = changeStringListToIntList(publicKey!);
IoSenderManage.senderQueryingFingerprintStatusCommand(
keyID:BlueManage().connectDeviceName,
userID:await Storage.getUid(),
role:0xff,
fingerCount:20,
fingerNo:1,
token:getTokenList,
needAuthor:1,
publicKey:getPublicKeyList,
privateKey:getPrivateKeyList,
);
}
});
}
//
Future<void> senderCheckingCardStatus() async {
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
if (state == DeviceConnectionState.connected) {
var privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
var token = await Storage.getStringList(saveBlueToken);
List<int> getTokenList = changeStringListToIntList(token!);
var publicKey = await Storage.getStringList(saveBluePublicKey);
List<int> getPublicKeyList = changeStringListToIntList(publicKey!);
IoSenderManage.senderCheckingCardStatusCommand(
keyID:BlueManage().connectDeviceName,
userID:await Storage.getUid(),
role:0xff,
cardCount:20,
cardNo:1,
token:getTokenList,
needAuthor:1,
publicKey:getPublicKeyList,
privateKey:getPrivateKeyList,
);
}
});
}
@override
void onReady() {
// TODO: implement onReady
super.onReady();
print("onReady()");
_initReplySubscription();
}
@override
void onInit() {
// TODO: implement onInit
super.onInit();
print("onInit()");
// senderQueryingFingerprintStatus();
senderCheckingCardStatus();
}
@override
void onClose() {
// TODO: implement onClose
super.onClose();
_replySubscription.cancel();
}
}

View File

@ -7,6 +7,7 @@ import '../../../../app_settings/app_colors.dart';
import '../../../../tools/submitBtn.dart';
import '../../../../tools/titleAppBar.dart';
import '../../../../translations/trans_lib.dart';
import 'otherTypeKeyList_logic.dart';
class OtherTypeKeyListPage extends StatefulWidget {
const OtherTypeKeyListPage({Key? key}) : super(key: key);
@ -16,6 +17,9 @@ class OtherTypeKeyListPage extends StatefulWidget {
}
class _OtherTypeKeyListPageState extends State<OtherTypeKeyListPage> {
final logic = Get.put(OtherTypeKeyListLogic());
final state = Get.find<OtherTypeKeyListLogic>().state;
@override
Widget build(BuildContext context) {
var type = ModalRoute.of(context)?.settings.arguments as int;

View File

@ -0,0 +1,4 @@
class OtherTypeKeyListState{
}

View File

@ -1,4 +1,6 @@
import 'package:date_format/date_format.dart';
class DateTool {
String getNowDateYMDHM(){
@ -21,4 +23,13 @@ class DateTool {
// print("组合 $year-$month-$day $hour:$minute:$millisecond");
return "$year.$month.$day $hour:$minute";
}
String dateToString(String timeDate){
int time = int.parse(timeDate);
DateTime nowDate = DateTime.fromMillisecondsSinceEpoch(time);
String appointmentDate = formatDate(nowDate, [yyyy,'.',mm,'.',dd,' ',HH,':',nn]);
return appointmentDate;
}
}