Explorar o código

Added bluetooth listening and display logic

TC %!s(int64=2) %!d(string=hai) anos
pai
achega
d05db685b1
Modificáronse 4 ficheiros con 91 adicións e 20 borrados
  1. 81 20
      src/pm25go/lib/main.dart
  2. 2 0
      src/pm25go/lib/scan.dart
  3. 7 0
      src/pm25go/pubspec.lock
  4. 1 0
      src/pm25go/pubspec.yaml

+ 81 - 20
src/pm25go/lib/main.dart

@@ -1,7 +1,10 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
 import 'package:pm25go/scan.dart';
+import 'package:intl/intl.dart';
 import 'bluetooth.dart';
+import 'dart:typed_data';
+import 'dart:convert';
 
 void main() {
   runApp(const MyApp());
@@ -72,22 +75,42 @@ class MyHomePage extends StatefulWidget {
 
 class _MyHomePageState extends State<MyHomePage> {
   var _statusText = "正在等待藍牙運接…\nWaiting for Bluetooth Connection...";
-
+  var _updateText = "無數據";
   //Bluetooth Connection
-  bool _btConnected = false;
   DeviceSelectionWrapper connectedBluetoothDevice =
       DeviceSelectionWrapper("", "", false, false);
-
+  bool _alreadyListening = false;
+  var incomingLine = "";
   //Data update for display
   int _pm01 = 0; //No recommended data found
   int _pm25 = 0; //Healthy range: 35, recommend < 15
   int _pm10 = 0; //Healthy range: 150, recommend < 50
+
+  Color GetPm25Color() {
+    if (_pm25 == 0) {
+      return Colors.grey;
+    } else if (_pm25 < 15) {
+      return Colors.green;
+    } else if (_pm25 < 35) {
+      return Colors.orangeAccent;
+    }
+    return Colors.red;
+  }
+
+  Color GetPm10Color() {
+    if (_pm10 == 0) {
+      return Colors.grey;
+    } else if (_pm10 < 50) {
+      return Colors.green;
+    } else if (_pm10 < 150) {
+      return Colors.orangeAccent;
+    }
+
+    return Colors.red;
+  }
+
   void _toggleBluetooth() async {
-    // This call to setState tells the Flutter framework that something has
-    // changed in this State, which causes it to rerun the build method below
-    // so that the display can reflect the updated values. If we changed
-    // _counter without calling setState(), then the build method would not be
-    // called again, and so nothing would appear to happen.
+    //If the connection has already been established, stop the previous connection first
     DeviceSelectionWrapper deviceStateToSend = connectedBluetoothDevice;
     final DeviceSelectionWrapper result = await Navigator.push(
         context,
@@ -98,8 +121,50 @@ class _MyHomePageState extends State<MyHomePage> {
 
     //Update the status text
     if (result.deviceSelected && result.deviceConnected) {
+      //Device already setup. Start listening to it
       setState(() {
         _statusText = "已連接到藍牙裝置 " + result.deviceName;
+
+        if (!_alreadyListening) {
+          connectedBluetoothDevice.connection.input?.listen(
+            (Uint8List data) {
+              var incomingData = utf8.decode(data);
+              incomingLine = incomingLine + incomingData;
+              if (incomingLine.contains("\n")) {
+                var chunks = incomingData.split("\n");
+                var lineToBeProcessed = chunks[0];
+                chunks.removeAt(0);
+                var otherLines = chunks.join("\n");
+                //Process the target line to the target data on screen
+                var values = lineToBeProcessed.split(",");
+                if (values.length == 3 &&
+                    values[0] != "" &&
+                    values[1] != "" &&
+                    values[2] != "") {
+                  //Valid data.
+                  setState(() {
+                    _pm01 = int.parse(values[0]);
+                    _pm25 = int.parse(values[1]);
+                    _pm10 = int.parse(values[2]);
+
+                    _updateText = "最後更新: " +
+                        DateFormat('kk:mm:ss dd/MM/yyyy')
+                            .format(DateTime.now());
+                  });
+                }
+                print('Processing Line: ${lineToBeProcessed}');
+                //Replace the incoming line with the poped data
+                incomingLine = otherLines;
+              }
+              //connectedBluetoothDevice.connection.output.add(data); // Sending data
+            },
+            onDone: () {
+              //Connection terminated. Set already listening to false
+              _alreadyListening = false;
+            },
+          );
+          _alreadyListening = true;
+        }
       });
     } else {
       setState(() {
@@ -109,15 +174,6 @@ class _MyHomePageState extends State<MyHomePage> {
     return;
   }
 
-  void _connectBluetoothDevice() {
-    try {
-      _btConnected = true;
-    } catch (exception) {
-      //Connection to BT failed
-      _btConnected = false;
-    }
-  }
-
   @override
   Widget build(BuildContext context) {
     // This method is rerun every time setState is called, for instance as done
@@ -175,7 +231,7 @@ class _MyHomePageState extends State<MyHomePage> {
                   Expanded(
                     flex: 2,
                     child: Container(
-                        padding: EdgeInsets.all(5),
+                        padding: const EdgeInsets.all(5),
                         height: 120,
                         color: Colors.blue,
                         child: Text(
@@ -222,7 +278,7 @@ class _MyHomePageState extends State<MyHomePage> {
                     child: Container(
                         padding: EdgeInsets.all(5),
                         height: 120,
-                        color: Colors.grey,
+                        color: GetPm25Color(),
                         child: Text(
                           (() {
                             if (_pm25 == 0) {
@@ -270,7 +326,7 @@ class _MyHomePageState extends State<MyHomePage> {
                     child: Container(
                         padding: EdgeInsets.all(5),
                         height: 120,
-                        color: Colors.grey,
+                        color: GetPm10Color(),
                         child: Text(
                           (() {
                             if (_pm10 == 0) {
@@ -307,6 +363,11 @@ class _MyHomePageState extends State<MyHomePage> {
                         )),
                   ),
                 ])),
+            Container(
+              alignment: Alignment.center,
+              padding: EdgeInsetsDirectional.all(16),
+              child: Text(_updateText),
+            )
           ],
         ),
       )),

+ 2 - 0
src/pm25go/lib/scan.dart

@@ -186,10 +186,12 @@ class _ConnectionPage extends State<ConnectionPage> {
                                     ")";
                               });
                               operatingDevice.deviceConnected = true;
+                              /*
                               operatingDevice.connection.input!
                                   .listen((Uint8List data) {
                                 print(data);
                               });
+                              */
                             } catch (ex) {
                               print(ex);
                               setState(() {

+ 7 - 0
src/pm25go/pubspec.lock

@@ -74,6 +74,13 @@ packages:
     description: flutter
     source: sdk
     version: "0.0.0"
+  intl:
+    dependency: "direct main"
+    description:
+      name: intl
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.17.0"
   lints:
     dependency: transitive
     description:

+ 1 - 0
src/pm25go/pubspec.yaml

@@ -36,6 +36,7 @@ dependencies:
   # Use with the CupertinoIcons class for iOS style icons.
   cupertino_icons: ^1.0.2
   flutter_bluetooth_serial: ^0.4.0
+  intl: ^0.17.0
 
 dev_dependencies:
   flutter_test: