Merge to main #1

Merged
agrilink merged 19 commits from develop-gitea into main 2024-12-30 04:37:02 +00:00
9 changed files with 116 additions and 161 deletions
Showing only changes of commit 1622082f5c - Show all commits

View File

@ -16,6 +16,10 @@ String dateFormatterShort(String date) {
return formatter.format(dateTime);
}
String setTwoDigitAfterComma(double number) {
return number.toStringAsFixed(2);
}
String getGreeting(String time) {
DateTime parsedTime = DateTime.parse(time);
int hour = parsedTime.hour;

View File

@ -1,15 +1,15 @@
class RelayResponse {
bool? success;
List<Relay>? data;
List<Data>? data;
RelayResponse({this.success, this.data});
RelayResponse.fromJson(Map<String, dynamic> json) {
success = json['success'];
if (json['data'] != null) {
data = <Relay>[];
data = <Data>[];
json['data'].forEach((v) {
data!.add(Relay.fromJson(v));
data!.add(Data.fromJson(v));
});
}
}
@ -24,32 +24,29 @@ class RelayResponse {
}
}
class Relay {
class Data {
int? id;
int? number;
String? enabledAt;
String? disabledAt;
bool? currentStatus;
String? createdAt;
String? updatedAt;
Relay(
Data(
{this.id,
this.number,
this.enabledAt,
this.disabledAt,
this.currentStatus,
this.createdAt,
this.updatedAt});
this.createdAt});
Relay.fromJson(Map<String, dynamic> json) {
Data.fromJson(Map<String, dynamic> json) {
id = json['id'];
number = json['number'];
enabledAt = json['enabled_at'];
disabledAt = json['disabled_at'];
currentStatus = json['current_status'];
createdAt = json['created_at'];
updatedAt = json['updated_at'];
}
Map<String, dynamic> toJson() {
@ -60,7 +57,6 @@ class Relay {
data['disabled_at'] = disabledAt;
data['current_status'] = currentStatus;
data['created_at'] = createdAt;
data['updated_at'] = updatedAt;
return data;
}
}

View File

@ -107,14 +107,14 @@ class AppService {
final String auth = 'Bearer ${pref.getString('token')}';
try {
await Future.delayed(const Duration(seconds: 3));
final result = await _dioWithoutInterceptor.get(
'/api/get-relay',
final response = await _dioWithoutInterceptor.get(
'/api/relay/get-relay',
options: Options(
headers: {'Authorization': auth},
),
);
if (result.statusCode == 200) {
final data = RelayResponse.fromJson(result.data);
if (response.statusCode == 200) {
final data = RelayResponse.fromJson(response.data);
return data;
} else {
throw Exception('Failed to load data');
@ -134,7 +134,7 @@ class AppService {
try {
final response = await _dioWithoutInterceptor.post(
'/api/set-relay',
'/api/relay/set-relay',
data: {
'id': relayNumber,
'state': state,

View File

@ -1,5 +1,4 @@
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
class FirebaseApi {
final _firebaseMessaging = FirebaseMessaging.instance;
@ -11,10 +10,5 @@ class FirebaseApi {
provisional: false,
sound: true,
);
final fCMToken = await _firebaseMessaging.getToken();
if (kDebugMode) {
print('FCM Token: $fCMToken');
}
}
}

View File

@ -15,39 +15,8 @@ class ControlProvider extends ChangeNotifier {
getRelayStatus();
}
// ResultState mqttState = ResultState.initial;
// ResultState subscribeState = ResultState.initial;
ResultState relayState = ResultState.initial;
// Future<void> connectMqtt() async {
// mqttState = ResultState.loading;
// subscribeState = ResultState.loading;
// notifyListeners();
// try {
// final result = await _mqttService.setupMqtt();
// if (result == ResultState.hasData) {
// mqttState = result;
// final result2 = await _mqttService.subscribeToRelayStatus();
// // if (result2 == true) {
// // subscribeState = ResultState.hasData;
// // _control_1 = true;
// // } else {
// // subscribeState = ResultState.hasData;
// // _control_1 = false;
// // }
// } else {
// mqttState = ResultState.error;
// }
// } catch (e) {
// mqttState = ResultState.error;
// print(e);
// }
// notifyListeners();
// }
Future<void> getRelayStatus() async {
relayState = ResultState.loading;
notifyListeners();
@ -75,7 +44,7 @@ class ControlProvider extends ChangeNotifier {
relayState = ResultState.error;
notifyListeners();
if (kDebugMode) {
print(e);
print('Error Getting Relay Status: $e');
}
}
}
@ -122,23 +91,4 @@ class ControlProvider extends ChangeNotifier {
_control_2 = value;
notifyListeners();
}
// Future<ResultState> publishMessage(String topic, String message) async {
// try {
// final result = await _mqttService.publishMessage(topic, message);
// return result;
// } catch (e) {
// print(e);
// rethrow;
// }
// }
// Future<void> subscribeToTopic(String topic) async {
// try {
// await _mqttService.subscribeToTopic(topic);
// } catch (e) {
// print(e);
// rethrow;
// }
// }
}

View File

@ -72,7 +72,7 @@ class ControlScreen extends StatelessWidget {
),
children: [
ControlButtonWidget(
title: 'Katup Air',
title: 'Katup Nutrisi',
subtitle: 'Relay 1',
isActive: provider.control_1,
onTap: () async {
@ -85,13 +85,16 @@ class ControlScreen extends StatelessWidget {
},
),
ControlButtonWidget(
title: 'Lampu Utama',
title: 'Katup Air',
subtitle: 'Relay 2',
isActive: provider.control_2,
onTap: () {
provider.control_2 != true
? provider.switchControl2(true)
: provider.switchControl2(false);
onTap: () async {
final result = provider.control_2 != true
? await provider.switchRelay(2, true)
: await provider.switchRelay(2, false);
result == true
? provider.switchControl2(!provider.control_2)
: provider.switchControl2(provider.control_2);
},
),
],

View File

@ -1,4 +1,5 @@
import 'package:agrilink_vocpro/core/constant/app_color.dart';
import 'package:agrilink_vocpro/core/extension/extention.dart';
import 'package:agrilink_vocpro/core/route/app_route.dart';
import 'package:agrilink_vocpro/core/state/result_state.dart';
import 'package:agrilink_vocpro/features/home/provider/home_provider.dart';
@ -50,12 +51,10 @@ class ListDataFromCensorDht extends StatelessWidget {
DataDisplayerWidget(
title: 'Humidity',
subtitle: 'kelembaban udara',
value: provider.dhtHumidity.toString(),
value: setTwoDigitAfterComma(provider.dhtHumidity.toDouble()),
unit: '%',
icon: BootstrapIcons.droplet_half,
textColor: Colors.white,
color: AppColor.secondary,
iconColor: Colors.white,
color: Colors.white,
censorIdentifier: 'NPK 1',
onTap: () async {
await context

View File

@ -1,4 +1,5 @@
import 'package:agrilink_vocpro/core/constant/app_color.dart';
import 'package:agrilink_vocpro/core/extension/extention.dart';
import 'package:agrilink_vocpro/core/route/app_route.dart';
import 'package:agrilink_vocpro/core/state/result_state.dart';
import 'package:agrilink_vocpro/features/home/provider/home_provider.dart';
@ -46,15 +47,55 @@ class ListDataFromCensorNpk1 extends StatelessWidget {
childAspectRatio: 0.9,
),
children: [
DataDisplayerWidget(
title: 'Nitrogen',
subtitle: 'Kadar Nitrogen',
value: provider.npk1SoilNitrogen.toString(),
unit: 'mg/L',
icon: CupertinoIcons.eyedropper,
textColor: Colors.white,
color: AppColor.secondary,
iconColor: Colors.white,
onTap: () async {
await context.push(
'${AppRoute.nitrogen}/${provider.npk2SoilNitrogen}/${provider.npk1SoilNitrogen}');
},
),
DataDisplayerWidget(
title: 'Phosphorus',
subtitle: 'Kadar Fosfor',
value: provider.npk1SoilPhosphorus.toString(),
unit: 'mg/L',
icon: CupertinoIcons.eyedropper,
textColor: Colors.white,
color: AppColor.secondary,
iconColor: Colors.white,
onTap: () async {
await context.push(
'${AppRoute.phosphorus}/${provider.npk1SoilPhosphorus}/${provider.npk2SoilPhosphorus}');
},
),
DataDisplayerWidget(
title: 'Kalium',
subtitle: 'Kadar kalium',
value: provider.npk1SoilPotassium.toString(),
unit: 'mg/L',
icon: CupertinoIcons.eyedropper,
textColor: Colors.white,
color: AppColor.secondary,
iconColor: Colors.white,
onTap: () async {
await context.push(
'${AppRoute.potassium}/${provider.npk1SoilPotassium}/${provider.npk2SoilPotassium}');
},
),
DataDisplayerWidget(
title: 'Temperature',
subtitle: 'Suhu tanah',
value: provider.npk1Temperature.toString(),
unit: '°C',
icon: BootstrapIcons.thermometer_half,
textColor: Colors.white,
color: AppColor.secondary,
iconColor: Colors.white,
color: Colors.white,
censorIdentifier: censorIdentifier,
onTap: () async {
await context.push(
@ -100,42 +141,6 @@ class ListDataFromCensorNpk1 extends StatelessWidget {
'${AppRoute.conductivity}/${provider.npk1SoilEc}/${provider.npk2SoilEc}');
},
),
DataDisplayerWidget(
title: 'Nitrogen',
subtitle: 'Kadar Nitrogen',
value: provider.npk1SoilNitrogen.toString(),
unit: 'ppm',
icon: CupertinoIcons.eyedropper,
color: Colors.white,
onTap: () async {
await context.push(
'${AppRoute.nitrogen}/${provider.npk2SoilNitrogen}/${provider.npk1SoilNitrogen}');
},
),
DataDisplayerWidget(
title: 'Potassium',
subtitle: 'Kadar kalium',
value: provider.npk1SoilPotassium.toString(),
unit: 'ppm',
icon: CupertinoIcons.eyedropper,
color: Colors.white,
onTap: () async {
await context.push(
'${AppRoute.potassium}/${provider.npk1SoilPotassium}/${provider.npk2SoilPotassium}');
},
),
DataDisplayerWidget(
title: 'Phosphorus',
subtitle: 'Kadar Fosfor',
value: provider.npk1SoilPhosphorus.toString(),
unit: 'ppm',
icon: CupertinoIcons.eyedropper,
color: Colors.white,
onTap: () async {
await context.push(
'${AppRoute.phosphorus}/${provider.npk1SoilPhosphorus}/${provider.npk2SoilPhosphorus}');
},
),
],
);
case ResultState.noData:

View File

@ -46,15 +46,55 @@ class ListDataFromCensorNpk2 extends StatelessWidget {
childAspectRatio: 0.9,
),
children: [
DataDisplayerWidget(
title: 'Nitrogen',
subtitle: 'Kadar Nitrogen',
value: provider.npk2SoilNitrogen.toString(),
unit: 'mg/L',
icon: CupertinoIcons.eyedropper,
textColor: Colors.white,
color: AppColor.secondary,
iconColor: Colors.white,
onTap: () async {
await context.push(
'${AppRoute.nitrogen}/${provider.npk2SoilNitrogen}/${provider.npk1SoilNitrogen}');
},
),
DataDisplayerWidget(
title: 'Phosphorus',
subtitle: 'Kadar Fosfor',
value: provider.npk2SoilPhosphorus.toString(),
unit: 'mg/L',
icon: CupertinoIcons.eyedropper,
textColor: Colors.white,
color: AppColor.secondary,
iconColor: Colors.white,
onTap: () async {
await context.push(
'${AppRoute.phosphorus}/${provider.npk1SoilPhosphorus}/${provider.npk2SoilPhosphorus}');
},
),
DataDisplayerWidget(
title: 'Kalium',
subtitle: 'Kadar kalium',
value: provider.npk2SoilPotassium.toString(),
unit: 'mg/L',
icon: CupertinoIcons.eyedropper,
textColor: Colors.white,
color: AppColor.secondary,
iconColor: Colors.white,
onTap: () async {
await context.push(
'${AppRoute.potassium}/${provider.npk1SoilPotassium}/${provider.npk2SoilPotassium}');
},
),
DataDisplayerWidget(
title: 'Temperature',
subtitle: 'Suhu tanah',
value: provider.npk2Temperature.toString(),
unit: '°C',
icon: BootstrapIcons.thermometer_half,
textColor: Colors.white,
color: AppColor.secondary,
iconColor: Colors.white,
color: Colors.white,
censorIdentifier: censorIdentifier,
onTap: () async {
await context.push(
@ -100,42 +140,6 @@ class ListDataFromCensorNpk2 extends StatelessWidget {
'${AppRoute.conductivity}/${provider.npk1SoilEc}/${provider.npk2SoilEc}');
},
),
DataDisplayerWidget(
title: 'Nitrogen',
subtitle: 'Kadar Nitrogen',
value: provider.npk2SoilNitrogen.toString(),
unit: 'ppm',
icon: CupertinoIcons.eyedropper,
color: Colors.white,
onTap: () async {
await context.push(
'${AppRoute.nitrogen}/${provider.npk2SoilNitrogen}/${provider.npk1SoilNitrogen}');
},
),
DataDisplayerWidget(
title: 'Potassium',
subtitle: 'Kadar kalium',
value: provider.npk2SoilPotassium.toString(),
unit: 'ppm',
icon: CupertinoIcons.eyedropper,
color: Colors.white,
onTap: () async {
await context.push(
'${AppRoute.potassium}/${provider.npk1SoilPotassium}/${provider.npk2SoilPotassium}');
},
),
DataDisplayerWidget(
title: 'Phosphorus',
subtitle: 'Kadar Fosfor',
value: provider.npk2SoilPhosphorus.toString(),
unit: 'ppm',
icon: CupertinoIcons.eyedropper,
color: Colors.white,
onTap: () async {
await context.push(
'${AppRoute.phosphorus}/${provider.npk1SoilPhosphorus}/${provider.npk2SoilPhosphorus}');
},
),
],
);
case ResultState.noData: