TKK_E32220332/lib/services/mqtt_service.dart

136 lines
4.0 KiB
Dart

import 'dart:io';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
import 'package:flutter/foundation.dart';
class MqttService extends ChangeNotifier {
MqttServerClient? client;
String _temp = "25";
String _humidity = "55";
String _light = "125";
bool _isIntakeOn = false;
bool _isExhaustOn = false;
String _currentMode = "MANUAL";
double _maxTemp = 48.0;
double _maxHum = 75.0;
String get temp => _temp;
String get humidity => _humidity;
String get light => _light;
bool get isIntakeOn => _isIntakeOn;
bool get isExhaustOn => _isExhaustOn;
String get currentMode => _currentMode;
double get maxTemp => _maxTemp;
double get maxHum => _maxHum;
void setLimits(double t, double h) {
_maxTemp = t;
_maxHum = h;
notifyListeners();
}
// Callback for UI notifications
Function(String, bool)? onConnectionResult;
Future<bool> connect() async {
final String clientId = 'cli_kopi_${DateTime.now().millisecondsSinceEpoch % 10000}';
client = MqttServerClient.withPort(
'1f7929299fd649388da5f2e234152531.s1.eu.hivemq.cloud',
clientId,
8883
);
client!.secure = true;
client!.setProtocolV311();
client!.onBadCertificate = (dynamic cert) => true;
client!.keepAlivePeriod = 20;
client!.connectTimeoutPeriod = 10000;
client!.onDisconnected = onDisconnected;
client!.onConnected = onConnected;
client!.logging(on: true);
final connMess = MqttConnectMessage()
.withClientIdentifier(clientId)
.authenticateAs('kopi_user', 'Kopikopi1')
.startClean();
client!.connectionMessage = connMess;
try {
debugPrint('MQTT: Connecting to HiveMQ...');
await client!.connect();
} catch (e) {
debugPrint('MQTT Exception: $e');
onConnectionResult?.call('Koneksi Gagal: $e', false);
client!.disconnect();
}
if (client?.connectionStatus?.state == MqttConnectionState.connected) {
debugPrint('MQTT: SUCCESS!');
onConnectionResult?.call('✅ Terhubung ke Server Kopi', true);
_subscribeToTopics();
notifyListeners();
return true;
} else {
onConnectionResult?.call('❌ Koneksi Terputus', false);
notifyListeners();
return false;
}
}
void _subscribeToTopics() {
client!.subscribe("coffee/temp", MqttQos.atMostOnce);
client!.subscribe("coffee/humidity", MqttQos.atMostOnce);
client!.subscribe("coffee/light", MqttQos.atMostOnce);
client!.subscribe("coffee/intake", MqttQos.atMostOnce);
client!.subscribe("coffee/exhaust", MqttQos.atMostOnce);
client!.subscribe("coffee/config/mode", MqttQos.atMostOnce);
client!.updates!.listen((List<MqttReceivedMessage<MqttMessage?>>? c) {
final recMess = c![0].payload as MqttPublishMessage;
final pt = MqttPublishPayload.bytesToStringAsString(recMess.payload.message);
final topic = c[0].topic;
if (topic == "coffee/temp") _temp = pt;
if (topic == "coffee/humidity") _humidity = pt;
if (topic == "coffee/light") _light = pt;
if (topic == "coffee/intake") _isIntakeOn = (pt == "ON");
if (topic == "coffee/exhaust") _isExhaustOn = (pt == "ON");
if (topic == "coffee/config/mode") _currentMode = pt;
notifyListeners();
});
}
void publish(String topic, String message) {
if (topic == "coffee/intake") _isIntakeOn = (message == "ON");
if (topic == "coffee/exhaust") _isExhaustOn = (message == "ON");
notifyListeners();
if (client?.connectionStatus?.state == MqttConnectionState.connected) {
final builder = MqttClientPayloadBuilder();
builder.addString(message);
client!.publishMessage(topic, MqttQos.exactlyOnce, builder.payload!);
}
}
void onConnected() {
notifyListeners();
}
void onDisconnected() {
notifyListeners();
}
void updateFromLastLog(String t, String h, String l, bool i, bool e) {
_temp = t;
_humidity = h;
_light = l;
_isIntakeOn = i;
_isExhaustOn = e;
notifyListeners();
}
}