From 797eaa339c3df6cc60ac1a76ec74f064959d3b82 Mon Sep 17 00:00:00 2001 From: Jazmin Ferreiro Date: Mon, 12 Jul 2021 23:09:17 -0300 Subject: [PATCH 01/11] update page when file is deleted --- lib/screens/connection/bluetooth_device.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/screens/connection/bluetooth_device.dart b/lib/screens/connection/bluetooth_device.dart index 8e9dc1d..894f64a 100644 --- a/lib/screens/connection/bluetooth_device.dart +++ b/lib/screens/connection/bluetooth_device.dart @@ -39,17 +39,17 @@ class _DeviceScreenState extends State { setState(() { _ack = (_ack + 1) > 9? 1: (_ack + 1); }); + if(!valueRead.contains("start") && !valueRead.contains("end")){ + var jsonList = "[$valueRead]"; + measurementFile.add(jsonList); + } } print("SENDING.... ${_ack}ack"); await characteristic.write(utf8.encode("${_ack}ack")); - if(valueRead.contains("end")){ + if(valueRead.contains("end")) { measurementFile.save(); return; } - if(!valueRead.contains("start")){ - var jsonList = "[$valueRead]"; - measurementFile.add(jsonList); - } } } From d072fb989f3a8721daa7142e19a086109b983c2e Mon Sep 17 00:00:00 2001 From: Jazmin Ferreiro Date: Mon, 12 Jul 2021 23:40:47 -0300 Subject: [PATCH 02/11] realy little test --- lib/screens/connection/bluetooth_device.dart | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/lib/screens/connection/bluetooth_device.dart b/lib/screens/connection/bluetooth_device.dart index 894f64a..16d3a34 100644 --- a/lib/screens/connection/bluetooth_device.dart +++ b/lib/screens/connection/bluetooth_device.dart @@ -32,24 +32,9 @@ class _DeviceScreenState extends State { var word = 'HOLA'; var deviceId = "ac:87:a3:0a:2d:1b"; var measurementFile = await DeviceMeasurementsFile.create(deviceId, word); - while(true) { + for(int i = 0; i < 100; i++) { String valueRead = await characteristic.read().then((value) => new String.fromCharCodes(value)); print("READING.... $valueRead"); - if(!valueRead.contains("ack")){ - setState(() { - _ack = (_ack + 1) > 9? 1: (_ack + 1); - }); - if(!valueRead.contains("start") && !valueRead.contains("end")){ - var jsonList = "[$valueRead]"; - measurementFile.add(jsonList); - } - } - print("SENDING.... ${_ack}ack"); - await characteristic.write(utf8.encode("${_ack}ack")); - if(valueRead.contains("end")) { - measurementFile.save(); - return; - } } } From f049a01742d34942cf4476d38012731df4880fa0 Mon Sep 17 00:00:00 2001 From: Jazmin Ferreiro Date: Tue, 13 Jul 2021 18:52:19 -0300 Subject: [PATCH 03/11] realy little test --- lib/main.dart | 10 +++- .../{ => ble}/bluetooth_device.dart | 2 +- .../{ => ble}/bluetooth_widgets.dart | 0 .../connection/{ => ble}/find_connection.dart | 0 lib/screens/connection/wifi/socket.dart | 60 +++++++++++++++++++ 5 files changed, 70 insertions(+), 2 deletions(-) rename lib/screens/connection/{ => ble}/bluetooth_device.dart (98%) rename lib/screens/connection/{ => ble}/bluetooth_widgets.dart (100%) rename lib/screens/connection/{ => ble}/find_connection.dart (100%) create mode 100644 lib/screens/connection/wifi/socket.dart diff --git a/lib/main.dart b/lib/main.dart index 032eac0..4f2b8c6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,7 @@ import 'package:assets_audio_player/assets_audio_player.dart'; import 'package:flutter/material.dart'; -import 'package:lsa_gloves/screens/connection/find_connection.dart'; +import 'package:lsa_gloves/screens/connection/ble/find_connection.dart'; +import 'package:lsa_gloves/screens/connection/wifi/socket.dart'; import 'package:lsa_gloves/screens/files/file_content.dart'; import 'package:lsa_gloves/screens/files/file_list.dart'; import 'dart:developer'; @@ -132,11 +133,18 @@ class _MyHomePageState extends State { child: Icon(Icons.play_arrow), ), FloatingActionButton( + /* onPressed: () =>{ Navigator.of(context).push(MaterialPageRoute( builder: (context) => GloveConnectionPage() )) }, + */ + onPressed: () =>{ + Navigator.of(context).push(MaterialPageRoute( + builder: (context) => WifiPage() + )) + }, heroTag: 'Guante', tooltip: 'Guante', child: Icon(Icons.bluetooth), diff --git a/lib/screens/connection/bluetooth_device.dart b/lib/screens/connection/ble/bluetooth_device.dart similarity index 98% rename from lib/screens/connection/bluetooth_device.dart rename to lib/screens/connection/ble/bluetooth_device.dart index 16d3a34..3c7ac3e 100644 --- a/lib/screens/connection/bluetooth_device.dart +++ b/lib/screens/connection/ble/bluetooth_device.dart @@ -3,7 +3,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_blue/flutter_blue.dart'; import 'package:lsa_gloves/screens/files/storage.dart'; -import 'package:lsa_gloves/screens/connection/bluetooth_widgets.dart'; +import 'package:lsa_gloves/screens/connection/ble/bluetooth_widgets.dart'; class DeviceScreen extends StatefulWidget { const DeviceScreen({Key? key, required this.device}) : super(key: key); diff --git a/lib/screens/connection/bluetooth_widgets.dart b/lib/screens/connection/ble/bluetooth_widgets.dart similarity index 100% rename from lib/screens/connection/bluetooth_widgets.dart rename to lib/screens/connection/ble/bluetooth_widgets.dart diff --git a/lib/screens/connection/find_connection.dart b/lib/screens/connection/ble/find_connection.dart similarity index 100% rename from lib/screens/connection/find_connection.dart rename to lib/screens/connection/ble/find_connection.dart diff --git a/lib/screens/connection/wifi/socket.dart b/lib/screens/connection/wifi/socket.dart new file mode 100644 index 0000000..2c8fca0 --- /dev/null +++ b/lib/screens/connection/wifi/socket.dart @@ -0,0 +1,60 @@ +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + + +class WifiPage extends StatelessWidget { + + @override + Widget build(BuildContext context) { + + return Scaffold( + appBar: AppBar( + title: Text("Socket"), + ), + body: Center( + child: FloatingActionButton( + onPressed: () => connect(), + heroTag: "Wifi", + tooltip: 'Wifi', + child: Icon(Icons.wifi)))); + } +} + +void connect() async { + // connect to the socket server + final socket = await Socket.connect('192.168.1.9', 8080); + print('Connected to: ${socket.remoteAddress.address}:${socket.remotePort}'); + + // listen for responses from the server + socket.listen( // handle data from the server + (Uint8List data) { + final serverResponse = String.fromCharCodes(data); + print('Server: $serverResponse'); + }, + + // handle errors + onError: (error) { + print(error); + socket.destroy(); + }, + + // handle server ending connection + onDone: () { + print('Server left.....'); + socket.destroy(); + }, + ); + + // send some messages to the server + await sendMessage(socket, 'Knock, knock.'); + await sendMessage(socket, 'Banana'); +} + +Future sendMessage(Socket socket, String message) async { + print('Client: $message'); + socket.write(message); + await Future.delayed(Duration(seconds: 2)); +} \ No newline at end of file From e3d9d1739762cc6ea24da2a7ce5a2d39360551f9 Mon Sep 17 00:00:00 2001 From: Jazmin Ferreiro Date: Wed, 14 Jul 2021 03:04:56 -0300 Subject: [PATCH 04/11] realy little test --- lib/screens/connection/wifi/socket.dart | 56 +++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/lib/screens/connection/wifi/socket.dart b/lib/screens/connection/wifi/socket.dart index 2c8fca0..a419359 100644 --- a/lib/screens/connection/wifi/socket.dart +++ b/lib/screens/connection/wifi/socket.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; @@ -23,16 +24,67 @@ class WifiPage extends StatelessWidget { } } + +class DeviceInfo { + final String id; + final double battery; + DeviceInfo(this.id, this.battery); + + DeviceInfo.fromJson(Map json) + : id = json['id'], battery = json['battery']; + + Map toJson() => { + 'id': id, + 'battery': battery, + }; +} + +class Movement { + final double acc; + final double gyro; + Movement(this.acc, this.gyro); + + Movement.fromJson(Map json) + : acc = json['acc'], gyro = json['gyro']; + + Map toJson() => { + 'acc': acc, + 'gyro': gyro, + }; +} + + void connect() async { // connect to the socket server final socket = await Socket.connect('192.168.1.9', 8080); print('Connected to: ${socket.remoteAddress.address}:${socket.remotePort}'); + // send some messages to the server + await sendMessage(socket, '5'); + await sendMessage(socket, 'aBc'); + await sendMessage(socket, '1'); + await sendMessage(socket, '2'); + // listen for responses from the server socket.listen( // handle data from the server (Uint8List data) { final serverResponse = String.fromCharCodes(data); print('Server: $serverResponse'); + List list = serverResponse.split('\n'); + print('list : $list'); + for(int i = 0; i < list.length; i++){ + String jsonString = list[i]; + try{ + var pkg = DeviceInfo.fromJson(jsonDecode(jsonString)); + print('map to: ${pkg}'); + print('-> ${pkg.toJson().toString()}'); + }catch(Exception){ + var m = Movement.fromJson(jsonDecode(jsonString)); + print('map to: ${m}'); + print('-> ${m.toJson().toString()}'); + } + } + }, // handle errors @@ -48,9 +100,7 @@ void connect() async { }, ); - // send some messages to the server - await sendMessage(socket, 'Knock, knock.'); - await sendMessage(socket, 'Banana'); + } Future sendMessage(Socket socket, String message) async { From a155508e91c1f9bc0e7cea0621178bf36e38d5a2 Mon Sep 17 00:00:00 2001 From: Jazmin Ferreiro Date: Wed, 14 Jul 2021 03:12:50 -0300 Subject: [PATCH 05/11] work one time only --- lib/screens/connection/wifi/socket.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/screens/connection/wifi/socket.dart b/lib/screens/connection/wifi/socket.dart index a419359..558f587 100644 --- a/lib/screens/connection/wifi/socket.dart +++ b/lib/screens/connection/wifi/socket.dart @@ -70,9 +70,9 @@ void connect() async { (Uint8List data) { final serverResponse = String.fromCharCodes(data); print('Server: $serverResponse'); - List list = serverResponse.split('\n'); + List list = serverResponse.split('\n').where((s) => !s.isEmpty).toList(); print('list : $list'); - for(int i = 0; i < list.length; i++){ + for(int i = 0; i < list.length ; i++){ String jsonString = list[i]; try{ var pkg = DeviceInfo.fromJson(jsonDecode(jsonString)); From 6a4a9f4507d72a03da416bec4f198e9279e65877 Mon Sep 17 00:00:00 2001 From: Jazmin Ferreiro Date: Sat, 17 Jul 2021 16:11:54 -0300 Subject: [PATCH 06/11] request different bodies types --- lib/screens/connection/wifi/socket.dart | 127 ++++++++++++++++-------- 1 file changed, 85 insertions(+), 42 deletions(-) diff --git a/lib/screens/connection/wifi/socket.dart b/lib/screens/connection/wifi/socket.dart index 558f587..c54f8f7 100644 --- a/lib/screens/connection/wifi/socket.dart +++ b/lib/screens/connection/wifi/socket.dart @@ -1,3 +1,4 @@ + import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; @@ -24,69 +25,118 @@ class WifiPage extends StatelessWidget { } } +enum Type { deviceInfo, movement } -class DeviceInfo { - final String id; - final double battery; - DeviceInfo(this.id, this.battery); - DeviceInfo.fromJson(Map json) - : id = json['id'], battery = json['battery']; +class Package { + int type; + + Package(this.type); + + Package.fromJson(Map json) + : type = json['type']; Map toJson() => { - 'id': id, - 'battery': battery, + 'type': type, }; + +} + +class DeviceInfo extends Package { + final String id; + final double battery; + DeviceInfo(this.id, this.battery): super(0); + + DeviceInfo.fromJson(Map json) + : id = json['id'], battery = json['battery'], super.fromJson(json); + + Map toJson() { + var result = super.toJson(); + result.addAll({ + 'id': id, + 'battery': battery, + }); + return result; + } } -class Movement { +class Movement extends Package{ final double acc; final double gyro; - Movement(this.acc, this.gyro); + Movement(this.acc, this.gyro): super(1); Movement.fromJson(Map json) - : acc = json['acc'], gyro = json['gyro']; - - Map toJson() => { - 'acc': acc, - 'gyro': gyro, - }; + : acc = json['acc'], gyro = json['gyro'], super.fromJson(json); + + Map toJson(){ + var result = super.toJson(); + result.addAll({ + 'acc': acc, + 'gyro': gyro, + }); + return result; + } } void connect() async { - // connect to the socket server - final socket = await Socket.connect('192.168.1.9', 8080); + // CONNECTION RESET BY PEER + /* + print('Request info...'); + Socket skt = await Socket.connect('192.168.1.9', 8080, timeout: Duration(seconds: 5)); + print('Connected to: ${skt.remoteAddress.address}:${skt.remotePort}'); + skt.write('1'); + final data = await skt.first; + final serverResponse = String.fromCharCodes(data); + print('Server: $serverResponse'); + await skt.close(); + skt.destroy(); + + print('Request movement reads...'); + Socket socket = await Socket.connect('192.168.1.9', 8080, timeout: Duration(seconds: 5)); print('Connected to: ${socket.remoteAddress.address}:${socket.remotePort}'); - - // send some messages to the server - await sendMessage(socket, '5'); - await sendMessage(socket, 'aBc'); - await sendMessage(socket, '1'); - await sendMessage(socket, '2'); + socket.write('2'); + final data2 = await socket.first; + final response = String.fromCharCodes(data2); + print('Server: $response'); + await socket.close(); + skt.destroy(); + */ // listen for responses from the server + print('Request info...'); + Socket socket = await Socket.connect('192.168.1.9', 8080, timeout: Duration(seconds: 5)); + socket.write('2'); + socket.write('1'); socket.listen( // handle data from the server (Uint8List data) { final serverResponse = String.fromCharCodes(data); print('Server: $serverResponse'); - List list = serverResponse.split('\n').where((s) => !s.isEmpty).toList(); + List list = serverResponse.split('\n').where((s) => s.isNotEmpty).toList(); print('list : $list'); for(int i = 0; i < list.length ; i++){ String jsonString = list[i]; - try{ - var pkg = DeviceInfo.fromJson(jsonDecode(jsonString)); - print('map to: ${pkg}'); - print('-> ${pkg.toJson().toString()}'); - }catch(Exception){ - var m = Movement.fromJson(jsonDecode(jsonString)); - print('map to: ${m}'); - print('-> ${m.toJson().toString()}'); + var pkg = Package.fromJson(jsonDecode(jsonString)); + print('map to: ${pkg}'); + print('-> ${pkg.toJson().toString()}'); + switch (Type.values[pkg.type]) { + case Type.deviceInfo:{ + var pkg = DeviceInfo.fromJson(jsonDecode(jsonString)); + print('map to: ${pkg}'); + print('-> ${pkg.toJson().toString()}'); + } + break; + case Type.movement: { + var pkg = Movement.fromJson(jsonDecode(jsonString)); + print('map to: ${pkg}'); + print('-> ${pkg.toJson().toString()}'); + } + break; + default: + print('unknown package type'); } } - }, - // handle errors onError: (error) { print(error); @@ -100,11 +150,4 @@ void connect() async { }, ); - -} - -Future sendMessage(Socket socket, String message) async { - print('Client: $message'); - socket.write(message); - await Future.delayed(Duration(seconds: 2)); } \ No newline at end of file From fa14e94b826848e4fd54a1116ccdde26f681a7f2 Mon Sep 17 00:00:00 2001 From: Jazmin Ferreiro Date: Sun, 18 Jul 2021 11:46:33 -0300 Subject: [PATCH 07/11] suscribe socket only one time --- .../connection/ble/find_connection.dart | 4 +- lib/screens/connection/wifi/socket.dart | 298 ++++++++++++------ 2 files changed, 208 insertions(+), 94 deletions(-) diff --git a/lib/screens/connection/ble/find_connection.dart b/lib/screens/connection/ble/find_connection.dart index 597a44b..8e6e842 100644 --- a/lib/screens/connection/ble/find_connection.dart +++ b/lib/screens/connection/ble/find_connection.dart @@ -54,7 +54,6 @@ class BluetoothOffScreen extends StatelessWidget { } class FindDevicesScreen extends StatelessWidget { - @override Widget build(BuildContext context) { return Scaffold( @@ -72,8 +71,7 @@ class FindDevicesScreen extends StatelessWidget { .asyncMap((_) => FlutterBlue.instance.connectedDevices), initialData: [], builder: (c, snapshot) => Column( - children: snapshot.data! - .map((d) => ListTile( + children: snapshot.data!.map((d) => ListTile( title: Text(d.name), subtitle: Text(d.id.toString()), trailing: StreamBuilder( diff --git a/lib/screens/connection/wifi/socket.dart b/lib/screens/connection/wifi/socket.dart index c54f8f7..0964b18 100644 --- a/lib/screens/connection/wifi/socket.dart +++ b/lib/screens/connection/wifi/socket.dart @@ -1,4 +1,4 @@ - +import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; @@ -8,133 +8,248 @@ import 'package:flutter/material.dart'; class WifiPage extends StatelessWidget { - @override Widget build(BuildContext context) { - - return Scaffold( - appBar: AppBar( - title: Text("Socket"), - ), - body: Center( - child: FloatingActionButton( - onPressed: () => connect(), - heroTag: "Wifi", - tooltip: 'Wifi', - child: Icon(Icons.wifi)))); + return FutureBuilder( + future: Socket.connect('192.168.1.9', 8080, timeout: Duration(seconds: 5)), + builder: (context, socket) { + if (socket.hasData) { + return MovementRecorderWidget(clientSocket: socket.requireData); + } else { + return Scaffold( + appBar: AppBar(title: Text("Connectting....")), + body: Center(child: new Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CircularProgressIndicator(), + Container( + margin: const EdgeInsets.only(top: 20.0), + child: new Text('conectando...'), + ) + ]))); + } + }); } } -enum Type { deviceInfo, movement } +/// This is the stateful widget that the main application instantiates. +class MovementRecorderWidget extends StatefulWidget { + final Socket clientSocket; + const MovementRecorderWidget({Key? key, required this.clientSocket}) : super(key: key); + @override + State createState() => _MovementRecorderWidget(this.clientSocket, false); +} -class Package { - int type; +/// This is the private State class that goes with MyStatefulWidget. +class _MovementRecorderWidget extends State { + _MovementRecorderWidget(this.clientSocket, this._isRecording); + Socket clientSocket; + bool _isRecording; - Package(this.type); + StreamController _streamController = new StreamController.broadcast(); + List items = ["start"]; - Package.fromJson(Map json) - : type = json['type']; + @override + void initState(){ + super.initState(); + /* + Stream _socketSuscription = clientSocket.asBroadcastStream( + onListen: (subscription) { + subscription.onData((data) { + print("cancel socket suscription"); + }); + subscription.onDone(() { + print('Server left.....'); + subscription.cancel(); + clientSocket.destroy(); + }); + subscription.onError((error) { + print('connection errror: $error'); + subscription.cancel(); + clientSocket.destroy(); + }); + }, + onCancel: (subscription) { + print("cancel socket suscription"); + }, + ); + */ + } - Map toJson() => { - 'type': type, - }; -} + @override + Future dispose() async { + super.dispose(); + _streamController.close(); + await clientSocket.close(); + } -class DeviceInfo extends Package { - final String id; - final double battery; - DeviceInfo(this.id, this.battery): super(0); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Movement recording'), + ), + body: _getRecordingLogList(), + floatingActionButton: _getRecordingButton() + ); + } - DeviceInfo.fromJson(Map json) - : id = json['id'], battery = json['battery'], super.fromJson(json); + VoidCallback? startRecording() { + print('startRecording'); + setState(() { + _isRecording = true; + }); + print('streamController'); + _streamController = new StreamController.broadcast(); + _streamController.stream.listen((p) => setState(() => items.add(p))); + print('load'); + load(_streamController); - Map toJson() { - var result = super.toJson(); - result.addAll({ - 'id': id, - 'battery': battery, + } + VoidCallback? stopRecording() { + print('stopRecording'); + _streamController.close(); + setState(() { + _isRecording = false; }); - return result; + + } + + Widget _getRecordingLogList() { + return Center( + child: ListView.builder( + itemBuilder: (BuildContext context, int index) => _getListElement(index), + itemCount: items.length + )); + } + + Widget _getListElement(int index) { + if (index >= items.length) { + return Container(); + } + return Container( + child: Text(items[index]), + ); } + + Widget _getRecordingButton() { + if (_isRecording) { + return FloatingActionButton( + child: Icon(Icons.stop), + onPressed: () => stopRecording(), + backgroundColor: Colors.red, + ); + } else { + return FloatingActionButton( + onPressed: () => startRecording(), + heroTag: "startRecording", + tooltip: 'startRecording', + child: Icon(Icons.circle) + ); + } + } + + + load(StreamController sc) async { + //cant susbribe again + var socketSubscription = clientSocket.listen(null); + socketSubscription.onError((error) { + print(error); + socketSubscription.cancel(); + clientSocket.destroy(); + }); + socketSubscription.onDone(() { + print('Server left.....'); + socketSubscription.cancel(); + clientSocket.destroy(); + }); + socketSubscription.onData((Uint8List data) {// handle data from the server + final serverResponse = String.fromCharCodes(data); + List list = serverResponse.split('\n') + .where((s) => s.isNotEmpty) + .toList(); + print('server : $list'); + for (int i = 0; i < list.length; i++) { + if(sc.isClosed) { + print("stream controller is close"); + socketSubscription.cancel(); + this.items = ["start"]; + return; + } else { + try{ + String jsonString = list[i]; + var pkg = Movement.fromJson(jsonDecode(jsonString)); + print('map to: ${pkg}'); + print('-> ${pkg.toJson().toString()}'); + sc.add(pkg.toJson().toString()); + }catch(e){ + print('cant parse : jsonString'); + } + } + } + }); + + /* + final subscription = getStreamData().listen(null); + subscription.onData((event) { + if(sc.isClosed){ + print("stream controller is close"); + subscription.cancel(); + this.items = ["start"]; + return; + } + sc.add(event); + }); + */ + } + + Stream getStreamData() async* { + while (true) { + await Future.delayed(Duration(seconds: 1)); + yield "1.3, 34.7, 56.778, 45.67, 8.767"; + } + } + } -class Movement extends Package{ +class Movement { + final String deviceId; + final int eventNum; final double acc; final double gyro; - Movement(this.acc, this.gyro): super(1); + Movement(this.deviceId, this.eventNum, this.acc, this.gyro); Movement.fromJson(Map json) - : acc = json['acc'], gyro = json['gyro'], super.fromJson(json); + : deviceId = json['device_id'], eventNum = json['event_num'], + acc = json['acc'], gyro = json['gyro']; - Map toJson(){ - var result = super.toJson(); - result.addAll({ - 'acc': acc, - 'gyro': gyro, - }); - return result; - } + Map toJson() => { + 'device_id': deviceId, + 'event_num': eventNum, + 'acc': acc, + 'gyro': gyro, + }; } void connect() async { - // CONNECTION RESET BY PEER - /* - print('Request info...'); - Socket skt = await Socket.connect('192.168.1.9', 8080, timeout: Duration(seconds: 5)); - print('Connected to: ${skt.remoteAddress.address}:${skt.remotePort}'); - skt.write('1'); - final data = await skt.first; - final serverResponse = String.fromCharCodes(data); - print('Server: $serverResponse'); - await skt.close(); - skt.destroy(); - - print('Request movement reads...'); - Socket socket = await Socket.connect('192.168.1.9', 8080, timeout: Duration(seconds: 5)); - print('Connected to: ${socket.remoteAddress.address}:${socket.remotePort}'); - socket.write('2'); - final data2 = await socket.first; - final response = String.fromCharCodes(data2); - print('Server: $response'); - await socket.close(); - skt.destroy(); - */ - // listen for responses from the server print('Request info...'); Socket socket = await Socket.connect('192.168.1.9', 8080, timeout: Duration(seconds: 5)); - socket.write('2'); - socket.write('1'); - socket.listen( // handle data from the server - (Uint8List data) { + + var suscription = socket.listen((Uint8List data) { // handle data from the server final serverResponse = String.fromCharCodes(data); print('Server: $serverResponse'); List list = serverResponse.split('\n').where((s) => s.isNotEmpty).toList(); print('list : $list'); for(int i = 0; i < list.length ; i++){ String jsonString = list[i]; - var pkg = Package.fromJson(jsonDecode(jsonString)); + var pkg = Movement.fromJson(jsonDecode(jsonString)); print('map to: ${pkg}'); print('-> ${pkg.toJson().toString()}'); - switch (Type.values[pkg.type]) { - case Type.deviceInfo:{ - var pkg = DeviceInfo.fromJson(jsonDecode(jsonString)); - print('map to: ${pkg}'); - print('-> ${pkg.toJson().toString()}'); - } - break; - case Type.movement: { - var pkg = Movement.fromJson(jsonDecode(jsonString)); - print('map to: ${pkg}'); - print('-> ${pkg.toJson().toString()}'); - } - break; - default: - print('unknown package type'); - } } }, // handle errors @@ -149,5 +264,6 @@ void connect() async { socket.destroy(); }, ); + suscription.cancel(); +} -} \ No newline at end of file From 3752d80b67fd49f73f5039490f927e3e1d7f3d1f Mon Sep 17 00:00:00 2001 From: Jazmin Ferreiro Date: Sun, 18 Jul 2021 16:35:49 -0300 Subject: [PATCH 08/11] recording ok --- lib/screens/connection/wifi/socket.dart | 78 ++++++------------------- 1 file changed, 18 insertions(+), 60 deletions(-) diff --git a/lib/screens/connection/wifi/socket.dart b/lib/screens/connection/wifi/socket.dart index 0964b18..a15ac44 100644 --- a/lib/screens/connection/wifi/socket.dart +++ b/lib/screens/connection/wifi/socket.dart @@ -44,48 +44,16 @@ class MovementRecorderWidget extends StatefulWidget { /// This is the private State class that goes with MyStatefulWidget. class _MovementRecorderWidget extends State { - _MovementRecorderWidget(this.clientSocket, this._isRecording); - Socket clientSocket; bool _isRecording; + final Socket clientSocket; + final Stream _clientSocketBroadcast; + + _MovementRecorderWidget(this.clientSocket, this._isRecording) + : _clientSocketBroadcast = clientSocket.asBroadcastStream(); StreamController _streamController = new StreamController.broadcast(); List items = ["start"]; - @override - void initState(){ - super.initState(); - /* - Stream _socketSuscription = clientSocket.asBroadcastStream( - onListen: (subscription) { - subscription.onData((data) { - print("cancel socket suscription"); - }); - subscription.onDone(() { - print('Server left.....'); - subscription.cancel(); - clientSocket.destroy(); - }); - subscription.onError((error) { - print('connection errror: $error'); - subscription.cancel(); - clientSocket.destroy(); - }); - }, - onCancel: (subscription) { - print("cancel socket suscription"); - }, - ); - */ - } - - - @override - Future dispose() async { - super.dispose(); - _streamController.close(); - await clientSocket.close(); - } - @override Widget build(BuildContext context) { return Scaffold( @@ -106,7 +74,7 @@ class _MovementRecorderWidget extends State { _streamController = new StreamController.broadcast(); _streamController.stream.listen((p) => setState(() => items.add(p))); print('load'); - load(_streamController); + loadReceivedMessagesFromConnection(_streamController); } VoidCallback? stopRecording() { @@ -152,20 +120,23 @@ class _MovementRecorderWidget extends State { } } + loadReceivedMessagesFromConnection(StreamController sc) async { + var socketSubscription = _clientSocketBroadcast.listen(null); - load(StreamController sc) async { - //cant susbribe again - var socketSubscription = clientSocket.listen(null); socketSubscription.onError((error) { - print(error); + print('socket subscription error: $error'); socketSubscription.cancel(); clientSocket.destroy(); + //TODO Reload WifiPage ? }); + socketSubscription.onDone(() { print('Server left.....'); socketSubscription.cancel(); clientSocket.destroy(); + //TODO Reload WifiPage ? }); + socketSubscription.onData((Uint8List data) {// handle data from the server final serverResponse = String.fromCharCodes(data); List list = serverResponse.split('\n') @@ -191,26 +162,13 @@ class _MovementRecorderWidget extends State { } } }); - - /* - final subscription = getStreamData().listen(null); - subscription.onData((event) { - if(sc.isClosed){ - print("stream controller is close"); - subscription.cancel(); - this.items = ["start"]; - return; - } - sc.add(event); - }); - */ } - Stream getStreamData() async* { - while (true) { - await Future.delayed(Duration(seconds: 1)); - yield "1.3, 34.7, 56.778, 45.67, 8.767"; - } + @override + Future dispose() async { + super.dispose(); + _streamController.close(); + await clientSocket.close(); } } From 43040ec3042587674451beadc7769c8e02211d61 Mon Sep 17 00:00:00 2001 From: Jazmin Ferreiro Date: Sun, 18 Jul 2021 16:44:09 -0300 Subject: [PATCH 09/11] wifi icon button --- lib/main.dart | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 4f2b8c6..bb0eaf3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -133,21 +133,25 @@ class _MyHomePageState extends State { child: Icon(Icons.play_arrow), ), FloatingActionButton( - /* onPressed: () =>{ Navigator.of(context).push(MaterialPageRoute( builder: (context) => GloveConnectionPage() )) }, - */ + + heroTag: 'Ble', + tooltip: 'Ble', + child: Icon(Icons.bluetooth), + ), + FloatingActionButton( onPressed: () =>{ Navigator.of(context).push(MaterialPageRoute( builder: (context) => WifiPage() )) }, - heroTag: 'Guante', - tooltip: 'Guante', - child: Icon(Icons.bluetooth), + heroTag: 'Wifi', + tooltip: 'Wifi', + child: Icon(Icons.wifi), ), FloatingActionButton( onPressed: () => { From 0262234108e7b432d9dd444f3a6b5fc18ce531ba Mon Sep 17 00:00:00 2001 From: Jazmin Ferreiro Date: Sun, 18 Jul 2021 23:18:59 -0300 Subject: [PATCH 10/11] guardar archivo con nombre --- lib/model/movement.dart | 18 ++++ lib/screens/connection/wifi/socket.dart | 135 +++++++++++++----------- lib/screens/files/storage.dart | 24 +++-- lib/widgets/Dialog.dart | 26 +++++ 4 files changed, 131 insertions(+), 72 deletions(-) create mode 100644 lib/model/movement.dart create mode 100644 lib/widgets/Dialog.dart diff --git a/lib/model/movement.dart b/lib/model/movement.dart new file mode 100644 index 0000000..f8b9291 --- /dev/null +++ b/lib/model/movement.dart @@ -0,0 +1,18 @@ +class Movement { + final String deviceId; + final int eventNum; + final double acc; + final double gyro; + Movement(this.deviceId, this.eventNum, this.acc, this.gyro); + + Movement.fromJson(Map json) + : deviceId = json['device_id'], eventNum = json['event_num'], + acc = json['acc'], gyro = json['gyro']; + + Map toJson() => { + 'device_id': deviceId, + 'event_num': eventNum, + 'acc': acc, + 'gyro': gyro, + }; +} \ No newline at end of file diff --git a/lib/screens/connection/wifi/socket.dart b/lib/screens/connection/wifi/socket.dart index a15ac44..dafcc0b 100644 --- a/lib/screens/connection/wifi/socket.dart +++ b/lib/screens/connection/wifi/socket.dart @@ -5,8 +5,12 @@ import 'dart:typed_data'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:lsa_gloves/model/movement.dart'; +import 'package:lsa_gloves/screens/files/storage.dart'; +import 'package:lsa_gloves/widgets/Dialog.dart'; +/// Show a connection spinning or a page to record movements class WifiPage extends StatelessWidget { @override Widget build(BuildContext context) { @@ -47,12 +51,16 @@ class _MovementRecorderWidget extends State { bool _isRecording; final Socket clientSocket; final Stream _clientSocketBroadcast; + final GlobalKey _keyLoader = new GlobalKey(); + TextEditingController _fileNameFieldController = TextEditingController(); + String fileNameUserInputValue; + _MovementRecorderWidget(this.clientSocket, this._isRecording) - : _clientSocketBroadcast = clientSocket.asBroadcastStream(); + : fileNameUserInputValue = '', _clientSocketBroadcast = clientSocket.asBroadcastStream(); - StreamController _streamController = new StreamController.broadcast(); - List items = ["start"]; + StreamController _streamController = new StreamController.broadcast(); + List items = []; @override Widget build(BuildContext context) { @@ -72,20 +80,52 @@ class _MovementRecorderWidget extends State { }); print('streamController'); _streamController = new StreamController.broadcast(); - _streamController.stream.listen((p) => setState(() => items.add(p))); - print('load'); - loadReceivedMessagesFromConnection(_streamController); - + _streamController.stream.listen((p) => { + setState(() => items.add(p)) + }); + print('load msg from connection into item list'); + receivedMessagesFromConnection(_streamController); } + + VoidCallback? stopRecording() { print('stopRecording'); _streamController.close(); setState(() { _isRecording = false; }); - + showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text('Desea guardar los movimientos medidos?'), + content: TextField( + onChanged: (value) { + setState(() { + fileNameUserInputValue = value; + }); + + }, + controller: _fileNameFieldController, + decoration: InputDecoration(hintText: "Nombre"), + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context, 'Descartar'), + child: const Text('Descartar'), + ), + TextButton( + onPressed: () { + Navigator.pop(context, 'Guardar'); + saveMessagesInFile(fileNameUserInputValue, this.items); + }, + child: const Text('Guardar'), + ), + ], + ), + ); } + Widget _getRecordingLogList() { return Center( child: ListView.builder( @@ -99,7 +139,7 @@ class _MovementRecorderWidget extends State { return Container(); } return Container( - child: Text(items[index]), + child: Text(items[index].toJson().toString()), ); } @@ -120,7 +160,7 @@ class _MovementRecorderWidget extends State { } } - loadReceivedMessagesFromConnection(StreamController sc) async { + receivedMessagesFromConnection(StreamController sc) async { var socketSubscription = _clientSocketBroadcast.listen(null); socketSubscription.onError((error) { @@ -147,15 +187,13 @@ class _MovementRecorderWidget extends State { if(sc.isClosed) { print("stream controller is close"); socketSubscription.cancel(); - this.items = ["start"]; return; } else { try{ String jsonString = list[i]; var pkg = Movement.fromJson(jsonDecode(jsonString)); - print('map to: ${pkg}'); - print('-> ${pkg.toJson().toString()}'); - sc.add(pkg.toJson().toString()); + print('map to -> ${pkg.toJson().toString()}'); + sc.add(pkg); }catch(e){ print('cant parse : jsonString'); } @@ -164,6 +202,25 @@ class _MovementRecorderWidget extends State { }); } + saveMessagesInFile(String fileName, List movements) async { + if(movements.isEmpty){ + return; + } + //open pop up loading + Dialogs.showLoadingDialog(context, _keyLoader, "Guardando..."); + var word = fileName; + var deviceId = movements.first.deviceId; + var measurementFile = await DeviceMeasurementsFile.create(deviceId, word); + for (int i = 0; i < movements.length; i++) { + print('saving in file -> ${movements[i].toJson().toString()}'); + measurementFile.add(movements[i]); + } + await measurementFile.save(); + this.items = []; + //close pop up loading + Navigator.of(_keyLoader.currentContext!,rootNavigator: true).pop(); + } + @override Future dispose() async { super.dispose(); @@ -173,55 +230,5 @@ class _MovementRecorderWidget extends State { } -class Movement { - final String deviceId; - final int eventNum; - final double acc; - final double gyro; - Movement(this.deviceId, this.eventNum, this.acc, this.gyro); - - Movement.fromJson(Map json) - : deviceId = json['device_id'], eventNum = json['event_num'], - acc = json['acc'], gyro = json['gyro']; - - Map toJson() => { - 'device_id': deviceId, - 'event_num': eventNum, - 'acc': acc, - 'gyro': gyro, - }; -} - -void connect() async { - // listen for responses from the server - print('Request info...'); - Socket socket = await Socket.connect('192.168.1.9', 8080, timeout: Duration(seconds: 5)); - - var suscription = socket.listen((Uint8List data) { // handle data from the server - final serverResponse = String.fromCharCodes(data); - print('Server: $serverResponse'); - List list = serverResponse.split('\n').where((s) => s.isNotEmpty).toList(); - print('list : $list'); - for(int i = 0; i < list.length ; i++){ - String jsonString = list[i]; - var pkg = Movement.fromJson(jsonDecode(jsonString)); - print('map to: ${pkg}'); - print('-> ${pkg.toJson().toString()}'); - } - }, - // handle errors - onError: (error) { - print(error); - socket.destroy(); - }, - - // handle server ending connection - onDone: () { - print('Server left.....'); - socket.destroy(); - }, - ); - suscription.cancel(); -} diff --git a/lib/screens/files/storage.dart b/lib/screens/files/storage.dart index 4e42ba3..caccbb2 100644 --- a/lib/screens/files/storage.dart +++ b/lib/screens/files/storage.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:io'; import 'dart:convert'; +import 'package:lsa_gloves/model/movement.dart'; import 'package:lsa_gloves/screens/edgeimpulse/api_client.dart'; import 'package:path_provider/path_provider.dart'; @@ -75,26 +76,27 @@ class DeviceMeasurementsFile { return DeviceMeasurementsFile._(file, creationDate, json); } - Future add(String measurementLine) async { + Future add(Movement measurement) async { if(this.fileContent == null){ this.fileContent = await readJsonContent(); } - this.fileContent!.add(measurementLine); + return this.fileContent!.add(measurement); } factory DeviceMeasurementsFile.fromFileSystem(file, lastModificationDate){ return DeviceMeasurementsFile._(file, lastModificationDate, null); } - void save() { + Future save() async { try { //TODO proteger concunrrencia, mutex?? String json = jsonEncode(this.fileContent); print("saving $json"); - this.file.writeAsString(json); + await this.file.writeAsString(json); + return true; } catch (e) { print("error saving content to file"+ e.toString()); - return; + return false; } } @@ -145,10 +147,16 @@ class SensorMeasurements { SensorMeasurements(this.deviceId, this.word, this.values); - void add(String measurementStr) { - var list = json.decode(measurementStr); - List measurementList = list.cast(); + bool add(Movement measurement) { + if(measurement.deviceId != this.deviceId){ + print("wrong deviceId $measurement.deviceId"); + return false; + } + List measurementList = []; + measurementList.add(measurement.acc); + measurementList.add(measurement.gyro); this.values.add(measurementList); + return true; } factory SensorMeasurements.fromJson(dynamic json) { diff --git a/lib/widgets/Dialog.dart b/lib/widgets/Dialog.dart new file mode 100644 index 0000000..b75e246 --- /dev/null +++ b/lib/widgets/Dialog.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; + +class Dialogs { + + static Future showLoadingDialog( + BuildContext context, GlobalKey key, String message) async { + return showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return new WillPopScope( + onWillPop: () async => false, + child: SimpleDialog( + key: key, + children: [ + Center( + child: Column(children: [ + CircularProgressIndicator(), + SizedBox(height: 10,), + Text(message) + ]), + ) + ])); + }); + } +} \ No newline at end of file From a8fa984633790652f26887bf47f6876b74f34bd8 Mon Sep 17 00:00:00 2001 From: Jazmin Ferreiro Date: Mon, 19 Jul 2021 01:33:29 -0300 Subject: [PATCH 11/11] guardar archivo con nombre --- lib/main.dart | 4 + lib/model/movement.dart | 104 ++++++++++++++++++++++-- lib/screens/connection/wifi/socket.dart | 6 +- lib/screens/files/storage.dart | 19 +++-- 4 files changed, 117 insertions(+), 16 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index bb0eaf3..dcb433a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:assets_audio_player/assets_audio_player.dart'; import 'package:flutter/material.dart'; import 'package:lsa_gloves/screens/connection/ble/find_connection.dart'; @@ -7,6 +9,8 @@ import 'package:lsa_gloves/screens/files/file_list.dart'; import 'dart:developer'; import 'package:lsa_gloves/screens/files/storage.dart'; +import 'model/movement.dart'; + void main() { runApp(MyApp()); diff --git a/lib/model/movement.dart b/lib/model/movement.dart index f8b9291..afddb77 100644 --- a/lib/model/movement.dart +++ b/lib/model/movement.dart @@ -1,18 +1,108 @@ class Movement { final String deviceId; final int eventNum; - final double acc; - final double gyro; - Movement(this.deviceId, this.eventNum, this.acc, this.gyro); + final Hand hand; + + Movement(this.deviceId, this.eventNum, this.hand); Movement.fromJson(Map json) : deviceId = json['device_id'], eventNum = json['event_num'], - acc = json['acc'], gyro = json['gyro']; + hand = Hand.fromJson(json['hand'] as Map); Map toJson() => { 'device_id': deviceId, 'event_num': eventNum, - 'acc': acc, - 'gyro': gyro, + 'hand': hand.toJson(), + }; +} + + +class Hand { + final Finger thump; + /* + final Finger index; + final Finger middle; + final Finger ring; + final Finger pinky; + */ + + Hand(this.thump); + + Hand.fromJson(Map json) + : thump = Finger.fromJson(json['thump'] as Map); + + Map toJson() => { + 'thump': thump.toJson(), + }; + +} + +class Finger { + final Acceleration acc; + final Gyro gyro; + final Inclination inclination; + + Finger(this.acc, this.gyro, this.inclination); + + Finger.fromJson(Map json) + : acc = Acceleration.fromJson(json['acc'] as Map), + gyro = Gyro.fromJson(json['gyro'] as Map), + inclination = Inclination.fromJson(json['inclination']as Map); + Map toJson() => { + 'acc': acc.toJson(), + 'gyro': gyro.toJson(), + 'inclination': inclination.toJson(), + }; + +} +class Acceleration { + final double x; + final double y; + final double z; + + Acceleration(this.x, this.y, this.z); + + Acceleration.fromJson(Map json) + : x = json['x'], y = json['y'], z = json['z']; + + Map toJson() => { + 'x': x, + 'y': y, + 'z': z, + }; +} + +class Gyro { + final double x; + final double y; + final double z; + Gyro (this.x, this.y, this.z); + + Gyro .fromJson(Map json) + : x = json['x'], y = json['y'], z = json['z']; + + Map toJson() => { + 'x': x, + 'y': y, + 'z': z, }; -} \ No newline at end of file +} + +class Inclination { + final double roll; + final double pitch; + final double yaw; + Inclination(this.roll, this.pitch, this.yaw); + + Inclination.fromJson(Map json) + : roll = json['roll'], pitch = json['pitch'], yaw = json['yaw']; + + Map toJson() => { + 'roll': roll, + 'pitch': pitch, + 'yaw': yaw, + }; + +} + + diff --git a/lib/screens/connection/wifi/socket.dart b/lib/screens/connection/wifi/socket.dart index dafcc0b..13d0a82 100644 --- a/lib/screens/connection/wifi/socket.dart +++ b/lib/screens/connection/wifi/socket.dart @@ -97,7 +97,7 @@ class _MovementRecorderWidget extends State { showDialog( context: context, builder: (BuildContext context) => AlertDialog( - title: const Text('Desea guardar los movimientos medidos?'), + title: const Text('Guardar los movimientos?'), content: TextField( onChanged: (value) { setState(() { @@ -106,7 +106,7 @@ class _MovementRecorderWidget extends State { }, controller: _fileNameFieldController, - decoration: InputDecoration(hintText: "Nombre"), + decoration: InputDecoration(hintText: "Nombre del archivo"), ), actions: [ TextButton( @@ -195,7 +195,7 @@ class _MovementRecorderWidget extends State { print('map to -> ${pkg.toJson().toString()}'); sc.add(pkg); }catch(e){ - print('cant parse : jsonString'); + print('cant parse : ${list[i]}'); } } } diff --git a/lib/screens/files/storage.dart b/lib/screens/files/storage.dart index caccbb2..eb31c85 100644 --- a/lib/screens/files/storage.dart +++ b/lib/screens/files/storage.dart @@ -137,7 +137,6 @@ class DeviceMeasurementsFile { "${date.minute.toString()}:" + "${date.second.toString()}"; } - } class SensorMeasurements { @@ -147,14 +146,22 @@ class SensorMeasurements { SensorMeasurements(this.deviceId, this.word, this.values); - bool add(Movement measurement) { - if(measurement.deviceId != this.deviceId){ - print("wrong deviceId $measurement.deviceId"); + bool add(Movement mov) { + if(mov.deviceId != this.deviceId){ + print("wrong deviceId $mov.deviceId"); return false; } List measurementList = []; - measurementList.add(measurement.acc); - measurementList.add(measurement.gyro); + var thump = mov.hand.thump; + measurementList.add(thump.acc.x); + measurementList.add(thump.acc.y); + measurementList.add(thump.acc.z); + measurementList.add(thump.gyro.x); + measurementList.add(thump.gyro.y); + measurementList.add(thump.gyro.z); + measurementList.add(thump.inclination.yaw); + measurementList.add(thump.inclination.pitch); + measurementList.add(thump.inclination.roll); this.values.add(measurementList); return true; }