diff --git a/lib/mqtt/mqtt.dart b/lib/mqtt/mqtt.dart new file mode 100644 index 0000000..d72c7e9 --- /dev/null +++ b/lib/mqtt/mqtt.dart @@ -0,0 +1,118 @@ +import 'dart:convert'; +import 'dart:ffi'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:mqtt_client/mqtt_client.dart'; +import 'package:mqtt_client/mqtt_server_client.dart'; + +class MqttHandler with ChangeNotifier { + final ValueNotifier data = ValueNotifier(""); + late MqttServerClient client; + + Future connect() async { + client = MqttServerClient.withPort( + 'broker.hivemq.com', 'smartpump239834893453920938', 1883); + client.logging(on: true); + client.onConnected = onConnected; + client.onDisconnected = onDisconnected; + client.onUnsubscribed = onUnsubscribed; + client.onSubscribed = onSubscribed; + client.onSubscribeFail = onSubscribeFail; + client.pongCallback = pong; + client.keepAlivePeriod = 60; + client.logging(on: true); + + /// Set the correct MQTT protocol for mosquito + client.setProtocolV311(); + + final connMessage = MqttConnectMessage() + .withWillTopic('willtopic') + .withWillMessage('Will message') + .startClean() + .withWillQos(MqttQos.atLeastOnce); + + print('MQTT_LOGS::Mosquitto client connecting....'); + + client.connectionMessage = connMessage; + try { + await client.connect(); + } catch (e) { + print('Exception: $e'); + client.disconnect(); + } + + if (client.connectionStatus!.state == MqttConnectionState.connected) { + print('MQTT_LOGS::Mosquitto client connected'); + } else { + print( + 'MQTT_LOGS::ERROR Mosquitto client connection failed - disconnecting, status is ${client.connectionStatus}'); + client.disconnect(); + return -1; + } + + //wil be used to determine water tank status + print('MQTT_LOGS::Subscribing to the pump/current topic'); + const topic = 'pump/current'; + client.subscribe(topic, MqttQos.atMostOnce); + + client.updates!.listen((List>? c) { + final recMess = c![0].payload as MqttPublishMessage; + final pt = + MqttPublishPayload.bytesToStringAsString(recMess.payload.message); + + data.value = pt; + notifyListeners(); + print( + 'MQTT_LOGS:: New data arrived: topic is <${c[0].topic}>, payload is $pt'); + print(''); + }); + + return client; + } + + void onConnected() { + print('MQTT_LOGS:: Connected'); + } + + void onDisconnected() { + print('MQTT_LOGS:: Disconnected'); + } + + void onSubscribed(String topic) { + print('MQTT_LOGS:: Subscribed topic: $topic'); + } + + void onSubscribeFail(String topic) { + print('MQTT_LOGS:: Failed to subscribe $topic'); + } + + void onUnsubscribed(String? topic) { + print('MQTT_LOGS:: Unsubscribed topic: $topic'); + } + + void pong() { + print('MQTT_LOGS:: Ping response client callback invoked'); + } + + void pumpTrigger(bool state) { + const pubTopic = 'trigger/pump'; + final builder = MqttClientPayloadBuilder(); + builder.addBool(val: state); + if (client.connectionStatus?.state == MqttConnectionState.connected) { + client.publishMessage(pubTopic, MqttQos.atMostOnce, builder.payload!); + } + } + + void updateConfig(String nextRun, UnsignedInt duration, bool auto) { + const pubTopic = 'update/config'; + final builder = MqttClientPayloadBuilder(); + builder.addString(jsonEncode({ + "next_run": nextRun, + "interval": duration, + "auto": auto, + })); + if (client.connectionStatus?.state == MqttConnectionState.connected) { + client.publishMessage(pubTopic, MqttQos.atMostOnce, builder.payload!); + } + } +} diff --git a/pubspec.lock b/pubspec.lock index 763333c..d7142a1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -137,6 +137,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + event_bus: + dependency: transitive + description: + name: event_bus + sha256: "44baa799834f4c803921873e7446a2add0f3efa45e101a054b1f0ab9b95f8edc" + url: "https://pub.dev" + source: hosted + version: "2.0.0" fake_async: dependency: transitive description: @@ -432,6 +440,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + mqtt_client: + dependency: "direct main" + description: + name: mqtt_client + sha256: "873c124f6485c17b5ca085047880068f3c5acc9db54317995d752a3253f95a72" + url: "https://pub.dev" + source: hosted + version: "10.0.0" nested: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 88467f5..7776abc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -23,6 +23,7 @@ dependencies: sliding_up_panel: ^2.0.0+1 syncfusion_flutter_charts: ^23.1.44 table_calendar: ^3.0.4 + mqtt_client: ^10.0.0 dev_dependencies: flutter_lints: ^3.0.1